System designCore9 min
Consistency models
Copies of your data lag behind each other. A consistency model is the exact promise about what a read may show while they do. Learn the ladder from linearizable to eventual, and which rung each feature needs.
1 · The word
Three meanings of "consistency", and one false friend
Ask three engineers what "consistent" means and you get three correct answers. In ACID, the C means every transaction leaves the database obeying its rules: no negative balance, no duplicate username. In the CAP theorem, C means linearizability, defined below. Consistent hashing is about which server stores a key and has nothing to do with either. This article is about a third meaning, replica consistency: what the copies of one piece of data may show a reader.
Term | What it promises | Where it lives |
|---|---|---|
ACID consistency | Every transaction keeps the invariants | Transactions & isolation levels |
CAP consistency | Linearizability, the strongest model here | CAP & PACELC |
Replica consistency | What each copy may show a reader | This article |
Consistent hashing | Which server owns a key; unrelated | Consistent hashing |
Why is there a question at all? Because the shop this article follows keeps one copy of its database in London and another in New York, and every change made in one city takes time to reach the other. During that gap the copies disagree, and whoever reads the wrong one sees the past.
Two copies, one lagging. Every model below is a rule about what the New York reader may see while the copy is on its way. How the copy travels is Database replication; here only the promise matters.
2 · The strongest
Linearizable: as if there were one copy
Linearizable is the promise that the system behaves as if there were a single copy, and every operation took effect at one instant between the moment it started and the moment it returned. The instant is what matters: once a write has returned, every read that starts afterward, from any client in any city, must see it. This is what people usually mean by strong consistency, and it is the C in CAP.
The laptop already saw order #881, so the phone's later read must see it too. A read that returns the new value, followed by one that returns the old, is exactly what linearizability forbids. The lagging New York copy caused it.
The real-time requirement is the expensive part. The replica that answers must know it holds the latest write, so either every read goes to one leader or the replicas coordinate before answering. Both cost round trips, and neither works while the cities cannot talk. That bill is CAP & PACELC.
Guarantee | About | Respects real time? |
|---|---|---|
Linearizable | One operation on one object: a read, a write, a compare-and-set | Yes: what finished before another started comes first |
Serializable | Whole transactions over many objects, as if run one after another | No: any order will do, even one that puts an older commit after a newer one |
Strict serializable | Both at once | Yes |
Databases advertise serializable as their strongest isolation level, and readers assume it implies freshness. It does not. Serializability only says transactions appear to run one at a time in some order, and that order may place a transaction that committed a minute ago after yours. Isolation levels have their own page (Transactions & isolation levels). The row to remember: serializable plus linearizable is strict serializable.
3 · Relaxing it
Sequential drops the clock, causal drops the shared order
Each step down removes a promise and buys latency and availability. Everything at or above sequential must stop answering during a partition; causal and the session guarantees can keep answering if each client sticks to one replica.
Sequential consistency keeps one half of linearizability and drops the other. Everyone still sees the same single order of operations, and each client's own operations keep their program order, but the shared order need not match the clock. A review posted in London at 12:00:00 and one posted in New York at 12:00:05 may be shown to everyone, in both cities, with New York's first. Nobody can tell, unless they compare wristwatches.
Causal consistency drops the shared order too and keeps only the order that matters: if one operation could have influenced another, everyone sees them in that order. It is the happens-before relation from Time, clocks & ordering, turned into a promise. A seller reads a question on a product page and writes the answer, so the answer depends on the question: no copy may show the answer without it. Two unrelated reviews, though, may appear in different orders in the two cities. That is what causal gives up.
Causal is a special rung. It has been proved that a strengthening of it, real-time causal, is the strongest model a system can offer while staying available to every client and still converging. A common practical version is causal+: causal order plus a rule that makes conflicting writes converge. Anything stronger means coordinating across the ocean.
4 · The weakest
Eventual consistency promises convergence and nothing else
Eventual consistency is the weakest promise still worth a name. The definition: if no new updates are made to the object, eventually all accesses will return the last updated value. Read it twice. It promises convergence and only convergence: no bound on how long, and nothing about what a read returns before then. Put bluntly, it only says something good will eventually happen. It never says something bad will not.
You might expect | What eventual consistency actually says |
|---|---|
Reads show recent data | Any value ever written may come back until the copies converge |
Reads never go backwards | A read may show the new value, then the old one |
Convergence within seconds | No bound at all; "eventually" is the whole promise |
Two concurrent writes both survive | Only if you choose a merge rule; last-writer-wins silently drops one |
In practice the gap is usually short. Copies in one data center typically catch up within milliseconds, and copies in another region within about a second. Usually short is not always short: under load or during a partition the window stretches, and the promise gives you no number to plan around. Why timestamps are a poor merge rule is Time, clocks & ordering.
5 · The practical middle
Session guarantees fix the bugs users actually notice
Most users never notice a stale copy. They notice when the system contradicts them. Four promises stop this. They are the session guarantees: promises about one client's own sequence of reads and writes rather than about the system as a whole.
Read-your-writes rules this out: after your own write, your own reads must reflect it. Everyone else may still see Elm Rd for a moment; the promise is scoped to you.
Guarantee | Promise | Bug it prevents | Answers in a partition? |
|---|---|---|---|
Read-your-writes | Your reads reflect your earlier writes | You save a change; the page shows the old one | Yes, if you stick to one replica |
Monotonic reads | Your reads never go back in time | An order appears, vanishes, then is back | Yes |
Monotonic writes | Your writes apply everywhere in your order | Edit 2 lands before edit 1 on a copy, which keeps edit 1 | Yes |
Writes-follow-reads | A write is ordered after the reads it depended on | Your reply appears on a copy without the message it answers | Yes |
All four are cheap. Pinning a session to one replica gives read-your-writes and monotonic reads at once; a version number carried by the client, which a replica waits to reach, covers the rest. Together they amount to causal consistency for one client, which is why they sit just below it on the ladder.
6 · Choosing
Pick a model per feature, not per system
Which model? Wrong question, if asked once per system. Ask it per feature. The shop's gift-card balance, stock counts, wishlist counter, your profile and the sign-up form live in the same two copies and need different answers.
Feature | Model | Why |
|---|---|---|
Gift-card balance; the last unit in stock | Linearizable | Two cities each selling the last unit is money lost; the check needs the one true copy |
Username uniqueness at sign-up | Linearizable | "Is it taken?" asked of a stale copy says no twice; a lagging copy cannot enforce an invariant |
Your own profile edit | Read-your-writes + monotonic reads | You must see your change at once; others can wait a second |
Wishlist count on a product | Eventual | Off by one for 200 ms harms nobody, and every page view reads it |
Shopping cart | Causal, or eventual with a merge rule | Must stay writable through anything; two versions can be merged |
The price rises with each rung up. A linearizable operation waits for a round trip between the cities, about 70 ms between London and New York, and must refuse to answer while they cannot talk. An eventual one answers from the local copy and keeps answering through the outage. How that trade is forced, and what it costs when nothing is broken, is CAP & PACELC.
Check yourself
4 questions
Takeaways
Remember this
- "Consistency" means invariants in ACID, linearizability in CAP, and what copies may show in replication; consistent hashing is unrelated.
- Linearizable: as if one copy, each operation at one instant between start and end. Serializable orders transactions and does not imply freshness.
- Sequential drops real time, causal drops the shared order, eventual promises only that copies converge once writes stop.
- Session guarantees (read-your-writes, monotonic reads, monotonic writes, writes-follow-reads) are cheap and stop the bugs users notice.
- Choose per feature: balances and uniqueness need linearizability, counters can be eventual, and every rung up costs a round trip and availability.