Why this subtopic exists
Redis internals and CDN edge caching live in sibling subtopics — but interviewers probe how the application uses a cache relative to the database: read path, write path, invalidation, and what happens when the cache and DB disagree. This is a default follow-up in almost every system design round.
Networking owns HTTP/CDN semantics. This subtopic owns application-layer cache patterns and consistency trade-offs. Pair with the KV/Redis subtopic next for data-structure and persistence depth.
The four core patterns
| Pattern | Read path | Write path | Consistency risk |
|---|---|---|---|
| Cache-aside (lazy loading) | App reads cache → miss → read DB → populate cache | App writes DB → invalidate or update cache | Stale reads if invalidation missed |
| Read-through | App reads cache; cache loads from DB on miss | App writes DB → cache must be updated separately | Cache library must handle load failures |
| Write-through | App reads cache (always fresh after write) | App writes cache → cache writes DB synchronously | Higher write latency; cache is on critical path |
| Write-behind (write-back) | App reads cache | App writes cache → async flush to DB | Data loss if cache dies before flush; ordering bugs |
Cache-aside is the default in backend interviews — simplest mental model, app owns orchestration.
read(key):
v = cache.get(key)
if v is miss: v = db.get(key); cache.set(key, v, ttl)
return v
write(key, value):
db.update(key, value)
cache.delete(key) // or cache.set(key, value)Write-through when reads must never see pre-write state and you accept write latency. Write-behind only when you can tolerate loss/reordering (metrics buffers, analytics) — say that explicitly in interviews.
Where each tier lives
| Tier | Typical tech | Latency | What to cache |
|---|---|---|---|
| Process-local | Caffeine, Guava | μs | Hot keys, config, denormalized fragments |
| Distributed | Redis, Memcached | sub-ms–ms | Sessions, rate limits, shared denormalized views |
| CDN / edge | Cloudflare, Fastly | ms | Static assets, cacheable API GETs |
Multi-tier: local → Redis → DB. Invalidate top-down on write or use short local TTL + longer Redis TTL. Staff trap: two locals with no coordination → inconsistent across pods until TTL expires.
Invalidation strategies
| Strategy | When | Pitfall |
|---|---|---|
| TTL only | Staleness OK for N seconds | User sees old data until expiry |
| Delete on write | Stronger freshness | Miss storm if many keys per entity |
| Version / etag key | cache:user:123:v{ver} | Must bump version atomically with DB write |
| Pub/sub fan-out | Many app instances, local caches | Missed message → stale until TTL |
Interview thread: "User updates profile photo — what invalidates?" — user profile key, feed entries embedding avatar URL, CDN object, search index (async). Name all consumers, not just Redis.
Cache stampede (thundering herd)
Many clients miss the same hot key simultaneously → all hit DB.
Mitigations (name at least two):
- Request coalescing / singleflight — one loader per key; others wait on the in-flight fetch
- Probabilistic early expiration — refresh before hard TTL under load
- Stale-while-revalidate — serve stale while one worker refreshes (pairs with CDN
stale-while-revalidate) - Mutex per key — simple but watch lock contention on mega-hot keys
Cross-reference: Networking → CDN for edge stampede; Concurrency for lock/semaphore patterns behind singleflight.
Consistency questions interviewers ask
- Read-your-writes — route same user to same replica, or invalidate cache on write, or sticky session + short TTL
- Thundering herd after deploy — cold cache; warm gradually or pre-populate
- Cache penetration — queries for non-existent keys; use short TTL sentinel or Bloom filter
- Cache avalanche — many keys expire together; jitter TTLs
When not to cache
- Strong linearizability required on every read (financial balances without careful design)
- Low read:write ratio on mutable data
- Payload larger than network to DB (sometimes)
- Personalized PII where edge caching is forbidden (
Cache-Control: private,no-store)
Senior signal
Don't say "add Redis." Say: cache-aside on product metadata with 5-minute TTL, delete-on-write for inventory counts, singleflight on hot product pages, CDN for static assets with versioned URLs.
Link forward
KV, Redis, DynamoDB subtopic — Redis data structures, eviction, RDB/AOF. System Design Use Cases — distributed cache case for full timed rehearsal.
Further Reading
Hands-On Tasks (Optional)
Low-setup exercises — schema drills, paper walkthroughs, or optional local installs. No autograding; the goal is interview fluency on how data is stored.
- Profile update invalidation15m
User updates display name and avatar. List every cache layer you'd invalidate or version (local, Redis, CDN, search index, feed materialization) and one failure mode if you miss a layer.