Knowledge Guide
HomeSystem DesignReplication

hard CRDTs: State-Based vs Operation-Based

Converging without coordination

Conflict-free Replicated Data Types (CRDTs) let replicas accept writes independently — even while partitioned — and still converge to the same value with no consensus round and no locking, because reconciliation is deliberately restricted to a merge operation that is commutative, associative, and idempotent: apply it in any order, any number of times, and the result is the same. That single restriction is the entire trick behind every CRDT; state-based and operation-based CRDTs differ only in what goes on the wire and what the transport underneath is required to guarantee.

Two replicas of a G-Counter reconcile two ways. State-based: each replica gossips its whole counter state to the other; merge is an elementwise max, and because that merge is commutative, associative and idempotent, duplicate, reordered, or lost-then-resent messages are all tolerated. Operation-based: each replica broadcasts only the increment operation; because increment is not idempotent, the broadcast layer must deliver every operation exactly once and in causal order, or the count becomes wrong.
Two replicas of a G-Counter reconcile two ways. State-based: each replica gossips its whole counter state to the other; merge is an elementwise max, and because that merge is commutative, associative and idempotent, duplicate, reordered, or lost-then-resent messages are all tolerated. Operation-based: each replica broadcasts only the increment operation; because increment is not idempotent, the broadcast layer must deliver every operation exactly once and in causal order, or the count becomes wrong.

State-based CRDTs (CvRDTs)

Mechanism: each replica holds its full local state and periodically gossips that entire state to other replicas (or a coordinator polls it). On receipt, a replica doesn't overwrite its state with the incoming one — it computes merge(local, received), a join that returns the least upper bound of the two states on a semilattice. Because that join is commutative, associative, and idempotent by construction, it doesn't matter which order messages arrive in, whether the same state arrives twice, or whether a message is lost and only shows up on a later retransmission — the eventual merged result is identical either way.

That tolerance is what makes state-based CRDTs attractive operationally: the transport underneath can be as weak as unreliable, at-least-once gossip. No causal ordering, no deduplication, no delivery guarantee beyond "it'll get there eventually, maybe more than once." The cost is bandwidth — sending the whole state on every round trip gets expensive as state grows, which is why production systems often ship delta-CRDTs (only the recent delta of the state, not the whole thing) as a bandwidth optimization on top of the same state-based model.

Operation-based CRDTs (CmRDTs)

Mechanism: instead of exchanging state, each replica broadcasts the operation it performed — e.g. increment(A) — and every other replica applies that operation directly to its own local state. Messages are small: an operation, not a whole document or counter vector.

But the safety argument moves from the merge function to the transport. Operations must be commutative (concurrent, causally-unrelated operations may arrive in different orders on different replicas and must still produce the same result) — that part mirrors the state-based case. The new requirement is delivery: an operation like increment is not idempotent on its own — applying it twice produces a different (wrong) result — so the broadcast layer underneath must guarantee exactly-once delivery in causal order: no operation is delivered twice, none is dropped, and causally-dependent operations (e.g. an "add" that must be seen before a later "remove" of the same item) arrive in the right order. Building that reliable causal-broadcast layer — typically deduplication by operation ID plus a causal-order buffer keyed on something like a vector clock — is real infrastructure, which is the price paid for the smaller wire messages.

Traced example — a G-Counter under both models

A G-Counter (grow-only counter) keeps one slot per replica; a replica only ever increments its own slot, and the total is the sum of all slots. Two replicas, A and B, each increment their own slot once, concurrently, starting from {A:0, B:0}:

ModelWhat's sentHow B reconcilesResult if the message is delivered twice
State-basedA's whole state {A:1, B:0} merge = elementwise max({A:1,B:0}, {A:0,B:1}) = {A:1,B:1} — total 2 Merging {A:1,B:0} a second time: max({A:1,B:1},{A:1,B:0}) = {A:1,B:1} — still 2. Idempotent merge absorbs the duplicate.
Op-basedthe operation increment(A) B applies the op to its copy of slot A: A:0→1 — total 2 Applying increment(A) a second time: slot A goes 1→2 — total 3, wrong. The op itself has no memory of "have I already run," so the transport must guarantee it is delivered exactly once.

Both models reach the same correct total, 2, under normal delivery — the difference only shows up under message duplication, which is exactly the failure state-based CRDTs are engineered to shrug off and op-based CRDTs must prevent one layer down, in the broadcast mechanism.

Pitfalls

When CRDTs beat consensus (and when they don't)

Takeaways


Sources: Shapiro, Preguiça, Baquero & Zawirski, “A comprehensive study of Convergent and Commutative Replicated Data Types,” INRIA research report RR-7506 (2011), for the CvRDT/CmRDT distinction and the join-semilattice merge requirement; Martin Kleppmann, “Designing Data-Intensive Applications,” ch. 5, on CRDTs vs. Operational Transformation. See also this guide's CRDT overview page (“CRDTs — Conflict-Free Replicated Data Types”) for the catalog of CRDT types (G-Counter, PN-Counter, OR-Set, sequence CRDTs). Re-authored for this guide; G-Counter and state-vs-op diagrams hand-authored as SVG.

🤖 Don't fully get this? Learn it with Claude

Stuck on CRDTs: State-Based vs Operation-Based? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **CRDTs: State-Based vs Operation-Based** (System Design) and want to truly understand it. Explain CRDTs: State-Based vs Operation-Based from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **CRDTs: State-Based vs Operation-Based** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **CRDTs: State-Based vs Operation-Based** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **CRDTs: State-Based vs Operation-Based** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes