Posted in Engineering

CRDTs Explained: How Conflict-Free Replicated Data Types Keep Distributed Data in Sync

Collaborative editors, offline-first mobile apps, and multi-region databases all face the same problem: two copies of the same data get changed at the same time, and they have to end up identical without anyone losing work. Conflict-free replicated data types, or CRDTs, are the best-studied answer. This explainer covers what they guarantee, the two ways they are built, the classic examples, and the libraries most developers reach for today.

At a Glance

ConceptSummary
What a CRDT isA replicated data type whose copies can be updated independently and always merge to the same state
GuaranteeStrong eventual consistency: replicas that received the same updates are in the same state
Two designsState-based (CvRDT): ship and merge whole states; operation-based (CmRDT): ship commuting operations
Formalized inShapiro, Preguiça, Baquero, Zawirski, “Conflict-free Replicated Data Types” (SSS 2011)
Popular librariesAutomerge (JavaScript/Rust) and Yjs (JavaScript)
Best forCollaboration, offline-first apps, and multi-replica systems that must accept writes anywhere

Short Verdict

Reach for CRDTs when every replica must accept writes without waiting for the others, such as a document edited offline or a counter updated in several regions. You trade some storage overhead and a constrained set of data types for the ability to merge automatically, with no conflict-resolution code and no rollbacks. If your data needs strict invariants that span many records, such as “this account balance must never go negative,” a CRDT alone is the wrong tool.

The Guarantee: Strong Eventual Consistency

Plain eventual consistency only promises that replicas will agree at some point after updates stop arriving, and usually needs some way to arbitrate conflicts or roll back. The 2011 paper by Marc Shapiro, Nuno Preguiça, Carlos Baquero, and Marek Zawirski formalized a stronger property, strong eventual consistency (SEC): any two replicas that have delivered the same set of updates are in equivalent states, at all times. Because convergence is built into the data type, no rollback or arbitration step is needed. The paper also shows that replicas of a CRDT converge in a self-stabilizing way despite any number of failures.

Two Ways to Build a CRDT

State-based (CvRDT)Operation-based (CmRDT)
What replicas sendTheir full stateIndividual update operations
Mathematical requirementStates form a join semilattice; merge computes the least upper bound; updates only move the state upwardConcurrent operations must commute
Network requirementVery little: states can arrive late, twice, or out of orderOperations must be delivered in causal order
Trade-offSimple delivery, but sending whole states can be heavySmall messages, but needs a reliable causal delivery layer

The paper proves both designs give strong eventual consistency and that each can emulate the other, so the choice is an engineering trade-off about bandwidth and delivery guarantees rather than about correctness.

Classic Examples

  • Increment-only counter. Each replica keeps a vector with one slot per replica and only increments its own slot. Merging takes the per-slot maximum, and the counter’s value is the sum. This is what most later writing calls a G-Counter.
  • Increment/decrement counter. Two increment-only counters, one for increments and one for decrements; the value is the difference. Commonly called a PN-Counter.
  • Add-only set. Sets merge by union, so adds can never conflict. Commonly called a G-Set.
  • Add/remove set with tombstones. The paper’s U-Set pairs an add set with a remove set and assumes each element is added only once; the familiar 2P-Set works the same way, and the trade-off is that a removed element cannot come back.
  • Directed graph. The paper’s op-based graph tags vertices and arcs with unique IDs; if one replica removes a vertex while another adds an arc to it, the removal wins.

Libraries You Can Use Today

Automerge is a library of CRDT data structures for collaborative apps. Each user keeps a local copy that can be edited offline and saved to disk, and changes merge automatically when devices reconnect. It is written in Rust, compiles to WebAssembly for browsers, runs on Node.js, exposes a C API for platforms without a JavaScript engine, and is network-agnostic: it can sync over WebSockets, peer-to-peer WebRTC, or even a file passed by email. The companion automerge-repo library provides ready-made networking and storage.

Yjs exposes CRDTs as shared types, similar to familiar maps and arrays, that many users can edit at once and that emit change events. It also makes no assumptions about the network: as long as every update eventually arrives, in any order, documents converge. It offers network adapters for WebSocket, WebRTC, and Hyper, persistence providers, and bindings for editors including ProseMirror, Tiptap, Monaco, Quill, and CodeMirror.

Pros

Writes never wait on other replicas, which makes offline editing and multi-region writes straightforward. Merges are automatic and deterministic, so there is no conflict-resolution code to write or test. Convergence is a mathematical property of the type, not a hope about timing, and it holds even when messages are delayed, duplicated, or reordered (for state-based designs).

Cons

Metadata such as per-replica vectors and tombstones grows over time and needs compaction or garbage collection. The automatic merge result is consistent but not always what a user intended, so applications still need to design sensible semantics. And CRDTs cannot enforce global invariants on their own, such as uniqueness across records or a minimum balance, which still require coordination.

Bottom Line

CRDTs turn “merge conflicts” into a property of the data type rather than a problem for application code. They are the right default for collaborative and offline-first features, and libraries like Automerge and Yjs make them practical without implementing the math yourself. Pair them with coordination only where you truly need global invariants.

Frequently Asked Questions

  • What does CRDT stand for? Conflict-free replicated data type.
  • What is strong eventual consistency? A guarantee that any replicas which have received the same updates are in the same state, with no rollbacks needed.
  • State-based or operation-based? State-based tolerates unreliable delivery but sends more data; operation-based sends small messages but requires causal delivery. Both converge.
  • Do I need a server? No. Libraries like Automerge and Yjs work peer-to-peer or through a server, because convergence does not depend on a central authority.

Sources


Discover more from Software Online Review

Subscribe to get the latest posts sent to your email.

Unknown's avatar

Author:

Innovations, logic & design thinking