The Memory Hierarchy and Caching

The single most counterintuitive fact in performance engineering: accessing memory is not one speed. A value in the CPU cache is hundreds of times faster to reach than one in main memory, which is thousands of times faster than disk. Your code's speed often depends less on how many operations it does than on where the data lives — and understanding the memory hierarchy is what lets you see that.

The virtual-memory post hinted that memory access cost varies. This post makes that central: the memory hierarchy — the layered structure of storage from fast-tiny (CPU registers/cache) to slow-huge (disk) — and why locality and caching dominate real-world performance. This is one of the highest-leverage things an engineer can understand about performance, because it explains why two programs doing the same amount of work can differ enormously in speed. It’s the “why” behind a lot of performance mysteries.

Memory is not one thing

The mental model most people start with — “memory is memory, accessing it takes some fixed time” — is wrong and hides most of performance. Real machines have a hierarchy of storage, each level trading speed for size and cost:

            Speed        Size         (rough relative access time)
Registers   fastest      tiny         ~1x        (in the CPU)
L1 cache    very fast    ~KBs         ~a few x
L2 cache    fast         ~hundreds KB ~10x
L3 cache    fast-ish     ~MBs         ~tens of x
Main memory faster       ~GBs         ~hundreds of x   (RAM)
SSD/disk    slow         ~TBs         ~thousands+ x
Network     slowest      vast         ~much more

The key facts (the ratios matter more than exact numbers, which vary by hardware):

So “accessing memory” is not one speed — it’s a spread of speeds spanning many orders of magnitude, depending on which level the data is in. This single fact — that memory access cost varies by orders of magnitude by level — is the foundation of performance engineering, because it means where your data lives dominates.

Caching and locality

Because the fast levels are small and the slow levels are large, the system can’t keep everything fast — so it caches: keep the most-likely-to-be-used data in the faster levels. The CPU automatically caches recently- and nearby-accessed memory in L1/L2/L3, so that if you access the same or nearby data again, it’s served fast (a cache hit) instead of slow (a cache miss going to main memory). This works because real programs exhibit locality:

Caching + locality is why the hierarchy works: programs don’t access memory randomly; they access recent and nearby data repeatedly, so keeping that in fast caches gives most accesses fast. When your program has good locality, most accesses hit the cache (fast); when it has poor locality (random, scattered access), most accesses miss (slow, going to main memory). This is why the pattern of memory access, not just the amount, determines speed.

Why this dominates performance

Here’s the counterintuitive, high-leverage consequence: two programs doing the same number of operations can differ enormously in speed based purely on their memory-access patterns (locality). Because a cache miss costs ~100x a cache hit, a program that constantly misses the cache spends most of its time waiting for memory, not computing — even if it does the same arithmetic as a cache-friendly version. Real examples of this principle:

The lesson: performance is often about memory, not computation. When code is slower than its operation count suggests, the cause is frequently cache misses — poor locality, bad data layout, or a working set that overflows a cache level. This is why performance-conscious engineers think about data layout and access patterns, not just algorithms. It’s also why the same big-O algorithm can be 10x faster with cache-friendly data structures. Understanding the hierarchy lets you see this hidden dimension of performance.

What this means for engineers

You don’t manage the CPU cache directly (the hardware does), but understanding the hierarchy guides real decisions:

The memory hierarchy — orders-of-magnitude speed differences by level, made to work by caching and locality — is why where data lives and how you access it often matters more than how much computation you do. It’s a hidden but dominant dimension of performance, and understanding it turns “why is this slow?” from a mystery into a question about cache misses and locality. The next post covers the OS’s handling of the slowest common tier: I/O.

Key takeaways

Further reading

Sources & References