Two replicas of the same counter each accept writes while offline, then reconnect in some unpredictable order — no coordinator, no locking, maybe not even in the same order twice. Is there a data structure where "just apply whatever you both have" is guaranteed to produce the same answer, no matter the order?
Click P and Q's buttons in whatever order and however many times you like — they never talk to each other while doing it. Then hit "Merge": both boxes turn out exactly the same, holding the full total of everything either one ever did.
A G-Counter (grow-only counter) CRDT gives every replica its own slot that only that replica may increment. Merging two replicas' states takes the pointwise max of every slot:
- , — replica 's slot count as last seen by state or .
- — the merged state's slot : whichever of or has seen more of replica 's increments.
- value(state) — the counter's logical total: the sum of every slot.
- Merge is commutative and idempotent
for every slot, so it never matters who initiates a merge — and merging a state with itself changes nothing, so re-merging the same update twice is harmless.
- Merge is associative
over three or more values doesn't depend on how they're grouped, so merging replicas two at a time, in any order or pairing, reaches the exact same final state as merging them all at once.
Increment P and Q in any pattern — three P's then one Q, alternating, whatever. The panel always computes merge(P, Q) and merge(Q, P) side by side: they never disagree, at any point, no matter what either replica has done up to that moment.
Three replicas, each incrementing only their own slot, entirely independently:
- Independent local states
- P increments 3 times:
- Q increments 2 times:
- R increments once:
None of them has seen either of the others' updates.
- Merging P and Q, either direction
. Merging the other way, , produces the exact same .
- Bringing in R, in either grouping
, and also comes out to — total value , regardless of which two replicas happened to sync with each other first.
P, Q, and R each incremented independently, with no coordination. Using the sync buttons below in any order you like, get all three replicas to fully converge.
A CRDT's merge rule is built so that commutativity, associativity, and idempotence hold by construction — not by careful protocol design, but because (or union, for other CRDTs) simply has those properties. That's what "no coordination" really buys: replicas can accept writes and sync with whichever peers happen to be reachable, in whatever order, and still be mathematically guaranteed to converge to one shared state. The next chapter's Dynamo-style store reaches for a different tool — vector clocks — for exactly the writes a CRDT's merge rule can't silently resolve on its own.