Consistency
"What happens when replicas/caches disagree?"
Applies To
caches, read replicas, sessions
Why It Happens
A first-principles walkthrough of why replicas and caches necessarily disagree for a window. What read-your-writes, linearizable reads, and replication lag cost in latency, and how write-through invalidation and version checks close the gap between the primary and what the reader sees.
How It Works Underneath
Consistency is the question “which replica did you ask?” The primary has the new row, the read replica is 200ms behind, the cache still holds the old JSON. A user revokes a session, the primary marks it revoked, but the cache still returns “valid” for the next 5 seconds and the revoked token is accepted. The machinery is write-through: in the same transaction that marks revoked, delete the cache key, or version-check on read and treat a cache hit with stale version as a miss.
Cataloged Failure Modes
stale_readrevoked_session_still_valid
Code Comparison
# NAIVE: Revoking token in DB without cache invalidation
async def revoke(session_id: str):
await db.execute("UPDATE sessions SET revoked = TRUE WHERE id = %s", session_id)
# IMPROVED: Write-through cache invalidation
async def revoke(session_id: str):
async with db.transaction():
await db.execute("UPDATE sessions SET revoked = TRUE WHERE id = %s", session_id)
await redis.delete(f"session:{session_id}")