Tier 2 · Distributed Core

The Consistency Spectrum

Linearizable, sequential, causal, eventual — and which one you can actually afford

⏱ 18 min distributedconsistencytradeoffs

Three unrelated things called "consistency"

Clear this up first, because the overloading causes genuine confusion:

They are not the same thing and don't imply one another. A system can be ACID-consistent and give you stale reads all day.

The two axes

Most confusion dissolves once you see that "strong consistency" is really two separate properties:

Single object Multiple objects
Real-time order matters Linearizability Strict serializability
Any order will do Sequential consistency Serializability

The strong models

Linearizability. The system behaves as if there is a single copy of the data and every operation takes effect atomically at some instant between its invocation and its response. Consequences: no stale reads, and every client sees changes in the same order at the same time.

The cost is unavoidable: to guarantee no stale read, the node answering must confirm with others that it isn't behind — a round trip to a quorum, at minimum. Linearizability's price floor is the network round-trip time, and it's why it becomes expensive across regions and impossible during a partition.

Sequential consistency. All operations appear in some single total order that respects each client's own program order — but not necessarily real time. If I write and then phone you and you read, you might still see the old value. Weaker, cheaper, and rarely offered explicitly.

The weak models

Causal consistency. Operations causally related (in the happens-before sense from clocks) are seen in the same order by everyone. Concurrent operations may be seen in different orders by different observers.

This one deserves emphasis, because of a genuinely important theoretical result:

Causal consistency gives you things users actually notice: replies never appear before the message they answer, and an unfriend-then-post sequence isn't reordered so the post is visible to the person you just removed.

Eventual consistency. If writes stop, replicas eventually converge. That is the entire guarantee. It says nothing about when, and nothing about what you see in the meantime — including values going backwards. Useful, and much weaker than most people assume when they choose it.

The client-centric guarantees

Between causal and eventual sits a set of session guarantees — cheap, targeted promises that fix specific user-visible weirdness. These are what you actually reach for in practice:

These are covered mechanically in the replication lesson. The point here is architectural: you can buy them individually and cheaply, usually by routing a session to a consistent replica or tracking a version token — without paying for linearizability across the whole system.

The hierarchy

From strongest and most expensive to weakest and cheapest:

Strict serializability   (Spanner)
        ↓
Linearizability          (etcd, ZooKeeper, single-leader reads)
        ↓
Sequential consistency
        ↓
Causal consistency       ← strongest available under partition
        ↓
Session guarantees       (read-your-writes, monotonic reads)
        ↓
Eventual consistency     (Dynamo-style defaults, DNS)

Each step down removes coordination, and therefore removes latency and adds availability.

What real systems give you

System Default Available on request
etcd / ZooKeeper Linearizable writes Linearizable reads (ZK reads are not, without sync)
Postgres (primary) Read Committed, linearizable per connection Serializable
Postgres read replica Eventual (async) Route to primary
DynamoDB Eventually consistent reads ConsistentRead=true
Cassandra Tunable per query QUORUM/ALL
MongoDB Causal within a session readConcern: majority/linearizable
Spanner Strict serializability Stale reads for speed

Note how many are tunable per operation. That's the practical takeaway: consistency is a per-request decision, not a system-wide property.

Choosing

Work backwards from the consequence of being wrong:

Then, crucially: most systems are mostly the third and second categories, with a small critical core in the first. Designing everything to the standard of the critical core is the most common way to make a system needlessly slow and fragile.

What to take away

Check yourself

  1. A database is serializable. Can a transaction read stale data?

  2. What is the strongest consistency model a system can provide while remaining available during a network partition?

  3. Users complain that after saving their profile, a refresh sometimes shows the old value. What is the cheapest correct fix?

  4. Why does linearizability have a latency floor equal to a network round trip?