Realm in Mobile Applications: What It Is and How It Works

Author: IT Sectr Published: 2026-03-12 Reading time: 11 min

Realm is a mobile object-oriented NoSQL database developed as an alternative to SQLite and Core Data for iOS and Android. Data is stored in its own format with direct access to objects in memory, providing high read and write speed. Thanks to reactive notifications, automatic synchronization through Realm Sync and a cross-platform data model, Realm is used on over 1 billion devices (MongoDB data, 2025).

Key Takeaways

  • Realm is a NoSQL object database for mobile platforms with direct access to data in memory.
  • Live Objects — Realm objects automatically update when data changes without manual reloading.
  • Zero-copy — data is not copied between application layers, eliminating ORM overhead.
  • Realm Sync — built-in synchronization between devices via MongoDB Atlas Device Sync.
  • Cross-platform — the data model is defined once for iOS, Android, Flutter and React Native.

What is Realm?

Realm is an object-oriented database created specifically for mobile applications. Unlike SQLite, Realm does not use SQL or a relational model — data is stored as live objects (Live Objects), accessed directly without an intermediate ORM layer. The developer works with regular language objects (Swift, Kotlin, Dart) that are automatically saved to the database.

Realm appeared in 2014 as a startup Realm Inc., and in 2019 was acquired by MongoDB Inc. Since then, Realm has been developed as MongoDB Realm — part of the unified Atlas Device Sync platform for mobile data synchronization. The basic local Realm database remains free and open source (Apache 2.0 license), while Realm Sync (cloud synchronization) is distributed by subscription.

According to the MongoDB Developer Report (2025), Realm is used in 15% of mobile applications as the primary local storage. The main use cases are applications with offline mode, complex object models and the need for synchronization between devices, where Realm outperforms SQLite in development speed and ease of working with objects.

Realm Principles

Live Objects — each Realm object is linked to disk via memory-mapped file. Changing an object in any thread is immediately reflected in all other threads without manual notification. The UI automatically redraws when data changes through Realm notifications. Zero-copy — Realm does not copy data from the database into objects; objects are the data in memory.

How Realm Works: Architecture and Storage

Realm core is written in C++ and uses B+ Tree for data indexing. Unlike SQLite, where each row is a record in a relational table, Realm stores objects as nodes in a graph structure with direct references between them (forward pointers). Relationships between objects are not foreign keys but direct pointers, eliminating the need for JOIN operations.

Realm files (.realm extension) are memory-mapped — the OS itself manages loading file pages into memory as they are accessed. This allows Realm to work with databases larger than available RAM and provides read latency at the level of native language data structures (Swift Array or Kotlin List) for data that fits in RAM.

Zero-copy and Live Objects

Memory-mapped files — Realm's key technology. Instead of copying data from the database file into language objects (as SQLite does via sqlite3_step + sqlite3_column_*), Realm maps the database file directly into the process address space. Language objects are simply pointers to data in mapped memory. Changing an object modifies the database on disk without a separate save call.

CharacteristicRealm (zero-copy)SQLite (copying)
ReadDirect memory access (nanoseconds)Copy to object (microseconds)
WriteImmediate write to memory-mapped filesave() with SQL INSERT/UPDATE transaction
RelationshipsDirect pointers (forward pointers)Foreign key + JOIN
Memory consumptionFile + OS page cacheObjects + SQLite page cache
Live objectsYes (automatic update)No (requires new fetch)

Memory consumption is higher in Realm during active reading (the entire file or a large portion is mapped into memory), but lower during write operations since no memory allocation for object copies is required. For databases up to 1 GB on mobile devices, the memory-mapped approach provides better overall performance than SQLite with its intermediate copying.

Realm vs SQLite vs Core Data: Comparison

SQLite is a relational DBMS with SQL and ACID transactions. Realm is an object NoSQL database with memory-mapped access. Core Data is Apple's ORM layer on top of SQLite. Each of the three approaches has its own application area and strengths. Realm wins in direct object access speed and reactivity, SQLite in versatility and maturity, Core Data in integration with the Apple ecosystem.

Realm's read performance is 10-50% higher than SQLite thanks to zero-copy access. Realm is also faster on writes due to the absence of SQL parsing and direct modification of memory-mapped pages. However, Realm may consume more RAM when working with large databases (>500 MB), since the file is fully mapped into the address space.

