Consistency models
Exact words for how out of date a read is allowed to be.
What problem does a stronger consistency model solve?
Once data lives on more than one machine, "is this current?" stops having one answer. Consistency models give you precise words for how old a read may be, so you can choose per feature instead of waving your hands.
This is where interviews separate people. "It is eventually consistent" is a phrase. "A user sees their own comment immediately, and sees other people's within about two seconds" is a design.
What a stronger consistency model costs you
Every concept in here states a cost. A technique with no price is a technique you have not understood yet — and naming the cost out loud is most of what separates a senior answer from a junior one.
When to reach for a stronger consistency model, and when not to
Use it when
- Strong: money, stock, seats, unique usernames, permission checks. Anything where being wrong cannot be undone.
- Read-your-own-writes: anywhere a user edits something and then immediately looks at it. That is most user-facing writes.
- Eventual: counts, feeds, search results, analytics, presence. Anything a person cannot tell is two seconds old.
Do not, when
- Do not use strong consistency by default because it feels safer. You are paying on every read for a promise most of your features do not need.
- Do not use eventual consistency for a decision the user cannot undo.
How a stronger consistency model actually works
Strong (linearizable): once a write is confirmed, every later read anywhere returns it. The system behaves like a single machine. It costs a majority round trip on writes, and often on reads too, and it goes unavailable on the smaller side of a network split.
Eventual: if writes stop, all copies end up the same. It promises nothing about when. It also allows a read to go backwards in time. You refresh and see an older value than the one you just saw. That is allowed, and it surprises people.
Read-your-own-writes: you always see your own changes, and other people's may lag behind. This is the sweet spot for user-facing products, and it is far cheaper than strong consistency, because you only have to route one user's reads carefully instead of making the whole system agree. You get it by pinning a user to the leader briefly after a write, or by tracking the write position and reading from a replica that has caught up to it.
Monotonic reads: you never see time run backwards. You get it by keeping a user on one replica, so they at least see one steady version of history. It is cheap, and it removes a whole class of "the page keeps flipping between two values" complaints.
Causal consistency: things that depend on each other show up in the right order. Nobody sees the reply before the comment. It is weaker than strong and much cheaper, and it is often what people mean when they say a system "feels" correct.
The practical move in an interview is to go feature by feature. "The like count is eventual, a second of lag is invisible. The comment you just posted is read-your-own-writes, or you will think it failed. The seat you just booked is strong, because two people cannot have it."
- Saying "eventually consistent" as if it were a design. How long is eventual, and what does the user see in the meantime?
- Applying one model to the whole system instead of per feature.
- Forgetting that eventual consistency lets reads go backwards.
The a stronger consistency model follow-up an interviewer will ask
"Two users click at the same millisecond. What happens?"
It depends on whether the thing they are clicking is contested. If it is a like button, both writes land, the count settles, and nobody cares. I would use an eventual counter and not spend a transaction on it. If it is the last seat, one must win, and the way to guarantee that is to make the decision at a single point. That means a conditional update in the database that only succeeds if the seat is still free, or a unique constraint on (event, seat) so the second insert simply fails. I am not suggesting we check and then write in application code, because that is the race itself. The loser gets a clear message and a suggested alternative. Cost: that write path is now strongly consistent, so it is slower, and it goes unavailable if the owning partition is unreachable. I accept that, because selling one seat twice is worse than an error message.
Your turn
A user posts a comment and refreshes, and it is not there. Which consistency guarantee was missing, and what is the cheapest way to add it?
Four features, four different answers
You are designing a marketplace. It has a product page with a view count, seller inventory, buyer reviews with replies, and a checkout. A junior engineer proposes making the whole system strongly consistent "to be safe". Your job is to price that proposal and then decide feature by feature.
- 1Price the blanket proposal
Strong consistency everywhere means a majority round trip on every read and write. The product page alone does about eight reads, so at about 2 ms of coordination each, run one after another, that is 16 ms added to a page nobody needed protected. If replicas ever span regions it becomes 640 ms and the product is unusable. It also means the page goes down entirely on the minority side of a network split, including the parts that could have been served perfectly well. The proposal was not free, and for most of the page it protected nothing.
- 2View count: eventual
Nobody can tell a view count is two seconds old, and nobody makes a decision from it. Eventual consistency, sharded counters, cached total refreshed every few seconds. The cost is that the number can briefly go backwards on refresh, which I remove cheaply by pinning a user to one replica: monotonic reads for almost nothing.
- 3Seller inventory: two answers, not one
This is the interesting one, because the same data needs different guarantees in different places. The "3 left" badge on the browse page can be eventually consistent and slightly wrong. The worst case is mild disappointment. The stock check inside checkout must be strongly consistent, and specifically must be a conditional update inside the transaction that reserves the item, not a read followed by a decision. Same field, two guarantees, chosen by what being wrong costs at that moment.
- 4Reviews and replies: causal
A reply appearing above the review it answers is not slow, it is nonsense, and users report it as a bug. But full strong consistency is not needed. A review taking two seconds to appear is fine; what matters is it appears in the right order relative to its parent. So route all writes for one review thread through one partition, and ordering comes free, with no cross-partition coordination.
- 5The seller's own listing: read-your-own-writes
A seller edits a price and reloads. If a lagging replica serves that read, they see the old price, assume it failed, and edit again, which creates a support ticket and possibly a duplicate. Pin their reads to the leader for ten seconds after any write. This is the cheapest fix on the page, and it prevents the complaint sellers are most likely to raise.
- 6Say the whole thing in one breath
"Counts eventual with monotonic reads. Browse-page stock eventual, checkout stock strongly consistent via a conditional update. Review threads causally ordered by partitioning on thread id. A seller's own edits read-your-own-writes for ten seconds. Four features, four prices, each chosen by what being wrong costs."
Learn it from the source
This page gets you interview-ready. These take you to where the idea is actually specified or measured — read them when you want the real depth.
- Jepsen — Consistency models ↗A map of the guarantees, with the relationships between them drawn out.
- Jepsen — Database analyses ↗Real databases tested against their own marketing. Sobering and very specific.