Articles

What Is a CRDT? Conflict-Free Replicated Data Types

A CRDT is a data structure that merges concurrent edits from multiple replicas automatically, without coordination or conflicts, using math instead of locks.

Chisato Chisato · · 4 min read
Server racks connected by cables

A CRDT, or conflict-free replicated data type, is a data structure designed so that multiple replicas can be updated independently — even while offline or disconnected from each other — and later merged back into a single consistent state automatically, with no coordination and no possibility of a merge conflict. The trick is mathematical: CRDT operations are designed to be commutative, associative, and idempotent, so it doesn’t matter what order updates arrive in or whether one arrives twice — every replica converges to the same result.

The problem CRDTs solve

In a distributed system, the easy way to keep replicas consistent is to make every write go through a single coordinator that orders operations — but that reintroduces a bottleneck and a single point of failure, undermining the whole point of replicating data. See what database replication is and the CAP theorem for the underlying tension: you can’t have perfect consistency, availability, and partition tolerance all at once.

The alternative is to let any replica accept writes independently and sync later. That’s great for availability, but it raises an obvious question: what happens when two replicas each accepted a conflicting edit to the same piece of data while disconnected? Traditional approaches punt this to the application — “last write wins,” a manual merge UI, or an outright rejection. CRDTs instead design the data type itself so that any set of concurrent updates has one well-defined merge result, computed automatically.

How convergence actually works

CRDTs come in two flavors that produce the same guarantee through different mechanisms.

State-based (CvRDTs) replicate their entire state periodically. Merging two replicas means applying a merge function that must be commutative, associative, and idempotent — so merge(A, B) == merge(B, A), order doesn’t matter, and merging the same state twice changes nothing. A simple example is a grow-only counter: each replica tracks its own increment count, and the merge function takes the max of each replica’s count, then sums them. No replica’s increments are ever lost or double-counted no matter how the merges are interleaved.

Operation-based (CmRDTs) instead broadcast individual operations to other replicas, relying on the network to deliver them (in any order, possibly with duplicates) and on the operations themselves being commutative. A counter that broadcasts “+1” operations converges the same way regardless of what order those messages arrive in.

Both approaches trade off differently on bandwidth and how much history needs to be retained, but they guarantee the same thing: strong eventual consistency — once two replicas have seen the same set of updates, they hold identical state, full stop, with no reconciliation step needed.

Common CRDT types

  • G-Counter / PN-Counter — grow-only and increment/decrement counters that merge by tracking per-replica contributions separately.
  • G-Set / OR-Set — sets that merge by union; an OR-Set (observed-remove set) additionally handles concurrent add/remove of the same element without the removes accidentally winning over later adds.
  • LWW-Register — a single value where concurrent writes are resolved by a tiebreaker (commonly a timestamp), trading a bit of “last write wins” semantics for simplicity.
  • RGA / sequence CRDTs — ordered lists designed so concurrent inserts near the same position converge to a consistent order, the mechanism behind real-time collaborative text editing.

Where CRDTs show up in practice

Collaborative editors (the kind where multiple people type into the same document simultaneously and it just works) are the most visible use case — sequence CRDTs let each client apply local edits instantly and merge everyone else’s edits without a central lock. Offline-first mobile and local-first software rely on CRDTs for the same reason: a user can edit on a plane, reconnect, and have their changes merge cleanly with everyone else’s. Distributed caches, shopping carts, and presence/counter features (like counts, view counts) in large-scale systems also use CRDT-like counters because they need to accept writes at many edge locations without a central coordinator serializing every increment — a pattern that shows up naturally behind a CDN or multi-region deployment.

CRDTs vs operational transformation vs locking

| | Locking / coordinator | Operational transformation (OT) | CRDT | |---|---|---| | Requires central coordination | Yes | Usually (a server transforms ops) | No | | Works offline | Poorly | Poorly | Well | | Merge conflicts | Prevented by blocking | Resolved by transforming ops | Prevented by design | | Complexity | Low | High (transform functions are notoriously hard to get right) | Moderate, concentrated in the data type | | Typical use | Traditional databases, single-writer systems | Older collaborative editors (e.g. early Google Docs) | Modern collaborative apps, offline-first apps, distributed counters |

The tradeoffs

CRDTs aren’t free. State-based CRDTs can grow tombstones — markers for deleted elements that must be kept around so a late-arriving delete doesn’t get undone by a concurrent add — which can bloat memory over time if not periodically compacted. Not every data structure has a natural conflict-free merge (a bank balance that must never go negative, for instance, needs more than a CRDT can guarantee on its own). And LWW-style resolution, while simple, silently discards one of the concurrent writes — that’s a design choice, not automatic conflict resolution in the intuitive sense.

The takeaway

A CRDT is a data structure engineered so that concurrent, uncoordinated updates from multiple replicas always merge into the same result, in any order, without conflicts. That makes it the backbone of offline-first apps and real-time collaborative editing — trading some memory overhead and a constrained set of usable data types for the ability to accept writes anywhere and sync whenever a connection is available.

The Lycoris Team The Lycoris Team · · 5 min read

The Raft Consensus Algorithm, Explained

Raft is a consensus algorithm that lets a cluster of servers agree on a shared state even when some nodes fail. How leader election and log replication work.

#Distributed Systems #Computer Science #Databases
The Lycoris Team The Lycoris Team · · 4 min read

What Is MVCC? Multi-Version Concurrency Control

MVCC lets readers and writers work on a database concurrently without blocking each other, by keeping multiple versions of each row instead of locking it.

#Databases #Computer Science #Backend