Sign in
TodayMapLearnPracticeReview
Library
18 MINcoreCachingNot started

Caching Strategies

Caching stores frequently accessed data in faster storage. The strategy you choose — cache-aside, write-through, write-behind, or refresh-ahead — determines when data is written to the cache, how stale it can be, and what happens during failures. Choosing the wrong strategy causes stale data, cache stampedes, or data loss.

Why this matters

Caching is the single most impactful performance optimization in most systems. A well-placed cache can reduce latency by 100x and reduce database load by 90%. But a poorly chosen caching strategy causes stale data, race conditions, and cache stampedes that take down the database. Understanding the four strategies — and when to use each — is a core system design skill.

Prerequisites
  • Latency vs Throughput
Related
  • Cache Aside (Lazy Loading)
  • Write Through
  • Write Behind
  • Refresh Ahead
Used in
  • Application Caching
  • Cache Aside (Lazy Loading)
  • CDN Caching
  • Client Caching
  • Database Caching
  • Web Server Caching
Lesson

How it works

A cache is a faster, smaller storage layer that sits between the application and the slower, larger source of truth (usually a database). The application checks the cache first; on a hit, it returns the cached value (fast). On a miss, it fetches from the database (slow) and writes the result to the cache for next time.

The caching strategy determines when and how data is written to the cache. There are four main strategies, each with different trade-offs in freshness, write latency, and failure behavior.

Cache Aside (Lazy Loading) — the most common strategy.

The application manages the cache explicitly:

  1. Check cache for the key.
  2. If hit → return the cached value.
  3. If miss → fetch from DB, write to cache with TTL, return.

Writes update the database, then invalidate (delete) the cache entry. The next read will miss and re-populate from the DB.

Pros:

  • Cache only holds data that's actually read (no wasted memory).
  • Fault-tolerant: if the cache crashes, the system still works (just slower).
  • Simple to implement.

Cons:

  • Stale data: between a write and the cache invalidation, reads can return old data. TTLs cap the staleness window.
  • Cache stampede: when a popular key expires, N concurrent requests all miss and all fetch from the DB simultaneously.
  • Application code is aware of the cache (not transparent).
Cache stampede (thundering herd)

When a popular cache entry expires, the next N requests all see a miss at the same time. They all fetch from the DB, all write to the cache. The DB takes N× the expected load for a brief window. Mitigations: (1) cache locking — only one request fetches, others wait; (2) early refresh — refresh before expiry; (3) probabilistic early expiration — add jitter to TTLs so they don't all expire at once.

Write Through — the cache is always fresh.

Writes go to both the cache AND the database synchronously. The application writes to the cache; the cache writes to the DB and returns only after both succeed. Reads always hit the cache.

Pros:

  • Cache is always fresh — no stale reads.
  • Read performance is optimal (always cache hit, assuming data has been written).
  • Simple read path (no DB fallback).

Cons:

  • Higher write latency (must write to cache + DB synchronously).
  • If the cache is down, writes fail (unless you add fallback logic).
  • Cache holds everything ever written, even if never read (wasted memory).

Best for: data that's written once and read many times, where staleness is unacceptable.

Write Behind (Write-Back) — the fastest writes, but risky.

Writes go to the cache only. The cache returns immediately. A background process writes to the DB asynchronously (batched, delayed).

Pros:

  • Extremely fast writes (only one write to cache, no DB round-trip).
  • DB load is smoothed (batched writes).
  • Survives brief DB outages (writes queue in cache).

Cons:

  • Data loss risk: if the cache crashes before flushing to DB, committed writes are lost.
  • Reads from the DB (by other services, analytics) can see stale data.
  • Complex to implement (write queue, flush logic, ordering).

Best for: high-write, low-criticality data (counters, analytics events, telemetry). Never use for payments or transactions.

Refresh Ahead — popular items never expire.

The cache proactively refreshes entries before their TTL expires. A background process watches for entries nearing expiry; if they're frequently accessed, it refreshes them from the DB before they expire.

Pros:

  • Popular items never miss — the user never waits for a DB fetch.
  • Smooths DB load (refreshes are spread over time, not bursty).

Cons:

  • Wastes resources refreshing items that nobody reads.
  • Complex to implement (need to track access frequency).
  • If the refresh fails, the item expires normally.

Best for: systems with clear 'hot' items (home page content, popular product pages, trending topics).

Check yourself
solid

Your cache aside system uses a 5-minute TTL on user profiles. A user updates their bio, the DB write succeeds, but the cache invalidation call fails (cache is briefly down). What happens?

Pick one answer.

Check yourself
interview

You need to cache analytics events that are written at 100,000 events/sec but only read for dashboards (rarely). Which strategy is best?

Pick one answer.

Check yourself
hard

A popular product page's cache entry expires. Within the same second, 1000 users request the page. What happens, and how do you mitigate it?

Pick one answer.

Database Replication & Caching— Supplementary explanation. The NO CAP lesson remains self-contained.

