The Memory Hierarchy — Why Bandwidth Rules Inference

Post 1 ended on a reversal: GPUs are fast at arithmetic, but arithmetic is rarely the bottleneck — moving data is. This post makes that concrete by walking the GPU's memory hierarchy, from the tiny ultra-fast registers next to the compute units down to the big slow memory that holds the model's weights. Once you see the orders-of-magnitude gaps between these levels, every performance decision in LLM inference starts to make sense.

The central fact of GPU performance is that there isn’t one “memory” — there’s a hierarchy of them, each a trade-off between speed and size. Compute units are fast; the memory holding your data is comparatively slow; and the whole game is keeping data as close to the compute as possible. This post builds that hierarchy and explains why, for LLM inference specifically, memory bandwidth — not compute — is usually the number that decides your speed.

The hierarchy, fastest to slowest

Like a CPU, a GPU has a memory hierarchy: small-and-fast at the top, large-and-slow at the bottom, with each level roughly an order of magnitude bigger and slower than the one above.

The gaps are large: reading from registers is perhaps a hundred times faster than reading from global memory. So a kernel that constantly reaches down to HBM will run at a fraction of the speed of one that keeps its working data in shared memory and registers. “Where does the data live?” is the question that governs GPU performance.

Bandwidth vs. capacity: two different limits

Global memory imposes two separate constraints, and conflating them causes a lot of confusion:

Capacity determines whether you can run the model; bandwidth often determines how fast. Both are about memory, not compute — which is already a strong hint about where LLM inference spends its time.

Why LLM generation is memory-bound

Here is the fact that surprises people new to inference. When an LLM generates text one token at a time (decoding), each step must read the model’s entire set of weights from HBM to compute just one token’s worth of output. For a large model that’s gigabytes of weights read per token — an enormous amount of data movement to produce a tiny amount of compute.

The result: the compute units finish their small amount of arithmetic and then sit idle, waiting for the next chunk of weights to arrive from memory. The GPU is memory-bandwidth-bound — its speed is set by how fast it can stream weights out of HBM, not by how many FLOPS it can do. This single fact explains a huge amount of inference engineering: - Why batching helps so much (serving series): if you read the weights once and use them for many sequences at once, you amortize the expensive memory read across many tokens — turning a memory-bound workload compute-bound. - Why quantization is so effective (post 5): smaller weights mean less data to stream from HBM per token, so a more compact model is directly a faster model, not just a smaller one. - Why the KV cache is a bandwidth problem, not just a capacity one: it too must be read every step.

Not everything is memory-bound — the prefill phase (processing the prompt) does enough parallel compute to be compute-bound, and large batches shift the balance. Knowing which regime you’re in is the whole point of the roofline model (post 3). But the default mental model for single-stream LLM generation is: you are waiting on memory bandwidth.

The takeaway: a GPU has a memory hierarchy — registers → shared memory/L1 → L2 → global memory (HBM) — each level roughly an order of magnitude larger and slower, so performance is governed by where the data lives (keep it in shared memory and registers; every trip to HBM is expensive). Global memory imposes two distinct limits: capacity (does the model + KV cache fit at all?) and bandwidth (how fast weights stream to the compute units). And the defining fact of LLM generation is that it’s memory-bandwidth-bound — each token requires reading the whole model from HBM — which is precisely why batching and quantization work: they reduce data movement per token.

Key takeaways

Further reading

Sources & References

Where weights and the KV cache live
Registers to HBM, fast-small to slow-large