Master Local AI
  1. 0Load
  2. 1You type
  3. 2Tokenize
  4. 3To the GPU
  5. 4Prefill
  6. 5Decode
  7. 6Show text
Can it run?

Chapter 8 · Builder

Serving: Batching, Paged KV and Prefix Caching

Batching is nearly free. KV memory sets the limit.

  1. 0Loadonce: file → VRAM
  2. 1You typetext in the app
  3. 2TokenizeCPU: text → IDs
  4. 3To the GPUIDs cross PCIe
  5. 4Prefillwhole prompt, one pass
  6. 5Decoderead all weights → 1 token
  7. 6Show textID → word · repeat 5

1Watch

Now

Press a step on the right, or change any control under the machine.

Readout

Key to the machine

A bottle-filling carousel: each bottle is one request; every turn drops a token into all of them. Watch the green KV crates. When the memory is full, bottles wait.
How the numbers work

A decode step reads every active weight once, however many sequences ride in the batch, so a turn takes the same time with one bottle or forty: total tokens per second climb almost in step with users while each user's rate falls slowly, until the KV cache (the crates) runs out or the GPU's arithmetic becomes the limit. Static batching shuts the gate until the slowest bottle is full; continuous batching (vLLM, SGLang, TensorRT-LLM) drops a new request into any free pocket at the next step, and paged KV blocks with a shared 512-token system prompt (prefix caching) fit more pockets than reserving 1,472 tokens per slot. Each turn here stands for 64 decode steps, slowed down; the readout comes from a simulation with 1,024-token prompts and 64–448-token replies, step time = bytes read ÷ (bandwidth × 0.7) or FLOPs ÷ (dense FP16 × 0.5), whichever is longer, and TTFT includes queue time.

  • Bottle = one request’s reply
  • Green crates = KV cache in use
  • Plugged pockets = no KV room
Speed
Open full screen ↗

2Try this

Then change anything yourself.

3Read on ↓

Batching is cheap until memory fills

One weight read serves every user in the batch. With B sequences:

t_\text{step} \approx \frac{W + B\cdot \text{KV}_\text{read}}{\eta \cdot \text{BW}},\qquad \text{throughput} = \frac{B}{t_\text{step}}

While the weights W dominate, throughput grows almost linearly with B. Three limits end this:

  1. KV memory. Each sequence needs its own cache. When VRAM is full, requests wait in a queue.
  2. KV bandwidth. At long contexts, the KV reads rival the weight reads.
  3. Compute. Past the roofline ridge (Chapter 3), the tensor cores reach their limit.

Step 2 above shows free batching. Step 4 shows the KV memory limit.

Five techniques

Each technique removes waste.

  • Continuous batching: the scheduler admits and retires requests at every decode step. vLLM, SGLang, TensorRT-LLM and llama-server (--parallel) use it.
  • PagedAttention (vLLM): the KV cache sits in fixed-size blocks, like virtual memory. No sequence reserves worst-case space, and sequences share blocks.
  • Prefix caching: requests that start with the same tokens reuse cached KV blocks. They skip that part of prefill.
  • Chunked prefill: the server splits a long prompt into chunks between the decode steps of other users. One 30k-token prompt then does not freeze the other streams.
  • Speculative decoding: a small draft model proposes tokens. The target model checks them in one pass, so each weight read gives more tokens.

Static or continuous

Continuous batching gives more throughput and a lower TTFT at the same load. Slots never wait for the longest request. Step 3 above shows the static penalty.

Past saturation, both policies queue. Then add KV capacity (FP8 KV, paged allocation), add a second GPU, or limit admissions.

Metrics

Quote four metrics, and state the test setup with them.

Metric Meaning Driven by
TTFT queueing + prefill until the first token compute, prompt length, prefix cache hits, scheduler
TPOT / ITL time per output token or between tokens bandwidth, batch size, KV length
Throughput total output tokens/s across users batch size, KV capacity
Goodput requests/s that meet the SLO (e.g. TTFT < 1 s, TPOT < 50 ms) all of the above

State the model, quant, context, concurrency, hardware, driver and runtime version. Without them, nobody can compare the numbers.

Explain it

  1. "What is PagedAttention?" The server stores KV caches in fixed blocks addressed through a table, like OS virtual memory. Sequences reserve no worst-case memory, and they share common prefixes.
  2. "TTFT is high at low load. What helps?" Prefix caching for the repeated system prompt and tool schemas. Chunked prefill and shorter tool outputs also help.
  3. "Throughput or latency?" Check the SLO. Batch until per-user TPOT reaches the SLO limit; that point is the goodput optimum.

Exercises

  1. Add prefix caching to the simulator: a shared 1,500-token system prompt costs prefill once per slot.
  2. Find the arrival rate where median TTFT crosses 2 s for each policy, at 8 and 32 slots.