Consistency Models

Consistency Models: What "Consistent" Has To Mean

A consistency model is a contract about which histories the system is allowed to produce — that is, which observations you will never make. "Strong consistency" names no such contract, and the first skill this module teaches is refusing the phrase until someone says which model they mean.

▶ Run the lab

The question this answers

The question

Someone says the database is "strongly consistent". What have they actually told me?

The guarantee — the property claimed, and its scope

A consistency model constrains the set of observable histories: it is a statement of the form "you will never observe X". Nothing more and nothing less. A model with no forbidden observation is not a guarantee, and a phrase like "strong consistency" forbids nothing because it names no model.

Everything below is bought to hold this sentence. "Strongly consistent" with no scope attached is a slogan, not a guarantee — read what it actually covers, and what it explicitly does not.

What a node knows — observation versus inference

A node knows its own state and the operations it has processed. A consistency model is a claim about what *readers across the whole system* may observe, so no single node can verify it locally — which is why consistency is checked by an external observer comparing histories, not by asking a replica whether it is up to date.

A node knows its own state and the messages that arrived. Everything else is inference from evidence that was already stale. "B has not replied in five seconds" is knowledge; "B is down" is a decision — and usually the bug.

What guarantee?What does a node know?How does it work?What can fail?How does it fail?Where is coordination?What holds under failure?How does it recover?How would you know?What is the simpler thing?
consistencyguaranteesmodelsvocabulary

A model is a set of forbidden observations

The productive way to hold consistency models is not "how fresh is my data" but "which histories has the system promised it will never produce?" Linearizability forbids a read that returns an older value than a read that completed before it. Monotonic reads forbids a session seeing time run backwards. Eventual consistency forbids nothing that you can observe in a finite run — which is a real and important thing to notice about it.

Framing it this way makes the models comparable, and it makes the useless phrases obvious. "Strongly consistent" forbids nothing, because it names no history. Ask the follow-up: strong in what sense — linearizable? serializable? read-your-writes? These three are genuinely different properties, and each of them is called "strong consistency" by somebody's marketing.

ModelForbidsScope
LinearizableprotocolA read returning a value older than one already returned to a completed earlier operationSingle operations on a single object
SequentialprotocolProcesses disagreeing about the order of operations — but real-time order need not be respectedSingle operations, all objects
CausalprotocolObserving an effect before its causeOperations related by happened-before
Session guaranteesprotocolA session seeing its own history incoherently — own writes missing, reads going backwardsOne session
EventualprotocolNothing observable in a finite run; only that divergence does not persist forever once writes stopWhole system, in the limit
SerializableprotocolAn outcome not producible by *some* serial execution of the transactionsMulti-operation transactions
Strict serializableprotocolBoth of the above — some serial order, and that order respects real timeMulti-operation transactions
The models this domain uses, by what each forbids

Two axes, not one ladder

People try to arrange these on a single line from weak to strong, and it does not work, because two independent questions are in play. Axis one: recency. Does an operation see the effects of operations that completed before it in real time? That axis runs eventual → session → causal → sequential → linearizable. Axis two: transactional isolation. Is a multi-operation, multi-object transaction equivalent to some serial execution? That axis runs read-uncommitted → read-committed → snapshot → serializable, and belongs to the Database domain.

The two axes are orthogonal, which is the subject of Serializability vs Linearizability: Two Different Properties and the single most common source of confident error in this material. A database can be serializable and not linearizable. A key-value store can be linearizable and have no transactions at all. Only their conjunction — strict serializability — gives you what most people imagine when they say "ACID and distributed".

  • Recency axis: what a *read* may return relative to writes that already completed.
  • Isolation axis: what a *transaction* may observe relative to other concurrent transactions.
  • Saying "we need strong consistency" typically conflates one point on each axis, and the two are usually purchased separately.
  • Scope is part of the model: "linearizable per key" and "linearizable across keys" are dramatically different products.

The vocabulary discipline, applied

When a vendor, a design doc or a colleague says "consistent", there are four questions that convert the claim into something you can build on. They are short, and asking them is not pedantry — every one of them has been the root cause of a production incident.

The most valuable of the four is the last. A guarantee that applies to one key and not across keys is extremely common and rarely stated, and a system built assuming cross-key guarantees on a per-key store will produce anomalies that look like application bugs for months.

1. Which model?      linearizable / serializable / causal / session / eventual
2. Which operations? all reads? only reads at a level? writes too? transactions?
3. Under what conditions?  steady state only, or also during a partition or failover?
4. Over what scope?  one key? one partition? one region? the whole dataset?

