Under the Hood
Consistency

Consistency models: from linearizable to eventual

'Eventually consistent' and 'strongly consistent' are the two words everyone knows and the two ends of a whole spectrum nobody teaches. In between sit the models that actually solve real bugs: causal consistency, and the session guarantees (read-your-writes, monotonic reads) that make an eventually-consistent system feel correct to a single user. This lesson lays the spectrum out from strongest to weakest, says exactly what each model promises and forbids, ties each to the coordination cost that buys it, and shows how the read-your-writes bug from the replication lesson is really a missing session guarantee.

Consistency models: from linearizable to eventual

The CAP lesson treated consistency as a single knob — you have it or you trade it away. In reality "consistency" is a spectrum of precisely-defined guarantees, and the useful engineering skill is knowing which one a given feature actually needs, because stronger guarantees cost more coordination (more latency, less availability) and weaker ones permit more anomalies. Reaching for "strong consistency" everywhere is as much a mistake as reaching for "eventual" everywhere; the craft is matching the model to the data.

A consistency model is a contract about what a read is allowed to return given the writes that happened before it. Here's the spectrum, strongest first.

Linearizability (strong consistency)

The strongest practical model. Linearizability says the system behaves as if there were a single copy of the data and every operation took effect instantaneously at some point between its start and its completion. The consequence that matters: once a write completes, every subsequent read — from any client, on any node — sees that write or a later one. There is no window where different clients see different values. It's the illusion that the distributed system is just one machine.

This is the most intuitive model (it's how a single variable in your program behaves), and it's exactly what you want for anything where staleness is a correctness bug: a distributed lock (two holders = disaster), a uniqueness check, a bank balance, a leader election. The cost is steep: to guarantee every read is current, nodes must coordinate on every operation — a read may have to confirm with a quorum that it isn't missing a newer write, a write must reach a quorum before completing. That coordination is round trips (latency, the PACELC "else-consistency" tax) and it's the availability you give up under partition (the CP choice). Linearizability is the gold standard and the expensive one.

Sequential and causal consistency

Two steps weaker, relaxing the "instantaneous real-time order" requirement:

  • Sequential consistency — all clients agree on one global order of operations, and each client's own operations appear in the order it issued them — but that global order need not match real (wall-clock) time. Everyone sees the same movie; it might be slightly behind live.
  • Causal consistency — the model that captures "what actually matters most of the time." It guarantees that operations which are causally related are seen in the right order by everyone, while operations that are concurrent (unrelated) may be seen in different orders on different nodes. Causality is the "this happened because of that" relation: if you post a message and I reply to it, everyone must see your message before my reply — a world where my reply shows up before the message it answers is nonsensical. But two unrelated messages in different groups have no causal link, so nodes are free to order them differently. Causal consistency is powerful because it's the strongest model that can still be fully available under partition — it forbids the anomalies humans actually notice (effects before causes) without paying for full linearizable coordination.

The classic causal-violation bug: comment threads where a reply appears above the comment it replies to, or a "removed from group" that arrives before the "added to group," because the two writes took different replication paths and nothing enforced their causal order.

Session guarantees: making eventual feel correct

Below causal sits a band of practical, per-client guarantees — often called session guarantees. They don't promise anything about what other users see; they promise that a single user's own experience is sane. This is the sweet spot for a lot of real apps, because a user mostly notices inconsistency in their own actions.

  • Read-your-writes — after you write something, your subsequent reads reflect it. (Other users might not see it yet — that's fine.) This is the one whose absence produces the vanishing-expense bug: you add an expense, your next read hits a lagging replica, and your own write is missing. Read-your-writes is the guarantee that bug violates.
  • Monotonic reads — successive reads never go backwards in time. Once you've seen a value, you never later see an older one. Its absence: you refresh and data you just saw disappears because your second read hit a replica lagging further behind the first.
  • Monotonic writes — your own writes are applied in the order you made them.
  • Writes-follow-reads — if you read a value and then write based on it, your write is ordered after the value you read.

The beautiful thing about session guarantees is how cheaply they buy correctness: you don't need global coordination, you just need to route a given user's requests consistently — pin them to one replica (fixes monotonic reads), or route their post-write reads to the primary for a window (fixes read-your-writes). Consistency becomes a routing decision, exactly as the replication lesson claimed — you get the feel of strong consistency for one user without paying for it globally.

Step down the ladder and watch the guarantees drop away as the coordination cost falls. Notice where session sits — it keeps the two guarantees a single user actually notices (read-your-writes, monotonic reads) for almost no cost, which is why it's the sweet spot for most apps.

Consistency model — strongest to weakest
Reads always current (globally)
Read-your-writes
Monotonic reads (never go backwards)
Preserves causal order
Converges eventually
coordination cost / latency
highest
Good for: Bank balances, distributed locks, inventory — where a wrong read is unacceptable. Every operation coordinates, so it is the slowest.

Consistency is a ladder, not a switch. Strong makes every replica agree instantly — and pays for it with coordination on every operation. As you step down, you trade guarantees for latency and availability: session guarantees are the sweet spot for most apps because they make a single user's own experience sane cheaply — just route that user's requests consistently. Eventual only promises replicas converge if writes stop — perfect for a like count, wrong for a balance. The skill is matching the model to the data, per feature.

Eventual consistency

The weakest useful model, and the most maligned. Eventual consistency promises only this: if writes stop, all replicas will eventually converge to the same value. It says nothing about when, and nothing about what you see in the meantime — reads can be stale, can go backwards, can see writes out of causal order. It is the price of an AP system staying available and fast.

"Eventual" sounds unacceptable until you notice how much of the world runs on it perfectly well: DNS (a record change propagates over minutes, and that's fine), CDN caches, like-counts, follower counts, search indexes. For data where a few seconds of staleness is invisible or harmless, eventual consistency is the right choice — it's what lets those systems be fast and always-up. The mistake isn't using it; the mistake is using it for a bank balance. (In practice, "eventually" is usually milliseconds, and modern AP stores layer session guarantees on top so individual users still get read-your-writes.)

Go deeper

Check yourself

Answer out loud, as if an interviewer asked. If you hand-wave, reread that section.

  1. Define linearizability in terms of the "single copy, instantaneous effect" illusion, state the concrete guarantee it gives a reader, and name the coordination cost that buys it.
  2. What does causal consistency guarantee and what does it deliberately allow? Give the reply-before-comment example, and explain why causal is "the strongest model still available under partition."
  3. Session guarantees promise nothing about other users. Explain read-your-writes and monotonic reads by the specific bug each one prevents, and why both can be achieved by routing rather than global coordination.
  4. Eventual consistency promises only convergence "if writes stop." Give two real systems for which it is the correct choice and explain why the staleness is harmless there.
  5. Explain why "strong consistency everywhere" is as much a design smell as "eventual everywhere," and describe the per-data-type question a senior engineer asks instead.
  6. Fable gets linearizability for free on balances but uses causal for chat and eventual for media. Explain where each comes from, and which session guarantee it would have to add when introducing a read replica.