On this page
- Why Use Realm Sync?
- Live Objects
- Conflict Resolution
- Using Realm Sync in Your App
- Before You Start
- Configure Your Data Model
- Choose an SDK
- Define Data Model
- Define Data Access Patterns
- Choose a Sync Mode
- Define Data Access Rules
- Configure and Enable Sync
- Enable Sync
- Optimize Sync Data Usage
- Best Practices
Realm Sync is a Realm app feature that synchronizes data on client devices with a data source linked to your MongoDB Realm back end. Realm Sync handles network access and conflict resolution in a background thread of your application, so your application logic stays the same regardless of network conditions. The Realm data model makes it easy to manage a consistent schema of objects in your database and across all client platforms.
Most mobile apps are data-dependent. Eventually, many apps need to share that data with other apps and the outside world. Realm Sync is an out-of-the-box that meets this need.
Consider a few examples:
- A team collaborates in real-time on a shared document across the Internet.
- A front-line worker fills out a report while working somewhere with low or no network connectivity.
- An IoT device uploads its sensor data to the cloud.
Traditionally, mobile app developers use an HTTP client to manually communicate with an endpoint. This means that every mobile app needs to solve the following problems for every client platform:
- a consistent schema of objects
- gracefully handling network failures and slowdowns
- resolving conflicts between changes to the same data on different clients
Realm Sync handles network access and conflict resolution in a background thread of your application, so your application logic stays the same regardless of network conditions. The Realm data model makes it easy to manage a consistent schema of objects in your database and across all client platforms.
Realm Sync is built on 3 main pillars:
For a deep dive into how Sync works, see: Realm Sync Protocol.
Realm Sync is built on the assumption that connectivity will drop. We call this mentality offline-first. After you make changes to the local realm on the client device, the Realm SDK automatically sends the changes to the server as soon as possible. Likewise, the Realm SDK automatically receives changes from the server and integrates those changes into the local realm. In effect, you continue to work with the local realm without moment-to-moment concern for network connectivity or lack thereof.
The offline-first design leads to one of the main benefits of MongoDB Realm: a seamless user experience. Users interact with local data with zero latency regardless of their moment-to-moment connectivity, and because Realm Sync is built into the Realm SDK, you do not need to write your own synchronization protocol and deal with connectivity issues when synchronizing data.
The main difficulty with offline-first data is ensuring that devices that are offline for extended periods are able to resolve potential conflicts with changes made to the same data. Ultimately, every client device must arrive at the same state when all changes have been synced. This is why Realm Sync includes automatic conflict resolution.
Realm's Live objects means that you can update data in one place (a mobile app, for example), and that data is updated everywhere. Live objects always reflect the latest data stored in Realm Database. This concept extends across devices: updates on one device sync to the corresponding objects on other devices. Notifications based on these updates make it easy to update the application UI to react to local and remote changes.
MongoDB Realm's sync conflict resolution engine is deterministic. Changes received out-of-order eventually converge on the same state across the server and all clients. As such, Realm Sync is strongly eventually consistent.
From MongoDB Realm's perspective, changesets may arrive any time that connectivity allows. There is no guarantee that an earlier-timestamped changeset from one client actually arrives before a later-timestamped changeset from another client. As a result, the server has to be able to process events out-of-order. MongoDB Realm keeps a per-realm transaction history to deal with the out-of-order nature of messages.
In simple terms, Realm Sync's conflict resolution comes down to last write wins. Realm Sync also uses more sophisticated techniques like operational transform to handle, for example, insertions into lists.
To sync data across devices, you enable Realm Sync for your Realm app and then use the sync-related methods and properties in the SDKs.
If you prefer to learn by example, check out the Realm tutorial, which describes how to build a synced Task Tracker application with clients for common platforms that Realm supports.
- If you don't already have one, sign up for a free MongoDB Atlas account.
- Ensure that you have a MongoDB Atlas cluster that runs MongoDB version 4.4 or later. You can use a free shared M0 cluster to explore and develop your app. We recommend that you use a dedicated tier cluster (M10 and above) for production applications. You cannot use sync with a serverless instance or data lake.
- If you don't already have one, create a new Realm App linked to your Atlas cluster.
The Realm SDKs, available for multiple languages and platforms, include everything you need to work with synced Realms in your client application code. You can use multiple SDKs to work with the same set of synced data across devices and platforms.
This guide focuses on configuring sync with an SDK. For in-depth documentation that includes details on how to install and use the Realm SDKs more generally, check out the SDK docs:
The Web SDK does not currently support Realm Database or Realm Sync directly. However, it is compatible with apps that use sync through the MongoDB and GraphQL APIs.
A synced realm uses object models that you define to determine the type of objects in the realm. Additionally, Sync requires a server-side document schema for each synced object type so that Realm can translate and apply changes between synced realms and MongoDB Atlas.
To define your synced object models, do one of the following for each object type:
Sync object models from an SDK: In Development Mode, Realm automatically generates a document schema for each synced object type and assigns that schema to a collection in the linked cluster with the same name as the object type. Development mode lets you configure your synced data model from a client application using the same object models and code that you use in your production app. This is useful if you prefer a client-first approach that uses idiomatic object models in your preferred programming language.
For a walkthrough of how to turn on Development Mode, see Enable Development Mode.TipPartition-Based Sync
When you use Partition-Based Sync with Development mode, you must specify a partition key and database to hold synced data.
You may not know exactly what you want either of these to be long term, but that's okay. You can always use a placeholder value like
devModeDatabasewhile you build your data model and then change it later before you push to production.
Generate object models from a document schema: Realm can automatically generate language-specific object models that you can use in your client applications. The generated models match the document schemas defined for your app's synced cluster. You can define these schemas manually or Realm can sample existing data in the cluster to create them automatically. This is useful if you prefer a server-first approach and/or plan to build apps with multiple SDKs.
For a walkthrough of how to generate your object models based on server-side document schemas, see Generate SDK Object Models.
Once you have the generated object models, you can copy them directly into your client application and use them the same way you would any regular object or struct in your preferred programming language.
Once you have decided on your app's data model, you can define a data access pattern and access rules for your app's data.
When you use Partition-Based Sync, you must:
- Identify a partition strategy
- Define a partition key
- Configure data access rules
Partition key values and data access rules determine which users can read or write which data in your database.
When you use Flexible Sync, you must:
- Specify queryable fields
- Configure data access rules and default roles
Client applications can query the queryable fields you configure to determine which objects to sync. Then, Realm applies rules and default roles to determine whether users can read or write the objects that match the query.
Data access rules determine which data to sync, as well as each user's ability to read and write data. Rules are closely linked to your app's data model.
Flexible Sync does not require you to define a partition strategy. Instead, you specify which data to sync through queries for matching objects in a client application. Realm then evaluates session roles and rules to determine which of those matching objects a user can read and write.
You can define session roles on specific collections. Default roles provide read and write permissions when more specific session roles do not apply. Default roles apply to all collections a Realm app can access, but you can restrict a session role to a specific collection by specifying the collection name.
Once you have defined a data model and corresponding access rules, you can enable sync for your app. You can also optimize sync data usage by specifying a client maximum offline time.
When you enable Sync, you specify how clients can access data in your Realm app. For a walkthrough of how to turn on sync, see Enable Realm Sync.
Sync stores some utility data in your synced cluster to help synchronize data with clients. Realm has optimizations built-in to reduce the amount of utility data stored in synced clusters. If you'd like to reduce the amount of utility data further to suit your use case, see our guide to Optimize Realm Sync Atlas Usage.
In addition to the information in this guide, we recommend following these best practices to ensure optimal performance and a smooth user experience:
- Avoid breaking changes:
- Once you've enabled sync, there are limitations on how you can modify your data model. Specifically, sync does not support breaking changes to your object types such as changing a given property's type. If you want to make a breaking change you need to terminate and re-enable sync with the updated data models.
- Define a client reset handler:
- To recover from a serious error conditions where the client and server histories diverge, you should define a client reset handler when you open each synced realm with an SDK.
- Define a client maximum offline time:
- The Realm backend uses a history of changes to underlying data to synchronize clients. Configure a client maximum offline time to control the number of days of history stored by your Realm app. Clients that have not synchronized in more than that number of days must perform a client reset the next time they connect to the backend.
- Deployment model and geographic regions:
- Use a local deployment model when building a Realm Sync application. Configure your Realm app and MongoDB data source to run within the same geographic region and cloud provider.
- Atlas oplog:
- Realm Sync requires access to the oplog of your synced cluster. For best results, keep 48 hours of oplog for a cluster using Sync.
- Realm Sync Schema Data Consistency
- If you create or modify Realm Sync documents using another tool, such as the
mongoshell or MongoDB Compass, be sure the documents validate against the Sync object schema. For more information, see Unsynced Documents.
- Production Load Testing
- Measure performance and identify issues in a scaled-up production deployment with Sync Production Load Testing.
- Realm Sync is the part of realm that handles data synchronization between a Realm Database on one or more clients and MongoDB Atlas.
- Realm Sync enables offline-first app development by handling network loss and recovery automatically.
- Realm Sync has a built-in conflict resolution engine that guarantees strong eventual consistency.
- Realm Sync is included in the client SDKs to simplify app development.