Consistency Models and User Guarantees
LESSON
Consistency Models and User Guarantees
By the end of this lesson, you will be able to...
translate a user-facing surprise into a specific consistency guarantee.
trace how a minimum-version read prevents a stale replica from breaking "saved."
compare eventual convergence, read-your-writes, monotonic reads, causal consistency, and linearizability.
Idea in one sentence: A consistency model is a promise about what an observer is allowed to see after writes.
Core Insight
Nora opens a food delivery app at work.
Her saved delivery address is:
Office, 10 Market Street
Before ordering dinner, she changes it to:
Home, 42 River Road
The app says:
Address saved.
Then Nora goes to checkout. The checkout page reloads from a nearby replica that has not received the new address yet. It shows the old office address.
The database may be behaving exactly as designed. The replica may be healthy. Replication may catch up two seconds later.
But the product just broke a promise.
After the app told Nora the address was saved, Nora should not immediately see the old address as if the save never happened. The technical question is not "is the database consistent?" That question is too vague. The useful question is:
Which observation must this workflow forbid?
Plain meaning:
A consistency model tells the system which stale or reordered results are allowed, and which ones are forbidden.
In this scenario:
Nora's checkout read must not return an address older than the version she just saved.
Technical name:
This is a consistency guarantee. The specific guarantee Nora needs is read-your-writes.
The Naive Idea: Read From Any Healthy Replica
The address service has one write owner and several read replicas.
Madrid owner:
address/nora version 27 = Office
Dublin replica:
address/nora version 27 = Office
Lisbon replica:
address/nora version 27 = Office
The naive read rule is:
Send each read to the nearest healthy replica.
That rule is attractive. It is fast. It keeps traffic local. It avoids bothering the owner for every read.
Then Nora saves her new address.
Madrid owner:
version 27 -> version 28
address = Home
Dublin replica:
still at version 27 for a short time
If checkout reads from Dublin immediately, it may see version 27. That is a valid local copy, but it is not a valid answer for Nora's checkout after the app said "Address saved."
The missing piece is not another replica. The missing piece is an observation rule.
Check: If Dublin is healthy but still at version 27, should it return the office address to Nora's checkout?
Think first, then reveal.
Answer: No, not if Nora's session has evidence that version 28 was saved. Dublin can wait, route to a fresher replica, or return a retryable response. It should not silently return version 27.
A Worked Trace: Carry The Saved Version
The system can protect Nora by carrying a minimum version through her session.
Starting state:
address/nora:
version 27 = Office
Nora's app:
minimum address version = none
1. The Write Returns Evidence
Nora saves Home.
Nora app -> Madrid owner:
PUT address/nora = Home
Madrid owner:
version 27 -> version 28
starts replication to followers
Madrid owner -> Nora app:
saved_version = 28
The response does not mean every replica has version 28. It means Nora's session now has evidence that version 28 exists and is relevant to her next reads.
The app stores:
minimum address version = 28
2. Checkout Reads With A Requirement
Nora opens checkout.
Nora app -> checkout:
load delivery address
minimum_version = 28
The router sends the read to Dublin because it is nearby.
Dublin replica:
local version = 27
required version = 28
Dublin has several safe choices:
wait until version 28 arrives
route the read to Madrid
ask another replica
return "retry later" instead of old data
It has one unsafe choice:
return version 27 as if it satisfies the read
When Dublin finally applies version 28, it can answer:
Dublin -> Nora app:
version 28 = Home
This is read-your-writes. After Nora's accepted write, Nora's later reads observe that write or a newer one.
3. The Session Must Not Move Backward
Later, Nora edits delivery instructions.
version 29 = Home + "Ring the side bell"
If her app has already seen version 29, a later checkout read should not show version 28 unless the product explicitly says it is showing an old cached view.
seen by Nora: version 29
replica can serve: version 28
allowed silently? no
This is monotonic reads. Once an observer has seen a newer version, later reads in that observation path should not go backward.
So far, the mechanism is simple:
write response carries evidence
later read carries a requirement
replica checks whether its local state satisfies the requirement
The important design choice is the scope. Does the guarantee follow one browser tab, one device, one account, or every service that uses the address? That scope changes the cost.
What The Common Guarantees Forbid
Consistency models are easier to remember as forbidden surprises.
Eventual convergence says replicas that stop receiving new conflicting writes eventually become the same. It does not promise what Nora's next read will show. It is useful as a background property, but it is not enough for the checkout moment.
Read-your-writes forbids this surprise:
"I saved it, then I immediately could not see it."
It usually protects the writer's session, device, account, or token.
Monotonic reads forbids this surprise:
"I saw the new version, then the system showed me an older version."
It protects one observer from moving backward.
Causal consistency forbids this surprise:
"I saw the effect without the cause."
For example, suppose Nora saves the Home address and then adds delivery instructions: "Ring the side bell." Showing the instruction without the Home address can be confusing because the instruction depends on the address. Causal consistency keeps dependent events in an order that makes sense.
Linearizability forbids an even stronger surprise:
"A later operation missed a completed earlier operation."
Once a write completes, every later operation on that object behaves as if it sees one real-time order. This is useful for locks, inventory decrements, unique username claims, credential revocations, and other operations where one official answer matters.
The guarantees are not a single moral ladder from bad to good. They are tools for different promises. A product may use read-your-writes for address editing, causal order for comments, linearizability for a gift-card balance, and eventual convergence for search indexing.
The Data Path Changes With The Promise
The placement lesson told us where state lives and which replicas may answer. Consistency guarantees tell replicas when a local answer is good enough.
For Nora's address, a session token can carry:
address/nora must be >= version 28
The router can send the read to a follower. The follower can answer only if it has applied version 28 or newer. This preserves Nora's guarantee without forcing every address read to go to the owner.
For causal order, writes may carry dependencies:
instruction "Ring the side bell"
depends on address version 28
A replica that has the instruction but not address version 28 should wait, fetch the missing dependency, or hide the instruction until the cause is present.
For linearizability, the path is stricter. The read or write may need the owner, a quorum, a lease, or another coordination path that can defend one real-time order. That costs more latency and can reduce availability during uncertainty.
Check: A user changes their password and receives "Password changed." Which guarantee is usually closer: eventual convergence or linearizability for later login checks?
Think first, then reveal.
Answer: Linearizability, or a similarly strong coordinated rule, is usually closer. A later login check should not accept the old password just because one authentication replica has not caught up.
Worked Classification
Use the same question for every workflow:
What observation would make the product feel wrong or unsafe?
For a delivery address update, the forbidden observation is narrow. Nora saves Home, then Nora's checkout sees Office. The smallest useful guarantee is often read-your-writes for Nora's session or account. The system can still allow another user, support tool, or analytics job to see a slightly old address if that path does not make a delivery decision.
For a message reply, the forbidden observation is dependency order. A reply that says "yes, use the side door" makes little sense if the original message about the Home address is missing. The useful guarantee is causal consistency for the conversation: show dependent messages only after the messages they depend on.
For a password change, the forbidden observation is broader. After the change is confirmed, a later login check should not accept the old password from any authentication path. A session token on Nora's phone is too narrow. The system needs a stronger authority path, often linearizable or close to it for the credential state.
The method is the same each time. Name the surprise, name the observer, then choose the cheapest guarantee that forbids that surprise.
Trade-offs And Limits
The trade-off is that stronger guarantees prevent specific user-visible surprises, but they spend something.
They may spend:
- routing flexibility;
- session metadata;
- dependency metadata;
- waiting for a replica to catch up;
- coordination with an owner or quorum;
- availability when the needed evidence cannot be reached.
Weaker guarantees can make ordinary reads fast and resilient. They are safe only when the product names the stale behavior honestly and has a repair story. Search results can be a little stale. A "recent activity" widget can lag. A delivery address shown after "Address saved" has a stricter expectation.
The limit is scope. A session token can protect Nora's current checkout, but it may not protect a background fraud check, a restaurant tablet, or a courier dispatch service unless the evidence travels to those paths too.
Useful signals include:
- replica lag for keys needed by recent writes;
- reads delayed or rerouted because a minimum version was not available;
- observed version regressions within a session;
- causal dependency wait time and buffered dependent events;
- stale credential or policy decisions after a confirmed update; and
- user reports that "saved" data disappeared.
If these signals rise, the problem may not be storage durability. It may be that response wording and read guarantees do not match.
Common Confusions
Confusion: Strong consistency is always better
Why it is tempting:
"Strong" sounds safe and professional.
Better model:
Stronger guarantees protect stronger promises, but they cost latency, coordination, and sometimes availability. Use them where the forbidden surprise is expensive.
Confusion: Eventual convergence defines the next read
Why it is tempting:
If replicas eventually become the same, it feels like the system is basically safe.
Better model:
Eventual convergence says what happens later if updates stop. It does not say what Nora's checkout may read immediately after "Address saved."
Confusion: Read-your-writes means everyone sees my write
Why it is tempting:
The phrase sounds global.
Better model:
Read-your-writes usually protects the writer or a scoped observation path. Other users may still see an older value unless the product promises more.
Practice
Pick one workflow:
delivery address update
shopping cart update
password change
message reply
bank transfer
dashboard metric
notification read state
Fill in:
state and key:
write:
later read or decision:
forbidden stale or reordered observation:
scope of the promise:
smallest suitable guarantee:
evidence the system must carry:
what a stale replica should do:
cost of the guarantee:
signal that would reveal a violation:
Model answer for message reply:
state and key:
conversation/launch
write:
message 10: "Deployment failed"
later read or decision:
message 11: "I am rolling back" replies to message 10
forbidden observation:
seeing the reply without the message it depends on
scope:
everyone reading that conversation
smallest suitable guarantee:
causal consistency for replies and their parent messages
evidence:
reply carries dependency on message 10
stale replica action:
fetch message 10, wait, or withhold the reply
cost:
dependency metadata and possible waiting
signal:
buffered replies waiting for missing parent messages
Resources
- [ARTICLE] Jepsen: Consistency Models - Focus: Plain-language definitions and examples for observation guarantees.
- [PAPER] Linearizability: A Correctness Condition for Concurrent Objects - Focus: The original real-time ordering guarantee for concurrent operations.
- [BOOK] Designing Data-Intensive Applications - Focus: Replication lag, read-after-write behavior, causal dependencies, and stronger consistency costs.
Key Takeaways
- A consistency model is an observation promise, not a generic label for a whole database.
- Start by naming the stale or reordered observation the product must forbid.
- Read-your-writes, monotonic reads, causal consistency, and linearizability protect different surprises.
- A minimum-version read can let nearby replicas serve safely when they have caught up.
- Stronger guarantees cost metadata, routing constraints, waiting, coordination, or availability.