Three Tests Before Any Cache
1. READ-HEAVY? reads ≫ writes (10:1+ is comfortable territory)
2. STALENESS-TOLERANT? may the copy lag the source by seconds/minutes?
3. HOT ENOUGH? enough repeat reads to earn back the complexity?
pass all three → cache.
fail #1 → you'd invalidate constantly (cache churning on writes).
fail #2 → serve from source; consistency is the product (balances, inventory at checkout).
fail #3 → low hit rate pays memory cost for nothing.
The Decision Table
| Data | Read/write | Staleness OK? | Verdict |
|---|---|---|---|
| Product pages | Very read-heavy | Minutes fine | Cache aggressively |
| User profiles | Read-heavy | Seconds fine | Cache |
| Trip history feed | Read-heavy | Seconds fine | Cache with short TTL |
| Account balance | Mixed | NO at decision time | Don’t cache the answer |
| Seat inventory | Write-heavy | No | Source-of-truth only |
| Auth session tokens | Extreme reads | Short TTL fine | Cache (with revocation story) |
| Search results q=X | Read-heavy | Seconds fine | Cache popular queries |
The Classic Anti-Patterns
✗ CACHING WRITE-HEAVY DATA
every write invalidates; hit rate collapses; you pay
cache costs AND source costs simultaneously
✗ CACHING WHAT'S ALREADY FAST
indexing a small table to 2ms then caching to 1ms:
saved 1ms, added staleness bugs + a Redis dependency
✗ CACHING PER-REQUEST UNIQUE DATA
?timestamp=now or random nonces as keys → 100% miss rate,
pure memory heater
✗ CACHING WITHOUT AN EXPIRY STORY
"we'll invalidate manually" → stale data incidents forever
Compute Caching: The Same Tests
expensive COMPUTATIONS cache too (memoization at scale):
fare estimates same route+time → same price band ✓ cache
auth decisions same token within seconds ✓ cache
rendered reports same params, slow query ✓ cache
real-time pricing changes constantly ✗ don't
key discipline: canonicalize inputs first
("NYC→LAX" vs "nyc → lax" must map to ONE key,
else fragmentation kills your hit rate)
Sizing the Decision With Numbers
before building, estimate the payoff:
endpoint: GET /driver/:id
traffic: 20k rps
db latency: 45ms p99
expected hits: 96% (drivers queried repeatedly during trips)
cache cost: ~2GB redis, TTL 60s, invalidation on profile update
verdict math: saves ~18k rps × 45ms of db time.
that's a whole replica tier avoided → build it.
counter-example:
admin export endpoint: 3 rps, cached copies unused (params vary)
→ skip. even free caches have integration cost.
Revisit When Things Change
caching decisions have shelf life:
- write ratio grows → revisit invalidation strategy
- personalization increases → key cardinality explodes → hit rate dies
- consistency requirements tighten (compliance) → un-cache
review cache inventory quarterly like any architecture asset
Interview Framing
“What would you cache?” scored answers run the three tests OUT LOUD per candidate item, reject something credibly (“payment authorization: no cache, correctness over latency”), and quantify one positive case with hit-rate math. Knowing what NOT to cache is the stronger signal than listing everything you would.
Premium Content
Unlock When to Cache and all premium lessons with a subscription.
All premium lessons
Ad-free experience
Priority support
From ₹199.99/year — See plans