"Strongly consistent" answers none of these.
"Linearizable single-key reads and writes within a region, degrading to
 unavailable for the minority side of a partition" answers all four.
The four questions

Key points

  • A consistency model is a set of histories the system promises never to produce.
  • "Strong consistency" names no model and forbids nothing — always ask "strong in what sense?"
  • There are two orthogonal axes: recency of single operations, and isolation of transactions.
  • Scope is part of the guarantee. Per-key linearizability is not cross-key linearizability.
  • Consistency cannot be verified by asking a replica; it is a property of histories observed across the system.

The chain, answered

Every field here is required, which is why no lesson in this domain can recommend a design without naming what an operator sees when it fails, what survives the partition, what repairs it afterwards, and the simpler thing to consider first.

How it works
  • Define the set of legal sequential histories for the data type (a register, a counter, a set).
  • Observe a concurrent history: the invocations and responses of every operation, with real times.
  • The model states a condition under which that concurrent history is acceptable — typically the existence of a sequential history that is legal and preserves some ordering constraint.
  • The model is *satisfied* if such a witness exists for every possible execution, and violated by a single counterexample history.
  • Systems are checked against models empirically by recording histories and searching for a witness — this is what linearizability checkers do.
What can fail at the boundary
  • A replica serves a value older than one already returned elsewhere.
  • Two processes observe two operations in opposite orders.
  • An effect becomes visible before its cause on some replica.
  • A transaction observes a state no serial order could have produced.
  • A guarantee that holds within a partition silently fails to hold across partitions.
How it fails — what an operator sees
  • Anomalies attributed to application bugs: the team spends weeks looking for a race in the code when the read path simply offers a weaker model than the code assumes. Observable as intermittent, unreproducible data inconsistencies with no error signal.
  • Guarantee lost at a boundary: an operation touching two keys, two partitions or two regions gets none of the per-key guarantee the team relied on. The operator sees invariant violations that "cannot happen" concentrated on multi-key operations.
  • Silent downgrade under failover or degraded mode: the system falls back to a weaker read path during an incident, and the guarantee the design depended on is absent for exactly the duration of the incident.
  • Cross-team mismatch: two services assume different models of the same store, and the resulting corruption appears at the boundary between them with each team's telemetry clean.
Where coordination is required
  • Stronger recency guarantees require more communication before an operation can return, and the strongest require it on every operation.
  • The coordination is not only latency — it is availability, because an operation that must hear from other nodes cannot complete when it cannot reach them. See Coordination Couples Availability.
  • Session and causal guarantees are cheap precisely because they require the *client* to carry information rather than requiring nodes to agree.
What still holds under failure
  • Weak models are unaffected by partitions — they promised little and continue to deliver it.
  • Strong models must either block or return errors on the side of a partition that cannot reach a quorum. See CAP: What the Theorem Actually Says.
  • Many systems silently switch models under failure; whether yours does is a question with a definite answer that is usually undocumented.
How it recovers
  • Detect: run a history checker against the real system under fault injection rather than trusting documentation. See Fault Injection: The Catalogue, and Which Faults Are Hard.
  • Contain: make degraded read paths explicit and observable, so a weaker model during an incident is a signal rather than a surprise.
  • Recover: once a partition heals, weak-model systems converge via repair; strong-model systems resume serving the minority side.
  • Reconcile: for anomalies produced while a weaker model was in effect, reconciliation is an application-level task — the store cannot know what invariant you meant.
  • Verify: assert the invariant you actually care about, continuously, rather than asserting the model. Invariant checks catch model misunderstandings that model documentation does not.
How you would know
  • Which read path served each request — leader, replica, cache — because that is what determines the model in force.
  • The rate at which the system uses a degraded or fallback read path.
  • Continuous invariant checks over the data itself, which is the only end-to-end signal that the model matched the assumption.
  • For multi-key operations, an explicit count of operations that crossed a partition or region boundary, since that is where guarantees end.
When it helps
  • Any design conversation involving replicas, caches, regions or transactions — the vocabulary is the whole tool.
  • Evaluating a managed database, where the documentation's adjective and the theorem's adjective are frequently not the same one.
  • Debugging intermittent data anomalies with a clean error rate, which is the signature of a model mismatch.
When it hurts
  • Single-node systems with no replicas or caches, where the model is trivially strict serializability and the vocabulary adds nothing.
  • Conversations where the precision becomes a way to avoid deciding — the models exist to make a choice possible, not to defer it.
Simpler alternatives

