Back to the map

Module 01 · Machine basics · Lesson 2 of 4

The memory hierarchy

Registers, caches, RAM, SSD, disk and the network, each a hundred times slower than the last. The latency numbers worth memorising, cache lines and locality, why arrays beat linked lists.

CoreMust-knowJunior 12 min Updated Nov 2026

Why it matters

The single most useful set of numbers in computing is how long it takes to fetch data from each level of storage. They explain why caching works, why databases are organised in pages, why reading a file sequentially is fast and randomly is slow, and why a service that calls another service is so much slower than one that does not. Every design decision about where data lives is a decision about this hierarchy.

The idea

Fast memory is small and expensive; big memory is slow and cheap. So computers stack several levels, each larger and slower than the one above, and keep the data in current use in the faster levels. The CPU looks in the fastest level first and falls through to slower ones on a miss.

RegistersL1 cache · 32–64 KBL2 · ~1 MB · L3 · tens of MBMain memory (DRAM) · GBsSSD · TBsHard disk · object storage · TBs to PBsAnother machine over the networkfaster ↑larger ↓
Each level down is larger, cheaper per byte, and slower. The art of performance is keeping the working set as high up as possible.

Numbers worth memorising

AccessApproximate latencyIf one L1 hit were one second
L1 cache hit~1 ns1 second
L2 cache hit~4 ns4 seconds
L3 cache hit~15–40 nsunder a minute
Main memory (DRAM)~80–100 nsabout a minute and a half
NVMe SSD random read~20–100 µshalf a day to a day
Round trip within a data centre~0.5 msabout a week
Hard disk seek~5–10 mstwo to four months
Round trip across a continent~80–150 msabout three to five years
Exact values vary by hardware; the ratios between levels are what to remember.

Cache lines and locality

Caches do not move single bytes; they move cache lines, typically 64 bytes. Reading one byte from memory brings its 63 neighbours into the cache for free. Hardware prefetchers watch access patterns and fetch the next lines before you ask. Two kinds of locality make this pay off: temporal (data used now is likely used again soon) and spatial (data near what you used is likely used next). Code that walks memory sequentially gets near-L1 speed; code that jumps around pays a main-memory trip on almost every access.

PatternCache behaviourSpeed
Iterating an array in orderEach 64-byte line serves 16 ints; prefetcher runs aheadNear peak
Iterating a linked listEach node may be anywhere in memory; one miss per nodeOften 10x or more slower
2D array by rows (row-major language)SequentialFast
2D array by columnsEach access in a different lineSeveral times slower
Hash table with large valuesLookup hits a random line; value spans severalOne or more misses per lookup

When cores share caches

L1 and L2 are usually per core; L3 is shared. When two cores write to different variables that happen to sit in the same cache line, the line ping-pongs between them, each write invalidating the other core's copy: false sharing. Counters updated by many threads are the classic victim; padding each counter to its own line fixes it.

The same idea, all the way up

The hierarchy does not stop at the machine. A service's in-process cache, a Redis cluster, the database's buffer pool, a CDN edge and object storage are the same pattern at larger scale: keep the hot working set in the faster, smaller tier, and accept a miss penalty for the rest. The Caching module in System Design is this lesson applied to distributed systems.

Trade-offs

Caching trades capacity for speed at every level, and only pays off when access has locality. Workloads with no locality (random access over a dataset far larger than cache) run at the speed of the slowest level involved, no matter how much faster the top levels are. Data layout choices that favour the cache (arrays of structs versus structs of arrays, compact representations) often matter more than algorithmic tweaks.

In an interview

Use the numbers to justify placement: "Session lookups happen on every request, so they live in Redis in the same zone, about half a millisecond, not in the primary database across the region. Product data is cached in-process for the hottest 10,000 items, which is memory access, about 100 nanoseconds." Or to explain a data structure: "B-trees use page-sized nodes because each disk or SSD read fetches a whole page anyway."

Check yourself

Two loops sum every element of the same large 2D array of ints in a row-major language. One loops rows then columns; the other columns then rows. The second is several times slower. Why?

The memory hierarchy · Backplane