Securing Mobile Data with Realm’s Built‑In Encryption and Offline Sync
Realm’s native encryption and sync can reduce the code surface for secure, offline-first mobile apps. This post covers a conservative Swift setup, the trade-offs to watch, and a verification checklist.
05 Mar 2026, 20:28 UTC

The problem: protecting local data on a lost or offline device
Mobile apps often cache personal information—tokens, preferences, documents—directly on the device. If the phone is lost or the user works without a network, that data must stay unreadable to others while remaining usable by the app. Building a custom encryption and replication layer adds significant code surface and key-management risk.
Thesis: Realm’s native encryption and sync reduce that surface, but verify version and server requirements
Realm’s SDK includes transparent encryption for the database file and a sync protocol that replicates changes over HTTPS. Together they can support an offline-first security model without a separate crypto library. Because the research brief flags current verification requirements, treat the specifics below as starting points to confirm against your Realm version and deployment.
Transparent encryption at rest
- AES‑256‑GCM is used to encrypt the Realm file. The encryption key is supplied when the Realm is opened; after that, queries and writes behave as they would on an unencrypted file.
- The key never leaves the process. You provide it once per Realm instance, typically from the platform keystore (iOS Keychain or Android Keystore).
- The research brief reports roughly 5% added latency on typical mobile workloads, but this figure should be re-measured in your own app before relying on it.
Offline sync and conflict resolution
Realm Sync uses server-side storage as the authoritative state. Clients push and pull changesets over TLS. When two devices edit the same object offline, the server applies a deterministic conflict rule per property and notifies clients of the merged result. No manual merge code is required.
This depends on Realm’s server components. Purely air-gapped or offline-only deployments cannot replicate changes until a network path to the server exists.
Worked example: opening an encrypted Realm in Swift
import RealmSwift
// 1. Retrieve a 64-byte key from the iOS Keychain.
// Replace this placeholder with your SecItemCopyMatching result.
let key = Data(count: 64)
// 2. Configure the Realm with the encryption key.
// Bump schemaVersion when your model changes.
var config = Realm.Configuration(encryptionKey: key)
config.schemaVersion = 2
config.migrationBlock = { migration, oldSchemaVersion in
if oldSchemaVersion < 2 {
// Example: rename a property during migration.
migration.renameProperty(onType: "User", from: "fullName", to: "displayName")
}
}
// 3. Open the encrypted Realm.
let realm = try! Realm(configuration: config)
// 4. Write data — identical to an unencrypted Realm.
try realm.write {
let user = User()
user.id = UUID().uuidString
user.displayName = "Alex"
realm.add(user)
}
// 5. Diagnostic: attempt to open the same file without the key.
// Expect this to fail; if it succeeds, encryption is not active.
let badConfig = Realm.Configuration()
let unprotectedOpen = try? Realm(configuration: badConfig)
Replace the key placeholder with a value stored in the device’s secure enclave or keystore. The migration block shows how schema versions keep upgrades smooth without wiping data.
Trade-offs and limitations
- Key loss is permanent – If the key is lost (for example, the app is deleted and the Keychain entry is removed), the Realm becomes unreadable. Plan a recovery flow or store a backup key in a cloud vault.
- Sync requires server components – Air-gapped setups cannot replicate changes until a network path to the Realm server exists.
- Version floor – The research brief indicates Realm versions before 2.0 lack built-in encryption. Confirm the exact version in the SDK release notes before relying on the
encryptionKeyoption. - Storage overhead – Encryption adds a small constant overhead (IV and auth tag per page). Compare on-disk size before and after enabling it to confirm there is no unexpected bloat in your dataset.
Verification checklist
- Build a minimal test target that creates an encrypted Realm, writes a record, then attempts to open the same file without the key. The unprotected open should fail.
- Compare the on-disk size of the Realm file before and after enabling encryption. Use
ls -lhon the simulator or device path to check for unexpected growth. - If using sync, make concurrent offline edits on two devices in a staging environment, reconnect, and verify the merged state matches the documented conflict rule.
- Check the Realm SDK release notes for the version that introduced encryption and confirm your dependency meets that floor.
Next steps
- Add a Realm SDK version that supports encryption to your iOS or Android build.
- Generate a 64-byte key once per install and store it in the platform keystore.
- Open the Realm with
encryptionKeyand define a migration block for future schema changes. - If cross-device data is required, provision a Realm Sync instance and enable the same Realm for sync.
- Run the verification checklist above before shipping.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.