The Guarantee, Precisely Defined
READ-AFTER-WRITE (session consistency):
a user ALWAYS sees their own completed writes,
regardless of which replica serves their reads.
scope matters:
- PER USER/SESSION: Sarah sees Sarah's edit immediately
others may lag (that's fine!)
NOT global linearizability — that costs far more
and users can't tell the difference.
Why It Breaks by Default
write → primary ──async──► replicas (800ms behind)
read → LB picks any replica → STALE for that user
broken flows in every naive deployment:
- rename profile → refresh → old name
- post comment → it's not in the list
- upload avatar → old face stares back
Implementation 1: Sticky Window
after a WRITE, mark the session:
redis.set("raw:u912", now(), ex=10) # 10s window
on READ routing:
if session_wrote_recently(user):
route to PRIMARY
else:
route to any replica
properties: trivial to build; slightly over-routes
(primary load rises with write-active users); window
must exceed worst-case replication lag.
THE pragmatic default.
Implementation 2: Version/LSN Tokens
writes return a POSITION token:
POST /profile → 200 { ..., "_rv": "wal:8f3a92" }
client echoes token on subsequent reads:
GET /profile?_rv=wal:8f3a92
router logic:
if replica.replay_lsn >= _rv: serve from replica ✓
else: wait briefly / fall to primary ✓
precise: primary touched ONLY until replica catches up,
then traffic returns. more machinery; best at scale.
managed equivalents exist (DynamoDB consistent-read tokens).
Implementation 3: Affinity Routing
route each USER consistently:
hash(user_id) → replica group
their writes' replicas are likely caught up with them;
plus sticky-window for safety right after writes.
bonus: per-user cache affinity comes free
(same replica = warm cache for that user's slice).
Choosing Per Endpoint Class
| Flow | Mechanism |
|---|---|
| Profile/settings pages | Sticky window |
| Order confirmation | LSN token (correctness matters) |
| Feeds/browsing | Nothing needed (staleness fine) |
| Auth-critical checks | Primary always |
resist applying mechanisms globally:
blanket primary-routing after ANY write recreates
single-node read scaling. scope tightly, measure, relax.
Interview Framing
“User complains their edits don’t appear” scored diagnosis: replication-lag + replica-routing as root cause, fix menu presented with tradeoffs (sticky=cheap, tokens=precise), scoped-per-endpoint-class table. The precision of the guarantee definition (“session-scoped, not global”) is itself a seniority marker — say it explicitly.
Premium Content
Unlock Read-After-Write Consistency and all premium lessons with a subscription.
All premium lessons
Ad-free experience
Priority support
From ₹199.99/year — See plans