Production serving stacks run a warm up forward pass at the expected shapes before the pod accepts traffic. Explain what concretely happens during that first pass that the second and subsequent passes get for free, and why skipping warm up shows up as a multi-second TTFT spike on the very first real request.
The first forward pass runs cuBLAS/cuDNN heuristic search, CUDA-graph capture, and any JIT or TensorRT engine build, all cached after.
Imagine a chef arriving at a new kitchen for the first time. Before they can cook the first dish quickly, they have to learn where every pot lives, sharpen the knives to the right edge for this style of food, and pre-heat each burner to the temperature this menu wants. Once they have done all that, every dish after the first comes out fast. If you make a paying customer the first order of the night, that customer waits while the chef learns the kitchen. A warm-up is sending a fake order before opening so the chef can do all that learning, then the first real customer gets the fast experience.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
The first forward pass is special. Almost every layer of the GPU software stack defers shape-dependent work until real tensors arrive, then caches the result. The cost of that deferred work lands on whichever forward pass happens to be the first one. In production, that should be a synthetic warm-up batch, not a real user request.
This deep dive enumerates the caches that fill, quantifies the cost of each, explains why the caches are shape-keyed and what that means for warm-up coverage, and walks through the operational protocol that makes this invisible to users.
The four caches that fill on the first pass
Step through the layers of the stack and each one has its own one-shot cost.
cuBLAS and cuDNN heuristic selection. Both libraries expose multiple algorithm variants for each operation. cublasLt has dozens of GEMM algorithms differing in tile size, split-K strategy, and Tensor Core path. cudnnFind picks among convolution algorithms. The first time the library sees a problem size, it runs a brief benchmark or applies a learned heuristic to pick the fastest variant for that shape, dtype, and GPU. The choice goes into a cache keyed on the input parameters. Subsequent calls at the same shape skip the search and use the cached choice. In a transformer this cache fills across the QKV projection, the attention matmuls, the output projection, and the MLP gates; each distinct shape requires its own entry.
CUDA graph capture. A CUDA graph is a recorded sequence of kernel launches plus their parameters plus dependencies. After capture, the entire graph replays with a single cudaGraphLaunch call, eliminating the 5-20 microseconds of CPU overhead each unrecorded launch carries. For a 70B model with thousands of kernel launches per decode step, that overhead saving is several milliseconds per token. Capture requires executing the model once with stream-capture enabled. Because the graph captures specific pointers and shapes, it must be re-captured if those change, which is why continuous-batching stacks like vLLM pre-capture several graphs at the batch sizes they round forward passes to.
JIT or AOT compilation. Any compiler in the stack does serious work on the first call. torch.compile traces with TorchDynamo and lowers with Inductor to Triton-compiled fused kernels; the first call at each new shape takes seconds to compile, and a fresh compile on a 70B model can take a minute. TensorRT-LLM builds an engine, which is an exhaustive plan over fused operators, kernel choices, and tactic selection; the build itself happens ahead of time, but loading the engine and materializing plans on the device still happens at pod start. XLA does similar HLO compilation.
Allocator pools and metadata caches. PyTorch's caching allocator carves blocks lazily; the first allocation of each size hits the underlying cudaMalloc, which is slow and synchronizes the device. Once the pool is sized to the workload's working set, the allocator hands out reused blocks without driver calls. A warm-up pass at the production shape forces these pools to size themselves correctly, so steady-state requests never see an allocator stall.
Situations where this technique stops working.
2–4 min · Everything important, quickly.
| Phase | What happens | Typical cost | Cache-key |
|---|---|---|---|
| Weight load | Read parameters from disk to HBM | 1-30 s depending on size | Per pod |
| cuBLAS / cuDNN autotune | Benchmark or heuristic-pick best GEMM algorithm | 10-200 ms per shape | Per (shape, dtype, GPU) |
| CUDA graph capture | Record kernel launch sequence | 10-100 ms per graph | Per (shape, batch, seq_len) |
| JIT / TensorRT compile | Build fused-kernel engine | 1-300 s on first ever build | Per (model, ops, shapes) |
| Allocator priming | Carve permanent memory pools | Tens of ms | Per pod |
| GPU clock ramp | DVFS reaches boost clocks | Sub-second | Per workload start |
Real products, models, and research that use this idea.
- vLLM ships a warmup_steps parameter that walks the configured decode batch sizes during engine init, before the API server starts accepting requests.
- TensorRT-LLM builds an engine ahead of time, but its runtime still needs a warm-up forward pass on the GPU to materialize plans and prime allocators after loading the engine.
What an interviewer would ask next. Try answering before peeking at the approach.
QWhy must warm-up cover all production shapes, not just one?
cuBLAS, cuDNN, CUDA graphs, and TensorRT all key their caches on shape (and often on dtype and stride). A model warmed at batch 1 and prompt length 128 will hit a fresh autotune the first time batch 8 or prompt length 4096 arrives. Production warm-up routines enumerate the shape grid: typical batches and a coarse prompt-length spectrum.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Treating cold start as a model-load problem. The weight load is part of it, but the bigger surprise is the per-shape autotune, graph capture, and JIT compile that fire only on the first forward pass at each shape.
60 second bullets to scan on the way to the call.
What cuBLAS and cuDNN cache on first call and why it is shape-keyed
What CUDA graphs are and why capture is slow but replay is fast
Primary sources. Browse if you want the original framing.
Same topic, related formats. Practice these next.