Overview

Realm provides an embedded, object-oriented database service specifically engineered for mobile and edge devices, coupled with a server-side synchronization platform. Founded in 2011 and acquired by MongoDB, Realm is designed to facilitate the development of offline-first mobile applications that can operate robustly without continuous network connectivity while offering real-time data synchronization capabilities when online. Its core offerings include the Realm Database, an embedded NoSQL database, and Realm Sync, a service that handles bidirectional data synchronization between the local device database and a cloud-based MongoDB Atlas instance.

The Realm Database differentiates itself from traditional relational databases like SQLite by operating directly on native objects, eliminating the need for ORMs (Object-Relational Mappers). This approach aims to simplify data interaction for developers working with languages such as Swift, Kotlin, and JavaScript, allowing them to query and manipulate data directly using language-native syntax. The database supports live objects, meaning that changes to data are reflected immediately in all parts of the application observing that data, facilitating reactive UI development.

Realm Sync extends the local database's capabilities by providing seamless, real-time data synchronization with MongoDB Atlas. This feature is critical for applications requiring consistent data across multiple devices or collaborative features. It includes automatic conflict resolution, ensuring data integrity during concurrent updates. Developers can define flexible data access rules directly within MongoDB Atlas App Services, controlling who can read or write specific data based on user roles or data ownership. This integration with the broader MongoDB Atlas ecosystem allows applications built with Realm to scale from local device storage to a managed cloud backend, leveraging MongoDB's operational database capabilities and additional App Services like serverless functions, authentication, and GraphQL APIs. The developer experience is characterized by its focus on reducing boilerplate code for data persistence and synchronization, although the full integration with MongoDB Atlas for cloud features introduces additional architectural considerations.

Key features

  • Offline-First Database: The Realm Database runs directly on mobile devices, enabling applications to function without an internet connection and store data locally.
  • Real-Time Synchronization (Realm Sync): Synchronizes data bidirectionally between local Realm databases and MongoDB Atlas, providing real-time updates across multiple devices and automatic conflict resolution (Realm Sync documentation).
  • Object-Oriented Database: Stores data as objects directly, eliminating the need for ORMs and allowing direct manipulation with native language types (e.g., Swift objects, Kotlin data classes).
  • Live Objects: Data objects retrieved from Realm are live and automatically update when the underlying data changes, simplifying UI updates and reactive programming patterns.
  • Cross-Platform SDKs: Supports a range of client SDKs including Swift, Kotlin, Java, .NET, React Native, Flutter, and Node.js (Realm documentation).
  • Flexible Data Access Rules: Integrates with MongoDB Atlas App Services to define fine-grained permissions for data access and modification, based on user roles and data ownership.
  • Query Engine: Provides a query engine for efficient data retrieval and filtering directly on the device, supporting complex queries and relationships.
  • Encryption: Offers local database encryption to secure sensitive data stored on device.
  • Integrated with MongoDB Atlas: Leverages MongoDB Atlas for a scalable cloud backend, offering additional services like serverless functions, authentication, and GraphQL APIs (MongoDB Atlas App Services overview).

Pricing

Realm's pricing is integrated with MongoDB Atlas and its App Services. A free tier is available for initial development and small-scale applications.

Tier Details Key Features Cost (as of 2026-05-07)
Free Tier (M0) Shared cluster in MongoDB Atlas 0.5 GB data transfer, 1 GB data storage, basic App Services. $0/month
Paid Tiers (M0+ and higher) Dedicated clusters in MongoDB Atlas Increased data transfer and storage, advanced App Services, higher performance, and support. Starts from $9/month (for M0+ clusters), scales with usage (MongoDB Atlas Pricing).

Common integrations

  • MongoDB Atlas: Core integration for cloud backend, data synchronization, serverless functions, and authentication (Realm Sync with Atlas).
  • Firebase Authentication: Can be used for user authentication in conjunction with Realm Sync and MongoDB Atlas App Services (Firebase Authentication documentation).
  • Various Mobile Frameworks: Direct SDKs for Swift, Kotlin, Java, .NET, React Native, and Flutter enable integration into respective mobile projects (Realm SDKs).
  • Node.js: A Realm SDK for Node.js allows integration with server-side JavaScript applications (Realm Node.js SDK).

