Unit 8 · AI infrastructure · Lesson 8 of 10
PagedAttention, continuous batching and scheduling
Builds on
Step 1: Learn the ideas
- Static, dynamic and iteration-level (continuous) batching
- Selective batching of token-wise operations versus per-sequence attention
- Paged KV cache: fixed-size blocks, block tables, on-demand allocation
- Fragmentation from contiguous maximum-length reservations
- Sharing and copy-on-write for parallel sampling and beam search
- Admission control, preemption, swapping versus recomputation
- Chunked prefill and token budgets per iteration
- Prefill/decode disaggregation (awareness)
- Automatic prefix caching (awareness)
- Scheduling policies and fairness across requests and tenants
Why it matters
A serving engine's throughput is decided by how many sequences it keeps in flight. Prompt and output lengths differ and KV caches grow with every generated token, so batching and memory management must adapt at every step. Iteration-level batching and paged KV-cache management are the two ideas behind modern engines, and they lead straight to scheduling questions about admission, preemption, fairness and prefix sharing.
Core ideas
From static to iteration-level batching. With request-level batching, a batch runs until its longest sequence finishes: finished slots idle and new requests queue. Orca schedules at the granularity of one model iteration instead: after every step, finished sequences leave and waiting ones join. Token-wise operations (linear layers, normalization) are batched across all sequences, while attention is computed per sequence because lengths differ, which Orca calls selective batching.
Paged KV cache. Reserving a contiguous buffer for each request's maximum length wastes memory on unused reservations and gaps between buffers, which caps the batch size. PagedAttention splits each sequence's cache into fixed-size blocks allocated on demand and records them in a block table, the analogue of a page table; the attention kernel follows the table. Waste is limited to the partly filled last block. Blocks can be shared across sequences with reference counts and copy-on-write, serving parallel sampling, beam search and common prefixes.
When memory runs out. The scheduler admits a request only if enough free blocks exist. If running sequences need more blocks than are free, some must be preempted: swap their blocks to host memory and back, paying transfer bandwidth, or drop them and recompute later, paying another prefill. The vLLM paper serves requests first-come-first-served and evicts all blocks of a sequence group together.
Prefill-decode interference. Adding a long prompt to a batch makes that iteration slow, stalling every decoding sequence and causing inter-token latency spikes. Chunked prefill, as in Sarathi-Serve, splits long prompts into pieces processed alongside decodes under a per-iteration token budget. Disaggregation, as in DistServe, runs prefill and decode on separate GPU pools and transfers the KV cache between them.
Prefix caching. When requests share an exact prefix (system prompt, conversation history, agent scaffolding), their KV blocks can be identified by content and reused, skipping that part of prefill. Cached blocks compete with active requests for memory and are evicted under pressure.
Common misconceptions
- "Continuous batching means bigger batches." It means batch membership changes every iteration; batch size is still capped by KV memory and latency targets.
- "PagedAttention makes the attention math faster." Its main gain is memory efficiency, which allows more concurrent sequences; following block tables adds some kernel overhead.
- "Preemption is cheap." Swapping costs host-device bandwidth and recomputation repeats prefill; either shows up in tail latency.
- "Prefix caching always helps." It needs exact shared prefixes at block granularity and spare memory to keep them.
How to approach it
Simulate first: a toy scheduler with a fixed number of KV blocks, requests with random prompt and output lengths, and both static and iteration-level batching; compare throughput and waiting time. Then run a real engine, vary its batching limits, toggle chunked prefill and prefix caching, and measure latency percentiles under open-loop load. When asked to design a scheduler, state the objective (throughput, SLO attainment, fairness), the admission rule and the preemption policy before details.
Suggested order
- 1Read the Orca paper’s sections on iteration-level scheduling and selective batching.
- 2Read the PagedAttention paper: memory-waste analysis, block tables, sharing with copy-on-write, and the scheduling and preemption policy.
- 3Read vLLM’s design pages on paged attention and automatic prefix caching to see the implemented versions.
- 4Read Sarathi-Serve for chunked prefill and DistServe’s motivation for disaggregation.
- 5Write the toy scheduler simulation, then run the serving benchmark project with chunked prefill and prefix caching toggled.
Step 2: Check off what you can do
Tap each one you can genuinely do or explain. Each earns 10 XP.
Step 3: Go deeper
Efficient Memory Management for Large Language Model Serving with PagedAttentionStart here
arXivPaged KV-cache design, sharing and copy-on-write, and the preemption policy.
Open(opens in a new tab)Link responded, 5 Oct 2026Orca: A Distributed Serving System for Transformer-Based Generative ModelsStart here
USENIXIteration-level scheduling and selective batching, the basis of continuous batching.
Open(opens in a new tab)Link responded, 5 Oct 2026vLLM documentation
vLLM projectSection: Design: Automatic Prefix Caching
How a production engine implements block-level prefix caching and paged attention today.
Open(opens in a new tab)Link responded, 5 Oct 2026Taming Throughput-Latency Tradeoff in LLM Inference with Sarathi-Serve
USENIXChunked prefill and stall-free scheduling to protect inter-token latency.
Open(opens in a new tab)Link responded, 5 Oct 2026DistServe: Disaggregating Prefill and Decoding for Goodput-optimized Large Language Model Serving
USENIXPrefill-decode interference and the case for disaggregating the two phases.
Open(opens in a new tab)Link responded, 5 Oct 2026
Step 4: Practice
Write a toy simulator (an hour or two in Python) with a KV block pool, random prompt and output lengths, and static versus iteration-level batching; report throughput, queueing delay and preemptions. Then run a serving engine on a small model, sweep its maximum batched sequences and tokens, toggle chunked prefill and prefix caching, and record latency percentiles at a fixed open-loop rate. Explain each change you see in terms of the mechanisms above.
- Benchmark an LLM server under open-loop load and report goodputOpen(opens in a new tab)Not attemptedSelf-directed (vLLM or another serving engine)
- Estimate the KV cache for a model you choose and check it against measured memoryOpen(opens in a new tab)Not attemptedSelf-directed (Hugging Face Transformers or vLLM)
Record attempts on each problem’s page (+15 XP, +10 more when solved on your own).
Step 5: Test yourself
Answer each one out loud or on paper before you finish the lesson.
- Question 1Why does static batching waste GPU time when output lengths vary?
- Question 2Where does memory waste come from when KV caches are reserved contiguously for maximum length?
- Question 3What triggers preemption, and what does each preemption mode cost?
- Question 4Why do long prefills cause inter-token latency spikes, and how does chunked prefill help?
- Question 5When does prefix caching help an agent workload?
You’re done when you can
- Explain iteration-level batching and selective batching in under two minutes.
- Explain how block tables reduce fragmentation and enable copy-on-write sharing.
- Compare swap and recompute preemption and say when each is preferable.
- Design an admission and preemption policy for a stated SLO and defend it.
Finish the lesson
Unlocks next: Serving metrics: goodput, TTFT and inter-token latency


