Docs Menu

Docs HomeRealm

Realms - Java SDK

On this page

  • Types of Realm
  • Read-Only Realms
  • In-Memory Realms
  • Dynamic Realms
  • The Realm Lifecycle
  • Multi-process
  • Comparison with Other Databases
  • Realm Schema
  • Synced Realms
  • Find Your Realm File
  • Realm File Size
  • Limit the Maximum Number of Active Versions
  • Compact a Realm
  • Backup and Restore Realms

A realm is a set of related objects that conform to a pre-defined schema. Realms may contain more than one type of data as long as a schema exists for each type.

Every realm stores data in a separate realm file that contains a binary encoding of each object in the realm. You can automatically synchronize realm across multiple devices and set up reactive event handlers that call a function any time an object in a realm is created, modified, or deleted.

When opening a realm, you can configure many properties of the realm.

It's sometimes useful to ship a prepared realm file with your app that contains shared data that does not frequently change. You can use the readOnly() method when configuring your realm to make it read-only. This can prevent accidental writes to the realm and causes the realm to throw an IllegalStateException if a write occurs.


Read-Only Realm Files are Writeable

Read-only realms are only enforced as read-only in process. The realm file itself is still writeable.


To create a realm that runs entirely in memory without being written to a file, use the inMemory() method.

When memory runs low on an Android device, in-memory realms may swap temporarily from main memory to disk space. The SDK deletes all files created by an in-memory realm when:

  • the realm closes

  • all references to that realm fall out of scope

Conventional realms define a schema using RealmObject subclasses or the RealmModel interface. A DynamicRealm uses strings to define a schema at runtime. Opening a dynamic realm uses the same configuration as a conventional realm, but dynamic realms ignore all configured schema, migration, and schema versions.

Dynamic realms offer flexibility at the expense of type safety and performance. As a result, only use dynamic realms when that flexibility is required, such as during migrations, manual client resets, and when working with string-based data like CSV files or JSON.

Every realm instance consumes a significant amount of resources. Opening and closing a realm are both expensive operations, but keeping a realm open also incurs significant resource overhead. To maximize the performance of your application, you should minimize the number of open realms at any given time and limit the number of open and close operations used.

However, opening a realm is not always consistently expensive. If the realm is already open within the same process or thread, opening an additional instance requires fewer resources:

  • If the realm is not open within the same process, opening the realm is expensive.

  • If the realm is already open on a different thread within the same process, opening the realm is less expensive, but still nontrivial.

  • If the realm is already open on the same thread within the same process, opening the realm requires minimal additional resources.

When you open a realm for the first time, Realm Database performs the memory-mapping and schema validation required to read and write data to the realm. Additional instances of that realm on the same thread use the same underlying resources. Instances of that realm on separate threads use some of the same underlying resources.

When all connections to a realm are closed in a thread, Realm Database frees the thread resources used to connect to that realm. When all connections to a realm are closed in a process, Realm Database frees all resources used to connect to that realm.

As a best practice, we recommend tying the realm instance lifecycle to the lifecycles of the views that observe the realm. For instance, consider a RecyclerView that displays RealmResults data via a Fragment. You could:

  • Open a single realm that contains the data for that view in the Fragment.onCreateView() lifecycle method.

  • Close that same realm in the Fragment.onDestroyView() lifecycle method.


If your realm is especially large, fetching a realm instance in Fragment.onCreateView() may briefly block rendering. If opening your realm in onCreateView() causes performance issues, consider managing the realm from Fragment.onStart() and Fragment.onStop() instead.

If multiple Fragment instances require access to the same dataset, you could manage a single realm in the enclosing Activity:

  • Open the realm in the Activity.onCreate() lifecycle method.

  • Close the realm in the Activity.onDestroy() lifecycle method.

You cannot access encrypted or synced realms simultaneously from different processes. However, local realms function normally across processes, so you can read, write, and receive notifications from multiple APKs.

The Realm data model is similar to both relational and document databases but has distinct differences from both. To underscore these differences, it's helpful to highlight what a realm is not:

A realm is not a single, application-wide database.
Unlike other applications, which store all of their data in a single database, Apps often split data across multiple realms to organize data more efficiently and to enforce access controls.
A realm is not a table.
Tables typically only store one kind of information, such as street addresses or items in a store inventory, whereas a realm can contain any number of object types.
A realm is not a collection of schemaless documents.
Application objects are similar to documents, but every object in a realm conforms to a defined schema for its object type. An object cannot contain a field that is not described by its schema.