CriterionRealmSQLiteCore Data
TypeNoSQL object DBRelational DBMS (SQL)ORM on top of SQLite
Read speedHigh (zero-copy)MediumMedium (ORM overhead)
ReactivityLive Objects (built-in)Need wrapper (Room/GRDB)NSFetchedResultsController
SynchronizationRealm Sync (MongoDB Atlas)Custom implementation neededNSPersistentCloudKitContainer
PlatformsiOS, Android, Flutter, RN, Node.jsiOS, Android, Web, DesktopiOS/macOS only
Library size~4 MB~600 KBBuilt into SDK

The choice between Realm and SQLite often comes down to priorities: development speed and reactivity (Realm) versus control and versatility (SQLite). Realm is especially good for MVPs and prototypes where the data model changes frequently and it is important to get live UI updates quickly. SQLite/Room is preferable for mature products with large data volumes and complex analytical queries.

Realm on Android: Kotlin SDK

Realm Kotlin SDK is the official library for Android, written in Kotlin (not a wrapper over Java SDK). The data model is defined through classes inheriting from RealmObject, with the @PrimaryKey annotation for a unique identifier. Realm Kotlin supports Kotlin Coroutines, Flow and KSP (Kotlin Symbol Processing) for compile-time code generation.

RealmQuery provides a type-safe API for filtering without SQL. Queries are built using a method chain: queryfiltersortfind. The result can be returned as a list (loaded into memory) or as a Flow (reactive stream updating when data changes). Realm Kotlin also supports nested objects and lists (RealmList).

Realm Kotlin SDK Example

Data model Realm is defined as a data class implementing the RealmObject interface. The _id field is marked with @PrimaryKey for unique identification. A one-to-many relationship is implemented through RealmList — a list of other RealmObjects. All write operations (create, update, delete) are performed inside a write transaction block.

kotlin
class Project : RealmObject {
    @PrimaryKey
    var _id: ObjectId = ObjectId().generate()
    var name: String = ""
    var tasks: RealmList<Task> = realmListOf()
}

class Task : RealmObject {
    @PrimaryKey
    var _id: ObjectId = ObjectId().generate()
    var title: String = ""
    var isComplete: Boolean = false
}

val config = Realm.Configuration.Builder(
    schema = setOf(Project::class, Task::class)
).build()

val realm = Realm.open(config)
realm.write { transactionRealm ->
    val project = copyToRealm(Project().apply {
        name = "Mobile App"
    })
    project.tasks.add(copyToRealm(Task().apply {
        title = "Design UI"
    }))
}

val projects: Flow<RealmResults<Project>> =
    realm.query<Project>()
        .sort(Project::name, Sort.ASCENDING)
        .asFlow()

Flow-returning query automatically emits new results upon any data change in Realm: adding, updating or deleting a Project or Task. The Flow approach pairs perfectly with Compose: collectAsState() in ViewModel automatically recomposes the UI when data changes without manually updating list adapters or using LiveData.

Realm on iOS: Swift SDK

Realm Swift SDK provides a native Swift API with support for async/await, Combine Publishers and Swift Concurrency. Data models are defined as classes inheriting from Object, using @Persisted for properties. Realm Swift automatically updates objects on changes, and notifications (NotificationToken) allow subscribing to changes of individual objects or collections.

@ObservedRealmObject and @ObservedResults are Property Wrappers for SwiftUI that automatically redraw the View when Realm data changes. @ObservedResults works with query results, @ObservedRealmObject works with a specific object. Both properties cancel the subscription when the View is deinitialized.

Realm Swift SDK Example

SwiftUI integration Realm is one of the SDK's strong points. The @ObservedResults Property Wrapper links a Realm query with SwiftUI display. When any task changes, SwiftUI automatically recomposes the list. realm.writeAsync performs transactions on a background thread without blocking the UI.

swift
import RealmSwift

class TaskItem: Object, Identifiable {
    @Persisted(primaryKey: true) var _id: ObjectId
    @Persisted var title: String = ""
    @Persisted var isDone: Bool = false
    @Persisted var priority: Int = 0
}

struct TaskListView: View {
    @ObservedResults(TaskItem.self,
        sortDescriptor: SortDescriptor(["priority"]))
    var tasks

    var body: some View {
        List {
            ForEach(tasks) { task in
                TaskRow(task: task)
            }
        }
        Button("Add Task") {
            let realm = try! Realm()
            try! realm.write {
                realm.add(TaskItem(value: ["title": "New task"]))
            }
        }
    }
}

