Search Tech Journey

Find topics, journeys and posts

back to blog
system designadvanced 12m2026-06-24

Day 26 — Caching Strategies — CDN, Application Cache, Cache-Aside, Read-Through, Write-Through

Caching is the single biggest lever for latency and cost. Cache invalidation is one of two hard problems in CS. Knowing the standard patterns + their failure mo…

Caches are amplifiers — they multiply throughput, reduce cost, and shave latency. They also amplify bugs (staleness, inconsistency, herd effects). Picking the pattern that matches the consistency need is the senior skill.

🧠 Concept

Why it matters & the mental model.

1. The cache hierarchy

Each layer has its own TTL and invalidation story. The closer to the user, the cheaper and the staler.

2. Cache-aside (lazy loading)

  • Read: try cache; on miss, read DB, write to cache, return.
  • Write: update DB, invalidate (or update) cache.
  • Pros: simple, cache only what's read.
  • Cons: stale window after writes; cold-start every cache miss hits DB.

3. Read-through

  • Cache is a transparent wrapper over DB; on miss it loads behind the scenes.
  • Same characteristics as cache-aside but encapsulated.
  • Examples: Spring @Cacheable, Django's cache_page.

4. Write-through

  • Write goes to cache + DB synchronously.
  • Pros: cache always fresh.
  • Cons: writes pay both latencies; cache holds data that may never be read (wastes memory).

🛠 Deep Dive

Internals, code, architecture.

5. Write-behind (write-back)

  • Write to cache; DB updated asynchronously.
  • Pros: fastest writes.
  • Cons: data loss window if cache dies before flush; ordering issues.
  • Use only where loss tolerance is explicit (counters, analytics).

6. Cache-aside + invalidation: getting it right

Three patterns:

  • TTL-only: write to DB, let cache expire. Simple, bounded staleness.
  • DEL on write: write to DB, DEL the cache key. Next read populates fresh.
  • Update on write: write to DB, SET cache directly. Fastest reads, but reasoning about race conditions is harder.

The race: two writers update DB then both write cache → last writer wins; with TTL-only or DEL, you avoid this class of bug.

7. Cache stampede / thundering herd

A hot key expires; thousands of requests miss simultaneously → all hit DB → DB falls over. Fixes:

  • Probabilistic early expiration: refresh before TTL with probability rising near expiry.
  • Request coalescing / singleflight: only one request rebuilds; others wait and share the result.
  • Soft TTL + background refresh: serve stale-but-revalidate, refresh async.

8. Hot key problem

Single key serves 90% of traffic (a celebrity post). Mitigations:

  • Client-side cache with TTL + invalidation messages (Redis tracking).
  • Replicate the key to N shards, randomise read path.
  • CDN at the edge for read-mostly data with HTTP Cache-Control headers.

🚀 In Practice

Trade-offs, exercises, what to ship today.

9. Eviction policies

  • LRU (Least Recently Used): default.
  • LFU (Least Frequently Used): better for stable distributions, worse on bursts.
  • TinyLFU + W-TinyLFU (Caffeine): admission control prevents pollution from one-off scans.
  • FIFO: ring buffer; cheap; surprisingly good in some workloads (FIFO Queue research, 2023).

10. Negative caching

Cache "not found" too — otherwise every miss for a non-existent key hammers the DB. TTL shorter than positive cache.

11. CDN-specific

  • Cache-Control: public, max-age=3600, s-maxage=86400, stale-while-revalidate=300.
  • Vary header for content negotiation (accept-language, user-agent).
  • Cache keys: URL + selected headers; keep keys stable to avoid fragmenting.
  • Purges: instant (slow, costly) vs versioned URLs (fast: change ?v=2).

12. What to take away

"How do you cache X?" Strong answers: pattern (cache-aside / read-through), TTL strategy, invalidation, stampede mitigation, one hot-key story. Bonus: name negative caching and edge CDN config.

Key points

    Resources

    Practice Problem: LFU Cache (Hard)