CMD Guide
HomeSystem DesignCaching

Introduction to Caching

A cache works because a small pool of fast storage placed in front of a slow source can answer most requests from a working set that is far smaller than the whole dataset: you pay the slow source's latency once to populate an entry, then serve every subsequent request for that key from memory until it is evicted or expires. The entire payoff rests on one physical fact — reading from RAM is roughly five orders of magnitude faster than a cross-datacenter round trip — so if even a modest fraction of requests hit the fast layer, the average latency collapses toward the fast number.

The latency hierarchy that motivates caching

Caching is not a clever trick; it is arbitrage against a steep cost gradient. These are the canonical order-of-magnitude numbers (Jeff Dean's "Latency Numbers Every Programmer Should Know," updated to modern hardware):

OperationTypical latencyRelative to L1
L1 cache reference~1 ns
Main memory (RAM) reference~100 ns100×
Read 1 MB sequentially from RAM~3 µs3,000×
SSD random read~16 µs16,000×
Round trip within same datacenter~0.5 ms500,000×
Disk (HDD) seek~2–10 ms~2–10 million×
Round trip California → Netherlands~150 ms~150 million×

A cache moves the answer up this table: an in-memory cache turns a 0.5 ms in-datacenter DB round trip (or a 150 ms cross-continent call) into a ~100 ns memory read. That is the whole game — and it is why "just add RAM in front of it" is the single highest-leverage latency optimization in systems work.

Worked example: what a 90% hit ratio actually buys

Suppose a read is served either from a Redis cache (1 ms end-to-end, including the network hop to the cache node) or, on a miss, from Postgres (50 ms including query + round trip). Let h be the hit ratio. The blended average latency is:

avg = h × t_hit + (1 − h) × t_miss

Note the subtlety: a miss usually costs more than a bare DB read, because you pay the cache lookup (1 ms), then the DB (50 ms), then a write-back to the cache. So a truthful miss cost is ~51 ms. Walking the ratio:

Hit ratio hAvg latency = h·1 + (1−h)·51vs. no cache (50 ms)
0% (cache useless)51.0 msslower — pure overhead
50%26.0 ms1.9× faster
90%6.0 ms8.3× faster
99%1.5 ms33× faster

Two lessons fall out. First, the curve is dominated by the tail: going from 90% → 99% (a mere 9 points) roughly quarters the average latency, because each remaining miss is 51× more expensive than a hit. Second, a cold or badly-keyed cache with a low hit ratio can be net negative — at h=0 you added 1 ms of pure overhead to every request and got nothing. Hit ratio is the metric that decides whether the cache is an asset or a liability.

diagram
diagram

Key terminology, tied to the mechanism

Where caches live

The same mechanism recurs at every layer, differing only in what "fast" and "source" mean: CPU L1/L2/L3 (source = RAM), OS page cache and browser cache (source = disk/network), an in-memory cache like Redis or Memcached (source = database), the database's own buffer pool (source = disk pages), and a CDN edge cache (source = origin server, replacing a cross-continent trip with a nearby one). "Database caching" specifically means the DB keeping hot pages/results in its buffer pool — not a separate product.

Pitfalls

When to reach for a cache — and when not to

A cache is the right tool when the access pattern is read-heavy with temporal locality: the same keys are requested repeatedly within a short window, and the data can tolerate being slightly stale. Concrete signals: read:write ratio well above ~10:1, a skewed key distribution (a small "hot set" serves most traffic), an expensive-to-produce value (a heavy join, an aggregation, a remote API call), and a business tolerance for bounded staleness (a product page can be seconds stale; a bank balance at a teller cannot). The inverse signals disqualify just as fast: write-heavy keys needing strong freshness (balances, live inventory) and per-user data with almost no reuse pay the cache's costs without its payoff.

Trade-offs vs. named alternatives

Choose a cache when the working set is much smaller than the dataset and reads dominate. You gain latency (the ~8× above) and offload the source. It costs you: a second system to operate, a coherence problem (invalidation) you did not have before, and the possibility of serving stale data.

The senior instinct: do not add a cache reflexively. Add it when you can point to a specific hot read path, estimate the hit ratio, and accept a defined staleness bound. If any of those three is missing, a cache adds complexity and stale-data risk without a guaranteed win.

Fast disqualifiers

Design-review follow-ups: Why not cache everything? Fill cost + staleness + stampede risk must beat DB cost. What do you watch in operation? Hit rate, miss latency, and stampede DB QPS on TTL boundaries.

Takeaways


Re-authored and deepened for this guide. Latency figures adapted from Jeff Dean & Peter Norvig's "Latency Numbers Every Programmer Should Know" (with Colin Scott's updated interactive tables) and Brendan Gregg's Systems Performance. Caching patterns and failure modes draw on Alex Xu, System Design Interview (Vol. 1), Martin Kleppmann, Designing Data-Intensive Applications (Ch. 1, 5), and the Redis and AWS ElastiCache documentation. The invalidation aphorism is Phil Karlton's.

🤖 Don't fully get this? Learn it with Claude

Stuck on Introduction to Caching? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **Introduction to Caching** (System Design) and want to truly understand it. Explain Introduction to Caching from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **Introduction to Caching** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **Introduction to Caching** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **Introduction to Caching** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes