What a reader sees after a write
Consistency describes what a reader sees after somebody writes. You change your address in an app, reload the page and see the old one. That is a consistency problem.
It matters because copies of data are never updated at the same instant. A system must choose between answering fast and answering with the newest data.
By the end of this lesson
Note
I can say what a reader sees after a write, and the trade-off.
Key words
| Word | What it means | Example |
|---|---|---|
| Consistency | what readers see after a write | |
| Strong consistency | every read sees the latest write | |
| Eventual consistency | copies agree after a short time | |
| Stale read | a read that returns an old value | |
| Trade-off | gaining one thing by giving up another | |
| Replication delay | the time a write takes to reach a copy | 50 ms |
The cells students fill in are left blank in this preview.
A write reaches each copy at different times
When you write to the primary, the log travels to each replica. That takes time, and the time differs from copy to copy.
In between, the copies disagree. A read at the primary sees the new value. A read at a replica that has not yet heard sees the old one. That old value is a stale read.
Worked example: one write, three reads
| Time | What happens | Value the reader sees |
|---|---|---|
| 10 ms | Write stock = 11 at the primary | Primary: 11 |
| 20 ms | Read at the replica, which has not heard | Replica: 12 (stale) |
| 60 ms | The log reaches the replica | Replica: 11 |
| 100 ms | Read at the replica again | Replica: 11 |
The cells students fill in are left blank in this preview.
Reads before and after the log arrives
# A write at time 10 reaches the primary at once and a replica 50 ms later.
write_time = 10
delay = 50
for read_time in [20, 59, 60, 100]:
if read_time >= write_time + delay:
print("read at", read_time, "ms: new value")
else:
print("read at", read_time, "ms: old value")
# Change delay to 5 and run again.
Strong consistency waits, eventual consistency answers now
With strong consistency every read sees the latest write. The system waits until the copies agree, or reads only from the primary. Answers are right and slower.
With eventual consistency a read is answered by the nearest copy, even if it is behind. If writes stop, all copies agree after a short time. Answers are fast and may be stale.
Make a tiny client called v
v() ( printf '%s\r\n' "$*" | nc -w 1 valkey 6379 )Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Write a stock level
v SET stock:lamp 12Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Read it straight back
v GET stock:lampShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Wait up to 100 ms for a replica
v WAIT 1 100Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Two ways to answer the same read
# The same write, read from two copies at time 30.
primary = "stock 11"
replica = "stock 12" # the replica has not yet heard about the sale
print("Strong: ask the primary ->", primary)
print("Eventual: ask the nearest copy ->", replica)
# After a short wait the replica is updated too.
replica = primary
print("A moment later the copies agree:", replica == primary)
Which kind suits which job
| Job | Stale read costs | Better choice |
|---|---|---|
| Bank balance before a payment | A wrong payment | Strong |
| Last item in stock | Selling it twice | Strong |
| Number of likes on a post | Nothing much | Eventual |
| A news feed | A post shows a moment late | Eventual |
The cells students fill in are left blank in this preview.
A common mistake
Warning
Many people think eventual consistency means data can be wrong for ever. It does not. Once writes stop, every copy ends with the same value, usually within moments. The risk is a stale read in between, not a lost write.
A user should see their own change
Even with eventual consistency, one rule feels important. After you save something, you expect to see it. This is called reading your own writes.
A simple fix: for a short time after a user writes, send their reads to the primary. Everyone else can still read from the nearest copy.