Alternatives

  • Firebase Firestore: A NoSQL cloud database that offers real-time synchronization and offline support, part of the Google Firebase ecosystem (Firebase Firestore documentation).
  • Supabase: An open-source Firebase alternative providing a PostgreSQL database, real-time subscriptions, authentication, and storage.
  • SQLite: A C-language library that implements a small, fast, self-contained, high-reliability, full-featured, SQL database engine. It is a common embedded database for mobile and desktop applications (SQLite official website).
  • Core Data: Apple's framework for managing and persisting application data on iOS, macOS, watchOS, and tvOS devices (Apple Core Data documentation).
  • Jetpack Room: Android's official persistence library, providing an abstraction layer over SQLite to enable more robust database access while harnessing the full power of SQLite (Android Jetpack Room documentation).

Getting started

This example demonstrates how to set up Realm in a Kotlin Android project, define a simple data model, and perform basic CRUD operations. This assumes you have a new Android project set up with Kotlin.

// 1. Add Realm dependency to your app/build.gradle.kts (Kotlin DSL)
//    and apply the Realm plugin
//
// build.gradle.kts (Project level)
// plugins {
//    id("io.realm.kotlin") version "1.11.0" apply false // Check for latest version
// }
//
// build.gradle.kts (Module level - app)
// plugins {
//    id("io.realm.kotlin")
// }
// dependencies {
//    implementation("io.realm.kotlin:realm-kotlin-library-base:1.11.0") // Check for latest version
// }

// 2. Define a data model (e.g., app/src/main/java/com/example/myapp/Task.kt)
package com.example.myapp

import io.realm.kotlin.types.RealmObject
import io.realm.kotlin.types.annotations.PrimaryKey
import org.mongodb.kbson.ObjectId

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

// 3. Initialize Realm and perform operations (e.g., in your MainActivity.kt)
package com.example.myapp

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import io.realm.kotlin.Configuration
import io.realm.kotlin.Realm
import io.realm.kotlin.ext.query
import io.realm.kotlin.query.RealmResults
import io.realm.kotlin.notifications.ResultsChange
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import android.util.Log

class MainActivity : AppCompatActivity() {

    private lateinit var realm: Realm
    private lateinit var tasks: RealmResults<Task>
    private val scope = CoroutineScope(Dispatchers.Main)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Configure and open the Realm database
        val config = Configuration.create(schema = setOf(Task::class))
        realm = Realm.open(config)

        // Get all tasks and observe changes
        tasks = realm.query<Task>().find()

        scope.launch {
            tasks.asFlow().collect { changes: ResultsChange<Task> ->
                when (changes) {
                    is ResultsChange.Initial -> {
                        Log.d("Realm", "Initial tasks: ${changes.list.size}")
                        changes.list.forEach { task -> Log.d("Realm", "Task: ${task.name}") }
                    }
                    is ResultsChange.Update -> {
                        Log.d("Realm", "Tasks updated! Added: ${changes.insertions.size}, Deleted: ${changes.deletions.size}, Modified: ${changes.changes.size}")
                        changes.list.forEach { task -> Log.d("Realm", "Updated Task: ${task.name}, Complete: ${task.isComplete}") }
                    }
                    else -> {}
                }
            }
        }

        // Perform some database operations
        createTask("Buy groceries")
        createTask("Walk the dog")
        updateTaskStatus("Buy groceries", true)
        deleteTask("Walk the dog")
    }

    private fun createTask(name: String) {
        scope.launch {
            realm.write {
                copyToRealm(Task().apply { this.name = name })
                Log.d("Realm", "Created task: $name")
            }
        }
    }

    private fun updateTaskStatus(taskName: String, isComplete: Boolean) {
        scope.launch {
            realm.write {
                val task = query<Task>("name == $0", taskName).first().find()
                task?.isComplete = isComplete ?: false
                Log.d("Realm", "Updated task: $taskName to complete: $isComplete")
            }
        }
    }

    private fun deleteTask(taskName: String) {
        scope.launch {
            realm.write {
                val task = query<Task>("name == $0", taskName).first().find()
                task?.let { delete(it) }
                Log.d("Realm", "Deleted task: $taskName")
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        realm.close()
    }
}

This example demonstrates the basic setup, object definition, and transactional writes within a Realm database. For Realm Sync, additional configuration involving MongoDB Atlas App Services and user authentication is required to connect the local database with a cloud backend.