Realm → ObjectBox Migration
This guide walks you through moving a project from Realm to ObjectBox with minimal downtime: planning, schema mapping, data export/import, and code changes.
1) Plan & inventory
-
List entities, fields, relations, and indexes in Realm.
-
Decide where many-to-many relations become relation entities or reciprocal
ToMany
in ObjectBox.ObjectBox supports many-to-many relations, which can be modeled using a dedicated "link entity" or by using two
ToMany
relations that point to each other (a backlink). This is a necessary design decision during migration.Reference: ObjectBox Docs: Relations
-
Identify fields that should become indexes in ObjectBox.
Just like in Realm, adding indexes in ObjectBox is crucial for query performance. Fields that are frequently used in query conditions are prime candidates for an index.
Reference: ObjectBox Docs: Indexes
-
Note any custom types requiring Converters in ObjectBox.
ObjectBox can only persist a specific set of standard property types. If your Realm model uses custom data types (e.g.,
java.util.Date
), you must create aPropertyConverter
to map them to a type that ObjectBox can store.Reference: ObjectBox Docs: Custom Types using PropertyConverter
2) Schema mapping
Start with the API mapping and replicate the domain model:
- Replace
RealmObject
models with@Entity
classes/structs. - Add
@Id
fields (auto-assigned IDs on insert by default). - Add
@Index
on hot query fields. - Add relation fields (e.g.,
ToMany
) per binding conventions.
Unless you mark the ID as assignable (e.g., @Id(assignable = true)
in Java/Kotlin), ObjectBox assigns IDs automatically on insert. For migrations where you must preserve IDs, enable assignable IDs and ensure uniqueness before put()
.
3) Data export from Realm
- Use Realm’s APIs to iterate and serialize objects to a neutral format (JSON/CSV/custom).
- Keep foreign keys or relation references in the export so you can re-link after import.
- For large datasets, export in batches.
4) Import into ObjectBox
-
Create entities in ObjectBox mirroring the mapped schema.
-
Transaction batching: use
store.runInTx { … }
andbox.put(collection)
to import efficiently.This is the most efficient way to import data. Wrapping the operation in a transaction minimizes disk I/O, and using the
put(Collection)
method is significantly faster than putting objects one by one in a loop.Reference: ObjectBox Docs: Transactions and Write Performance
-
Reconstruct relations after the base entities are inserted (you’ll have the new IDs if you didn’t preserve old ones).
Import tips
- Validate each batch; log/skip malformed records.
- If preserving IDs, enable assignable IDs before calling
put()
.
5) Replace code paths
- Reads:
box.get(id)
/ queries per binding. - Writes:
box.put(obj or collection)
. - Deletes:
box.remove(id|obj|collection)
. - Wrap multi-step operations in a transaction.
6) Testing & verification
- Parity tests: compare counts, spot-check random samples.
- Query parity: replicate key Realm queries in ObjectBox; compare results.
- Performance baselines: measure cold/warm reads, writes, and batch operations.
7) Rollout
- Ship behind a feature flag if feasible.
- Keep a reversible path (backup exports) for the first versions.
- Monitor crash/error reports and data integrity metrics.