A Realm Schema is a list of valid object schemas that each define an object type that an App may persist. All objects in a realm must conform to the Realm Schema.

By default, the SDK automatically adds all classes in your project that derive from RealmObject to the realm schema.

Client applications provide a Realm Schema when they open a realm. If a realm already contains data, then Realm Database validates each existing object to ensure that an object schema was provided for its type and that it meets all of the constraints specified in the schema.


A realm that contains basic data about books in libraries might use a schema like the following:

"type": "Library",
"properties": {
"address": "string",
"books": "Book[]"
"type": "Book",
"primaryKey": "isbn",
"properties": {
"isbn": "string",
"title": "string",
"author": "string",
"numberOwned": { "type": "int?", "default": 0 },
"numberLoaned": { "type": "int?", "default": 0 }

When you use Partition-Based Sync, synced realms represent partitions of Atlas data. Each realm corresponds to a subset of the data in your App's data source. You can customize the partitioning of data using your application's partition key. Unique values of the partition key, known as partition values, correspond to individual realms.

When you use Flexible Sync, you can customize the data your client application syncs by subscribing to queries. These queries search for data in your App backend, and the Flexible Sync realm syncs data that matches the queries. The client application can only sync data where the user has the appropriate read or read and write permissions to access the data.

You can customize permissions for the data that synced realms can read and write from your App when you configure Realm Rules.

Realm Database stores a binary encoded version of every object and type in a realm in a single .realm file.

The filesystem used by Android emulators is not directly accessible from the machine running Realm Studio. You must download the file from the emulator before you can access it.

First, find the path of the file on the emulator:

// Run this on the device to find the path on the emulator
Realm realm = Realm.getDefaultInstance();
Log.i("Realm", realm.getPath());

Then, download the file using ADB. You can do this while the app is running.

> adb pull <path>

You can also upload the modified file again using ADB, but only when the app isn't running. Uploading a modified file while the app is running can corrupt the file.

> adb push <file> <path>


See also: Auxiliary Realm Files

Realm Database creates additional files for each realm. To learn more about these files, see Realm Database Internals.

Realm Database usually takes up less space on disk than an equivalent SQLite database. However, in order to give you a consistent view of your data, Realm operates on multiple versions of a realm. If many versions of a realm are opened simultaneously, the realm file can require additional space on disk.

These versions take up an amount of space dependent on the amount of changes in each transaction. Many small transactions have the same overhead as a small number of large transactions.

Unexpected file size growth usually happens for one of three reasons:

  1. You open a realm on a background thread and forget to close it again. As a result, Realm Database retains a reference to the older version of data on the background thread. Because Realm Database automatically updates realms to the most recent version on threads with loopers, the UI thread and other Looper threads do not have this problem.

  2. You hold references to too many versions of frozen objects. Frozen objects preserve the version of a realm that existed when the object was first frozen. If you need to freeze a large number of objects, consider using Realm.copyFromRealm() instead to only preserve the data you need.

  3. You read some data from a realm. Then, you block the thread with a long-running operation. Meanwhile, you write many times to the realm on other threads. This causes Realm Database to create many intermediate versions. You can avoid this by:

    • batching the writes

    • avoiding leaving the realm open while otherwise blocking the background thread.

You can set maxNumberOfActiveVersions() when building your RealmConfiguration to throw an IllegalStateException if your application opens more versions of a realm than the permitted number. Versions are created when executing a write transaction.

Realm Database automatically removes older versions of data once they are no longer used by your application. However, Realm Database does not free the space used by older versions of data; instead, that space is used for new writes to the realm.

You can remove unused space by compacting the realm file:

  • Manually: call compactRealm()

  • Automatically: specify the compactOnLaunch() builder option when opening the first connection to a realm in your Android application


Compact All Production Applications

Every production application should implement compacting to periodically reduce realm file size.

Realm Database persists realms to disk using files on your Android device. To back up a realm, find your realm file and copy it to a safe location. You should close all instances of the realm before copying it.

Alternatively, you can also use realm.writeCopyTo() to write a compacted version of a realm to a destination file.


See also:

If you want to back up a realm to an external location like Google Drive, see the following article series: (Part 1, Part 2, Part 3).

←  Realm Database - Java SDKLive Queries - Java SDK →
Give Feedback
© 2022 MongoDB, Inc.


  • Careers
  • Investor Relations
  • Legal Notices
  • Privacy Notices
  • Security Information
  • Trust Center
© 2022 MongoDB, Inc.