Cache hierarchy — layered caches compose. Production systems rarely have one cache. They have a stack: each layer is faster but smaller, and each serves misses from the layer below.

A typical web app stack:

  1. Browser cache (per-user, seconds-to-days TTL). Static assets with hashes in filenames (e.g., app.abc123.js) cached for a year. HTML cached for seconds.
  2. CDN edge cache (per-PoP, minutes-to-hours TTL). Static assets, sometimes HTML, cached at 300+ PoPs globally. ~10ms latency to user.
  3. App-server in-process cache (per-instance, seconds TTL). Frequently accessed config, computed values. ~0.01ms latency. Lost on restart.
  4. Distributed cache (Redis/Memcached) (shared, seconds-to-minutes TTL). User profiles, session data, query results. ~1ms latency. Survives app restarts.
  5. Database query cache (per-DB, often disabled). Cached query results. Often more trouble than it's worth (invalidation is hard).
  6. Database buffer pool (per-DB, transparent). Pages cached in RAM. ~0.1ms latency. The OS page cache provides another layer.

The key insight: each layer only holds a fraction of the data, and each layer serves ~90% of its requests from cache. So 1000 user requests might result in 100 CDN misses (10%), of which 10 reach the app (90% served from CDN), of which 1 reaches the DB (90% served from Redis). The DB sees 0.1% of original load. This is why a small cache can carry a 1000x-larger database.

All four strategies, side by side.

StrategyWhen written to cacheRead pathWrite latencyStalenessFailure riskBest for
Cache-asideOn read miss (lazy)cache → DB on misslow (DB only)up to TTLcache crash = slow, not brokenread-heavy, can tolerate staleness
Write-throughOn write (sync to both)cache always hitshigh (cache + DB sync)nonecache down = write failswrites-once-read-many, freshness critical
Write-behindOn write (cache only, DB async)cache always hitsvery low (cache only)DB may lag seconds-minutescache crash = data losshigh-write, low-criticality (counters, telemetry)
Refresh-aheadProactively before TTL expirescache always hits (for popular items)lownone (for popular items)wasted work on cold itemshot items (home page, trending)

The right strategy depends on (1) read:write ratio, (2) staleness tolerance, (3) write latency tolerance, and (4) data-loss tolerance. Most systems combine: cache-aside as the default, write-through for transactional state, write-behind for counters and analytics, refresh-ahead for hot keys.

The architect's rule: start with cache-aside. Add complexity only when measurements prove you need it. Most cache-related outages come from over-engineering (write-behind on data you can't afford to lose) or under-engineering (cache-aside on a hot key without stampede protection).

Real system: Netflix EVCache

Netflix's EVCache is a Memcached-based distributed cache deployed across multiple AWS regions. It serves 90%+ of Netflix's read traffic — user profiles, watch history, content metadata, recommendations. The architecture: each region has its own EVCache cluster (multiple shards for horizontal scaling, with replicas for HA). Writes go to the local region's EVCache synchronously (write-through for user state, cache-aside for content metadata), then replicate cross-region via EVCache's replication layer (asynchronous, ~seconds latency). On a region failure, Netflix routes traffic to a healthy region via Route 53 — the cache there may be slightly stale but the system stays available. This is a textbook example of layered caching (CDN → app → EVCache → Cassandra) and per-workload strategy choice (write-through for user state, cache-aside for content). The key insight: Netflix didn't pick one caching strategy — they use multiple, tuned per workload.

Check yourself
interview

Your team lead proposes using write-behind caching for the payment system: 'Writes are 100x faster, the DB catches up in a few seconds, what could go wrong?' What's the right response?

Pick one answer.

Try this
interview

The carousel requires joining 5 tables to compute (DB query: ~500ms). When the cache hits, response is 2ms. When it misses, response is 502ms. At the 5-minute TTL boundary, all 10K req/sec suddenly see misses.

Your e-commerce site caches the home page product carousel in Redis with a 5-minute TTL. At peak (Black Friday), the carousel is requested 10,000 times/sec. Every 5 minutes, your database CPU spikes to 100% for ~10 seconds. Diagnose and fix.

Engineering mental model

Mental model. Think of Caching Strategies as a deliberate boundary in a system. The boundary exists because something becomes harder to manage when everything is done in one place: latency, scale, failure isolation, consistency, cost, or team ownership. The useful question is not “what does Caching Strategies mean?” but “what pressure makes this boundary worth introducing, and what new failure mode does it create?”

Design lens

Before choosing Caching Strategies, name the workload, the critical user path, the dominant bottleneck, the failure you are trying to absorb, and the trade-off you are willing to accept. If you cannot name those five things, the design is probably premature.

Original NO CAP systems visual for Caching Strategies.
Image unavailable. Original NO CAP systems visual for Caching Strategies.
Caching Strategies: a compact system-thinking visual.— Original NO CAP visual.
// Pseudocode
request = receive()
result = caching_strategies(request)
return result

