𝗖𝗥𝗗𝗧𝘀 𝗶𝗻 𝗞𝗼𝘁𝗹𝗶𝗻 𝗠𝘂𝗹𝘁𝗶𝗽𝗹𝗮𝘁𝗳𝗼𝗿𝗺: 𝗞𝗶𝗹𝗹 𝗬𝗼𝘂𝗿 𝗦𝘆𝗻𝗰 𝗦𝗲𝗿𝘃𝗲𝗿

Most teams build a central server to handle data conflicts. The server receives writes, picks a winner, and hopes for the best. This creates a single point of failure and complex code to maintain.

Conflict-Free Replicated Data Types (CRDTs) change this. Every device reaches the same state without a central boss. It is a mathematical guarantee.

You can replace your sync backend with simple blob storage. Your server becomes a relay that holds data blobs. It does not need to understand your data.

Use these primitives for your mobile apps:

• LWW-Register: Use for user profiles and settings. • G-Counter: Use for analytics or view counts. • PN-Counter: Use for inventory or cart totals. • OR-Set: Use for tags and favorites.

For most mobile apps, LWW-Registers and OR-Sets cover almost everything.

Implementation Tip: When you build an LWW-Register, always include a nodeId. If two updates have the exact same timestamp, the nodeId acts as a tiebreaker. Without this, your devices will not sync to the same state.

State-based vs. Operation-based:

Choose State-based (CvRDT) for mobile. It works on unreliable networks because the merge process is idempotent. If a sync fails halfway, you just try again.

Avoid Operation-based (CmRDT) early on. It requires exactly-once delivery. Building that infrastructure on mobile networks is difficult and adds the complexity you want to avoid.

The Architecture:

  1. Build your CRDT logic in the commonMain module of your Kotlin Multiplatform project.
  2. Use SQLDelight to store the data locally.
  3. Sync the data blobs to a service like S3 or Cloud Storage.
  4. Your backend stays simple and cheap.

Stop building complex sync engines. Use CRDTs to move the logic to the client. This lets you focus on building features instead of managing server rotations.

Source: https://dev.to/software_mvp-factory/crdts-in-kotlin-multiplatform-kill-your-sync-server-28n8