@ObservedResults automatically manages the Realm query lifecycle: when the View is created, a subscription to changes is created; when destroyed, it is cancelled. The Property Wrapper accepts an optional predicate (NSPredicate) and sort descriptor. This eliminates the need to manually write fetch requests, create ViewModels and subscribe to Realm notifications.

Realm Use Cases

Offline applications — Realm is ideal for scenarios where data must be available without internet. Built-in synchronization (Realm Sync with MongoDB Atlas) automatically resolves conflicts when connecting to the network. The app continues working with local data, and background sync updates it when a connection becomes available.

Reactive interfaces — Live Objects and Flow/Combine notifications make Realm a convenient choice for applications with frequently updating data: chats, task feeds, collaborative documents. The UI automatically updates when data is added, changed or deleted without manually calling reloadData or invalidate.

Cross-platform projects — Realm supports Kotlin Multiplatform (KMP), Flutter, React Native and Xamarin. The data model is defined once and used on all platforms. This reduces code duplication and guarantees schema consistency between iOS and Android applications with shared business logic.

Realm Sync: Synchronization via MongoDB Atlas

Realm Sync is a cloud service built into MongoDB Atlas. The application automatically synchronizes data between the user's devices and the server. Conflicts are resolved using the "last write wins" strategy or through custom Conflict Resolution Functions on the server. Realm Sync supports partial synchronization (subset of data) to reduce traffic.

kotlin
class SyncRepository {
    private val app = App(
        AppConfiguration(
            appId = "my-realm-app-id"
        )
    )

    suspend fun syncData() {
        val user = app.login(Credentials.anonymous())
        val config = SyncConfiguration.Builder(
            user, setOf(Project::class)
        ).build()

        val syncedRealm = Realm.open(config)
        // Automatic synchronization is active
    }
}

SyncConfiguration configures the connection to MongoDB Atlas and defines the set of models to synchronize. After user authentication, Realm automatically loads data from the cloud and merges it with local changes. Synchronization runs on a background thread and does not require manual calls — simply create a Realm instance with SyncConfiguration.

Frequently Asked Questions

Is Realm free for commercial use?

Yes, the local Realm database is completely free (Apache 2.0 license). Realm Sync (cloud synchronization) via MongoDB Atlas is a paid service included in the Atlas Device Sync subscription. The free Atlas tier includes the first 500 MB of data and 1 million operations per month.

Can I migrate from SQLite to Realm?

Yes, migration is possible by exporting data from SQLite to JSON and importing it into Realm on the first app launch. For large volumes, use streaming migration: write data to both databases in parallel while users transition to the new app version, then delete the SQLite file.

How does Realm handle sync conflicts?

Realm Sync by default uses the "last write wins" strategy — the last write overwrites the previous one. For complex conflicts, configure custom Conflict Resolution Functions on the MongoDB Atlas server that merge changes from different devices according to the application's business logic (e.g., merging values instead of replacing).

Does Realm support aggregate queries?

Realm does not support SQL aggregations (SUM, AVG, GROUP BY) at the database level. For analytical queries, it is recommended to export data from Realm to MongoDB Atlas via Realm Sync and run aggregations through the MongoDB Aggregation Pipeline. For simple counts, use realm.query<T>().count().

Are Realm data secure?

Realm does not encrypt data by default. For encryption, provide a 64-byte key in the configuration: Realm.Configuration(encryptionKey: key). Encryption uses AES-256 + SHA-2 HMAC and increases operation overhead by 10-20%. Without encryption, the .realm file can be read by any process with file system access.

Summary

  • Realm is an object-oriented NoSQL database with memory-mapped access, live objects and a cross-platform data model for mobile applications.
  • Zero-copy architecture allows reading data directly from a memory-mapped file without copying into language objects, making Realm 10-50% faster than SQLite on reads.
  • Live Objects and @ObservedResults (SwiftUI) / Flow (Kotlin) provide automatic UI updates when data changes without manual database queries.
  • Realm Sync with MongoDB Atlas provides built-in cloud synchronization with conflict resolution using the "last write wins" strategy.
  • Cross-platform SDKs support Kotlin Multiplatform, Flutter, React Native — the data model is defined once for all platforms.
  • For analytical queries Realm falls short of SQLite due to the lack of grouping aggregations — complex reports are run through the MongoDB Aggregation Pipeline.
  • Recommendation — use Realm for offline applications with frequent UI updates and a need for cross-platform synchronization, SQLite/Room for projects with analytics and stable data sets.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also