// Production questions:
// 1. What happens on timeout?
// 2. Can this operation be retried safely?
// 3. What is the bottleneck?
A minimal engineering sketch for reasoning about Caching Strategies.

Back-of-the-envelope reasoning

Example: 10M requests/day ÷ 86,400 ≈ 116 requests/s average. Design for peak rather than average; a 10× peak is ≈ 1,160 requests/s.

Interactive sandboxdeterministic

Interactive thought experiment: Caching Strategies

Change the variables below and predict what breaks first in Caching Strategies. The production lab can later reuse these same inputs.

System pressure6%
Try this

Change one variable at a time. Predict the failure mode first, then move the slider and see whether your mental model matches the simplified system response.

Hint

If you are stuck on Caching Strategies, start by drawing the request path and marking every network hop, stateful component, queue, cache and failure boundary. Then estimate where the system will saturate.

Check yourself
solid

You increase traffic by 10× in a system using Caching Strategies. What should you inspect first?

Pick one answer.

Check yourself
interview

Which statement is the safest engineering habit when using Caching Strategies?

Pick one answer.

Try this
interview

You have dashboards for traffic, latency, errors and saturation. You can change the architecture, but every change has operational cost.

Production scenario: your system uses Caching Strategies, traffic suddenly spikes, and p99 latency doubles. What is your first move?

Interview drill

Answer this without notes: When would you choose Caching Strategies, and when would you intentionally avoid it? Mention at least one bottleneck it addresses, one failure mode it introduces, and one alternative. Then quantify the workload you are designing for.

Engineering lens

For Caching Strategies, reason in this order: what data is hottest, where can it live closer to the caller, what makes it stale, and what happens on a miss or cache failure. A cache is an optimization boundary, not the source of truth.

Numerical sanity check

A useful first-order model is cache_load = request_rate × (1 - hit_rate). If traffic is 20,000 req/s and the hit rate is 90%, roughly 2,000 req/s still reaches the origin before considering misses caused by expiration or eviction.

Check yourself
interview

Do not optimize for a memorized definition. Reason from the workload and failure mode.

You have a read-heavy Caching Strategies path. Traffic doubles overnight. What metric would you inspect first, and what would convince you to add another cache layer?

Pick one answer.

Trade-offs

What you gain, what you pay

Pros
  • +Dramatically reduces latency — cache hits are 100x faster than DB reads.
  • +Reduces database load — hot data served from cache, DB handles cold reads only.
  • +Multiple strategies for different use cases (freshness vs speed vs complexity).
Cons
  • −Stale data — every strategy has some window where cache and DB diverge.
  • −Cache stampede — popular key expiry can overwhelm the DB.
  • −Operational complexity — monitoring cache hit rate, eviction policy, memory usage.
  • −Data loss risk (write-behind) — if cache crashes before flushing to DB.
Failure modes

How this breaks in production

  • Stale data window — cache and DB diverge between write and invalidation.
  • Cache stampede — popular key expiry causes thundering herd.
  • Cache thrashing — keys evicted before they're read again (cache too small for working set).
  • Data loss (write-behind) — cache crash before DB flush.
Common mistakes

Don't fall into these traps

  • •No TTL. Without a TTL, a cache invalidation failure means stale data forever.
  • •Caching everything. Caching rarely-read data wastes memory and adds invalidation complexity.
  • •Forgetting cache stampede protection on hot keys.
  • •Updating cache before DB. If the cache write succeeds but the DB write fails, you are now inconsistent. Always write DB first, then cache.
Where you see it

Real systems using this

Netflix (EVCache — multi-tier caching: CDN → origin cache → DB).Redis / Memcached (in-memory key-value stores implementing cache-aside).CDN edge caching (Cloudflare, Fastly — cache static content at the edge).
Teardowns

How real systems implement this

  • Netflix EVCache — Multi-tier caching: CDN edge → origin cache (EVCache, built on Memcached) → database. 90%+ of reads served from cache. Cache-aside for content metadata, write-through for user state.
  • Redis — In-memory key-value store used as a cache. Supports cache-aside (GET/SET/DEL), write-behind (with background sync to DB), and TTLs. Most popular cache in production.
Interview prompts

Practice saying it out loud

  • Q1Compare cache-aside, write-through, write-behind, and refresh-ahead.
  • Q2What is a cache stampede, and how do you prevent it?
  • Q3Your cache and database diverged. How do you detect it, and how do you fix it?
  • Q4When would you NOT use caching? What are the risks?
Research

Further reading & references

System Design Primer
Open source
ByteByteGo — Scale from zero to millions
ByteByteGo
System Design Tutorial
GeeksforGeeks
System Design Roadmap
roadmap.sh
Caching reference
Reference
Caching reference
Reference
Caching reference
Reference

Core explanations are original NO CAP material. External references are provided for deeper study and standards.

What next?

Mark as understood once the mental model clicks.

Next recommended

Cache Aside (Lazy Loading)