GPU memory hierarchy
Where data actually lives on H100s
Sources: NVIDIA H100 Tensor Core GPU; NVIDIA Hopper Architecture In-Depth
Every optimization in vLLM ultimately bottoms out in one fact: bytes move at very different speeds depending on where they live. To reason about why prefill is fast, why decode is slow, why batching helps, why KV cache offload is a real option, and why multi-GPU serving requires NVLink, you have to know the rough numbers of the GPU memory hierarchy.
We’ll use the Nvidia H100 SXM5SXM5Server PCI eXpress Module, 5th generation — Nvidia's proprietary mezzanine board form factor for datacenter GPUs. (Despite the name, SXM bypasses PCIe entirely.) An H100 SXM5 module plugs directly into the motherboard via the SXM socket, which gives it more power (700 W vs ~350 W for PCIe), more NVLink bandwidth (900 GB/s per GPU), and higher HBM bandwidth than the PCIe variant of the same chip. Standard in HGX/DGX servers; what you get in most cloud H100 instances.See in glossary → as our concrete reference because it’s the workhorse of modern inference deployments. Other chips (A100, B100/B200, MI300X) have similar shapes with different magnitudes.
The tiers
From smallest and fastest at the top, to largest and slowest at the bottom:
| Tier | Location | Capacity | Bandwidth | Latency |
|---|---|---|---|---|
| Registers | per-thread, on-die | ~256 KB/SM | tens of TB/s (aggregate) | a few cycles |
| L1 / Shared (SRAMSRAMStatic Random-Access Memory — the on-chip scratchpad / L1+shared memory inside each SM. Tiny (~100s of KB per SM) but ~10× faster than HBM.See in glossary →) | per-SM scratchpad | up to 256 KB/SM | tens of TB/s (aggregate) | tens of cycles |
| L2 cache | shared across SMs | 50 MB | TB/s-scale | hundreds of cycles |
| HBM3HBMHigh-Bandwidth Memory — the DRAM stack soldered next to the GPU die. H100 SXM has 80 GB at ~3.35 TB/s.See in glossary → (VRAM) | on the GPU package | 80 GB | 3.35 TB/s | ~400 cycles |
| NVLinkNVLinkNvidia’s high-speed GPU-to-GPU interconnect. H100 NVLink ≈ 900 GB/s per GPU — much faster than PCIe.See in glossary → | GPU ↔ peer GPU | — | 900 GB/s | µs |
| PCIe Gen5PCIeThe bus between the GPU and the host (CPU/RAM/NVMe). PCIe Gen5 x16 ≈ 64 GB/s — far slower than HBM.See in glossary → | GPU ↔ host CPU/RAM | — | ~64 GB/s | µs |
| Host DDR5 RAM | on the CPU | 512 GB–2 TB | ~400 GB/s | ~100 ns |
| NVMe SSD | local disk | TBs | ~14 GB/s | ~50 µs |
| NIC (RDMARDMARemote DMA — letting one node’s NIC write directly into another node’s memory without involving the CPU. The basis of InfiniBand and RoCE.See in glossary → / InfiniBand) | node ↔ node | — | ~50 GB/s for a 400 Gb/s link | µs-scale |
The spread from registers to NIC is about 2,000× in bandwidth and even more in latency. Every order of magnitude matters.
What lives where
In a running vLLM worker, here’s where each kind of byte typically sits:
- Model weights: HBM. 16 GB for Llama-3-8B, ~140 GB for 70B (split across multiple GPUs).
- KV cache: HBM. Whatever is left after weights.
- Activations (intermediate per-step tensors): HBM, briefly. SRAM/registers during a kernel.
- The kernel’s actual operands: SRAM and registers. The matrix multiplies happen here.
- Idle KV pages from paused requests (if offload is enabled): host DDR5 RAM, reached over PCIe.
- Other GPUs’ shards of the same model: in their HBM, reached over NVLink.
- Other nodes’ shards: in their HBM, reached over the NIC via RDMA + GPUDirect.
- Cold model files: on NVMe disk until first load.
Try the scenarios
The visual below traces where bytes go in five common operations. Click through them and watch the animated packet follow its hops up and down the hierarchy.
A few things to notice:
-
HBM is fast, but not “free.” The H100’s 3.35 TB/s is extremely high DRAM bandwidth, but it is still far below on-chip storage bandwidth and tensor-core arithmetic throughput. A CUDA kernel tries to reuse data after loading it from HBM so that each byte supports as much arithmetic as possible.
-
PCIe is a cliff. Going off the GPU is 50× slower than HBM. This is why KV cache offload exists but isn’t free: pulling a 128 MB KV slab back from host RAM takes 2 ms, on top of whatever queueing the request did.
-
NVLink is why high-performance multi-GPU serving works. Tensor parallelism requires layer-by-layer collective communication. NVLink offers much more bandwidth and lower latency than PCIe, which can otherwise become a major bottleneck. The exact communication time depends on activation size, collective algorithm, and topology.
-
The NIC can be the bottleneck for multi-node serving. A 400 Gb/s link provides roughly 50 GB/s before protocol overhead; newer interconnects can provide more, but remain far below local HBM bandwidth. GPUDirect RDMAGPUDirectNvidia tech that lets the NIC or NVMe DMA straight into/out of GPU HBM, bypassing host RAM.See in glossary → avoids a round-trip through host RAM by letting the NIC DMA straight to/from HBM, which is important at scale.
Why decode is memory-bound, made concrete
Here’s the back-of-envelope for Llama-3-8B at fp16:
- Weights: 16 GB.
- HBM bandwidth: 3.35 TB/s.
- Time to read all weights once: ms.
- Matrix-multiply work per decode step: ~16 GFLOP (1 token through 8B weights, ×2 operations per parameter).
- H100 Tensor Core (TC) throughput (BF16): ~990 TFLOPS.
- Time to do the math: ms.
The math takes about 16 microseconds in this idealized calculation. The weights take 4.8 milliseconds to read. This roofline estimate shows why batch-1 decode has very low tensor-core utilization: HBM traffic, plus other real-world overheads, dominates.
So: read-heavy work, slow when you only have one user, much faster when you have many. The scheduler’s job is to fold “many users” into single GPU steps cleanly. That’s continuous batching, and it’s where serving stops being about the model and starts being about systems.