Module 13 · Distributed fundamentals · Lesson 17 of 18
CRDTs
Data types designed so that concurrent updates on different replicas always merge to the same result, with no coordination and no conflicts to resolve. Counters, sets, registers and sequences.

The video walkthrough is part of Pro.
See what Pro includesWhy it matters
Vector clocks detect concurrent writes and hand the conflict to the application. For many data shapes, that handoff can be eliminated: design the data type so that any two concurrent updates can be merged automatically into the same result everywhere, no matter the order they arrive. That is a CRDT. It is why offline-first apps, collaborative editors, distributed counters and multi-region caches can accept writes anywhere and still converge without a leader, and it is the modern answer to "how do you handle conflicts" in an interview.
The idea
A conflict-free replicated data type is a data structure with a merge function that is commutative, associative and idempotent: merging in any order, any grouping, and any number of times gives the same result. Replicas apply local updates immediately, exchange state or operations whenever they can, and are guaranteed to converge once they have seen the same updates. No locks, no consensus, no manual conflict resolution; the price is that the type's semantics are fixed in advance.
Two flavours
| State-based (CvRDT) | Operation-based (CmRDT) | |
|---|---|---|
| What is shipped | The whole state (or a delta) to be merged with a join function | Each operation, applied at every replica |
| Network requirement | Any; duplicates and reordering are harmless because merge is idempotent | Reliable, causally ordered delivery (or operations made idempotent and commutative themselves) |
| Cost | Larger messages; deltas mitigate | Small messages; needs delivery guarantees |
| Examples | G-Counter, OR-Set state, Riak data types | Text sequences in Yjs and Automerge (operation logs with causal metadata) |
The core types
- 1
G-Counter (grow-only)
One slot per replica; each replica increments only its own slot; value is the sum; merge is element-wise max. Concurrent increments on two replicas never collide because they live in different slots. - 2
PN-Counter
Two G-Counters, one for increments and one for decrements; value is their difference. Likes, inventory estimates, view counts across regions. - 3
LWW-Register
A value with a timestamp; merge keeps the higher timestamp. Simple and converges, but it is last-write-wins: concurrent writes lose one, so use it only where that is acceptable or timestamps are hybrid logical clocks. - 4
OR-Set (observed-remove)
Each add tags the element with a unique id; remove deletes the tags observed at that replica. A concurrent add and remove of the same element resolves to present (the new tag was not observed by the remover), which matches user intuition. Shopping carts, tag sets, membership lists. - 5
Sequences (RGA, LSEQ, Yjs's YATA)
Each character or item gets a unique position identifier that orders it between its neighbours; concurrent inserts at the same spot are ordered deterministically by identifier. This is collaborative text editing without a server deciding. - 6
Maps and composites
Maps of CRDTs keyed by field, with per-field merge, build documents: a JSON CRDT (Automerge) composes registers, counters, sets and sequences.
What CRDTs cannot do
They cannot enforce global invariants that require knowing everyone's state at once: a bank balance that must never go negative, a seat that can be sold once, a unique username. Those need coordination (consensus, a leader or a reservation protocol). CRDTs also carry metadata: tombstones for removed elements, per-replica slots, position identifiers, which grow and must be compacted. And their merge semantics are fixed: an OR-Set says add-wins, and if your product needs remove-wins you need a different type. Choose a CRDT by asking "what should happen under concurrency" and checking the type's answer.
Where they run
Collaborative editors (Figma's multiplayer, Apple Notes, Yjs- and Automerge-based tools), offline-first mobile apps that sync later, Riak's and Redis Enterprise's conflict-free data types for multi-region active-active, distributed counters and presence in chat systems, and SoundCloud's and others' multi-datacenter caches. Operational transformation, next lesson, is the older alternative for text and the one Google Docs still uses.