A model is a set of observations you will never make

A consistency model is a set of observations it promises you will never make
Not a strength, not a dial, not a ladder from weak to strong. A list of histories the system says it cannot produce — and a model that forbids nothing has told you nothing.
forbids
0 of 3 observations
scope
Unstated. That is the problem.
what it costs
Unknown, because the phrase names no model and therefore forbids no observation.
This forbids nothing on our list
There is no such model. "Strongly consistent" is a marketing phrase, not a guarantee: it names nothing, so it excludes nothing, so no observation can ever contradict it. The correct response is always the same question — strong in what sense, over what scope? Ask for linearizable, or serializable, or causal, and ask whether it holds per key or across keys.
LinearizableSequentialCausal (+ convergence)Session guaranteesEventual“Strongly consistent”
A read returns a value older than a write that had already completedprotocol✕ neverpermittedpermittedpermittedpermittedpermitted
Two reads in one session go backwards in timesimplified✕ never✕ never✕ never✕ neverpermittedpermitted
A reply is visible before the post it replies tosimplified✕ never✕ never✕ neverpermittedpermittedpermitted
“✕ never” means the model forbids that observation; “permitted” means a conforming system may legally show it to a user
The first observation as a history: C2 sees the write, then C3 — strictly later, no overlap — sees the old valueprotocol
C1 write(1) → ack; invoked at 0, responded at 2; no effect point placedC1write(1)no effect point placed→ ackC2 read → 1; invoked at 3, responded at 4; no effect point placedC2readno effect point placed→ 1C3 read → 0; invoked at 5, responded at 6; no effect point placedC3readno effect point placed→ 0t=0real time →t=6
invocation → response: the op is this whole intervaleffect point — one instant inside the interval
✕ Not linearizable

Search exhausted after 3 states: no placement of effect points inside the operations' intervals produces a legal sequential history that also respects real-time order. The search could never place C3's read: it observed 0 at a point where the register necessarily held 1.

Two things collapse most arguments about consistency. First, the two axes are orthogonal: recency of single operations (linearizability) and isolation of transactions (serializability) are different questions, and a system can be strong on one and weak on the other. Second, scope is part of the guarantee — per-key linearizability is not cross-key linearizability, and a system that gives you the first will happily show you a torn read across two keys. And none of it can be checked by asking a replica how it feels: consistency is a property of histories observed across the whole system, which is why it is verified by an external checker replaying a log, exactly as above.
simplifiedThree observations stand in for the whole space, and the models are compared only on those three. The “linearizable forbids a stale read” cell is not asserted — it is the verdict `linearizabilityCheck` returns on the history shown below.

What people believe, and what is true

Claim

Strong consistency is a consistency model.

Reality

It is a marketing phrase. Linearizability, sequential consistency, serializability and strict serializability are models; each forbids something specific, and they forbid different things.

Claim

Consistency in CAP is the C in ACID.

Reality

They are unrelated. ACID's C is "the transaction preserves application invariants" — a property of your schema and constraints. CAP's C is linearizability. The shared letter is an accident of naming.

Claim

Stronger models are always safer.

Reality

Stronger models are safer per operation and less available during partitions. A system that is unavailable is not producing correct answers either, so the choice is a trade, not an upgrade.

Claim

The consistency model is a property of the database.

Reality

It is a property of the *read path you configured* — leader vs replica vs cache, and the isolation level you asked for. The same database offers several models simultaneously.

Go deeper

Only the levels this lesson can honestly fill — a missing level is a claim nobody had.

Overview

A consistency model says which observations the system will never produce. "Strong consistency" says nothing, because it names no observation.

Practical

For every read path in your system, answer the four questions: which model, which operations, under what failure conditions, over what scope. Then assert the actual invariant continuously, because the documented model and the delivered model diverge under failover.

Advanced

Models are defined by the existence of a witness — a sequential history that is legal for the data type and respects the model's ordering constraint. This is why checking linearizability is expensive (the search is NP-hard in general) and why weaker models are cheap to check as well as to provide. The formal hierarchy is a lattice rather than a line, and the two axes here are its two principal directions. See Linearizability: An Operation Is an Interval, Not a Point and Serializability vs Linearizability: Two Different Properties.

Apply it

Interview questions
  • 💬 A vendor says their database is strongly consistent. What four questions do you ask before believing anything follows from that?
  • 💬 Is the C in CAP the same as the C in ACID? Explain the difference precisely.
  • 💬 Your team reports intermittent data anomalies with a zero error rate. What class of cause does that pattern suggest?