The Pattern
READ:
val = cache.get(key)
if val: return val ← hit (~1ms)
val = db.query(key) ← miss
cache.set(key, val, ttl=300) ← fill for next time
return val
WRITE:
db.update(key, new_val) ← source of truth first
cache.delete(key) ← invalidate, don't update
the APPLICATION owns the logic; the cache is a dumb fast KV.
hence the alias: LAZY LOADING — data loaded into cache
only when first needed.
Why Delete-on-Write (Not Update)
write path alternatives:
UPDATE cache directly:
✗ race: two writers interleave db/cache ops → stale value
cached INDEFINITELY (no TTL to save you mid-window)
✗ cache holds derived shapes sometimes → writer must know them
DELETE + lazy refill:
✓ next read pulls FRESH from db — self-healing
✗ one extra read after each write (usually fine)
✗ tiny window where old value still served pre-delete
delete is simpler AND more correct. default to it.
The Known Race (and why it rarely matters)
interleaving that poisons the cache:
A: read miss → queries db (old value v1)
B: writes db (v2), deletes key
A: sets cache = v1 ← STALE until TTL expiry!
window is milliseconds and needs precise timing;
TTL bounds the damage. high-consistency keys need
versioned values or short TTLs or lock-assisted fills.
know it exists; don't over-engineer for it by default.
Strengths and Costs
| ✓ Wins | ✗ Costs |
|---|---|
| Cache holds only REQUESTED data (no waste) | First read of anything = full latency |
| Cache down = slow, not broken (resilient) | Miss penalty on every cold key |
| Simple; no broker contracts | App code carries the pattern everywhere |
| Works with any storage backend | TTL staleness between refreshes |
The resilience row matters operationally: flush Redis during an incident and the site degrades instead of dying.
When Cache-Aside Is Right
✓ read-heavy entities with tolerant staleness (profiles, catalogs)
✓ irregular access patterns (lazy = only cache what's asked)
✓ teams wanting zero magic — logic visible in code
reconsider when:
- write-heavy (constant invalidation churn)
- strict freshness required (TTL windows unacceptable)
- thundering-herd-prone hot keys (needs coalescing additions)
Interview Framing
This is the expected DEFAULT answer for “how do you cache user profiles?” — name it, sketch both paths, justify delete-over-update with the race argument, cite TTL bounding the known flaw. Contrast one line with read-through (“broker-managed fills”) to show you chose, not defaulted blindly.
Premium Content
Unlock Cache-Aside and all premium lessons with a subscription.
All premium lessons
Ad-free experience
Priority support
From ₹199.99/year — See plans