Before you move a control in the demo, say what you expect to change.
Foundation reference
LLM Serving at Scale: Prefill, Decode & Continuous Batching
A language-model server handles each request in two phases: prefill processes the prompt, and decode generates the output one token at a time, reading the keys and values of earlier tokens from a key–value (KV) cache. vLLM's PagedAttention brought KV-cache waste close to zero and improved throughput 2–4× over earlier serving systems at the same latency (Kwon et al., 2023).
Study guide
Where to start
Why are prefill (large parallel matrix multiplications over the prompt) and decode (small matrix multiplications plus large KV-cache reads) such different workloads, and why does batching them together cause interference?
How to study this pagePredict · Check · Generalize · Continue
Compare what the demo shows with the key equation and with the papers cited below.
Identify the part of the idea that survives a change of notation or model, so you can recognize it in another paper or system.
The newer notebook covers the same concept and has an interactive demo.
Why It Matters for Modern Models
- A language-model server handles each request in two phases: prefill processes the prompt, and decode generates the output one token at a time, reading the keys and values of earlier tokens from a key–value (KV) cache. vLLM's PagedAttention brought KV-cache waste close to zero and improved throughput 2–4× over earlier serving systems at the same latency (Kwon et al., 2023).
- Prefill is usually compute-bound, while decode at typical batch sizes is limited by memory bandwidth. DistServe runs the two phases on separate GPUs and reports serving 7.4× more requests, or meeting 12.6× tighter latency targets, than earlier systems (Zhong et al., 2024).
- Continuous (iteration-level) batching adds and removes requests after every decoding step, so the GPU does not sit idle waiting for the longest request in a batch to finish (Yu et al., 2022).
- KV-cache memory grows with context length and limits how many requests fit in a batch; paging makes that memory easier to allocate and share.
Questions to Think About
- How does continuous batching, which keeps a rolling set of active sequences as requests arrive and finish, differ from simply using bigger batches?
- Why does the KV cache, rather than arithmetic, usually decide the largest batch a server can run?
- How does paging the KV cache avoid fragmentation as requests grow and finish at different times, and how does it let requests share a cached prefix?
Interactive Demo
Core Math
If you prefer intuition first, try the demo above, then come back for the math.
Serving a language model to many users is a scheduling problem under latency targets, and KV-cache memory is usually the binding constraint.
Latency of one request:
TTFT is dominated by prefill, which processes the whole prompt in parallel (plus any time spent queueing); TPOT is set by decode, which generates one token at a time and reads the KV cache at every step.
Goodput: DistServe defines it as the highest request rate at which a target fraction of requests (for example 90%) meet both latency objectives (Zhong et al., 2024):
where is the request arrival rate and are the service-level objectives (SLOs).
KV-cache paging: with blocks of tokens, a sequence of length occupies
PagedAttention stores each sequence's cache in fixed-size blocks that need not be contiguous. This removes fragmentation between sequences, limits waste to the unfilled part of each sequence's last block, and lets sequences share blocks for a common prefix (Kwon et al., 2023).