Handbooks  /  LLM Serving
Handbook~15 min readAdvanced
Deep Dive

Serving an LLM
fast, and cheap.

Training an LLM makes headlines; serving it pays the bills. Once a model is deployed to real users, a handful of systems tricks — the KV cache, continuous batching, quantization, speculative decoding — decide whether it feels instant or sluggish, and whether it costs a fortune or a rounding error. This is how they work.

01

Why serving is a memory problem

An LLM writes one token at a time, and to produce each token it must read every one of its billions of weights out of GPU memory. The arithmetic per token is trivial next to that data movement — so generation is memory-bandwidth-bound, not compute-bound. The GPU's math units sit mostly idle, waiting on memory.

This one fact explains almost every serving optimization. If the bottleneck is moving data, then the wins come from moving less of it (quantization), reusing what you've moved (the KV cache), and amortizing the move across many requests (batching). Keep "it's memory, not math" in mind and the whole field makes sense.

→ Mental model

Reading the weights for one token is like driving to the warehouse to pick up a single item. The drive dominates — so you batch many orders into one trip, carry lighter boxes, and never re-fetch what's already in the truck.

02

Prefill vs decode — two very different phases

Every request has two phases with opposite characteristics, and serving systems treat them differently.

The two phases of generation

Prefill — read the prompt

Process the entire input prompt at once, in parallel. Compute-heavy, fast per token, done once. Produces the first token and fills the KV cache.

Decode — write the answer

Generate output tokens one at a time, each depending on the last. Memory-bound, slow, repeated once per output token. This is where most of the time goes.

Prefill is parallel and cheap; decode is sequential and dominates latency for long outputs.

The split matters for two metrics you'll live by: time to first token (TTFT) is dominated by prefill, while tokens per second after that is a decode property. A long prompt slows your first token; a long answer slows everything after it.

03

The KV cache — the thing that eats your memory

Attention lets each new token look back at every previous token — specifically at their Key and Value vectors. Recomputing those for the whole history at every step would be madness, so they're computed once and kept around: the KV cache. It's what makes decode fast.

The catch is size. The cache grows with every token, every layer, and every request in the batch — and it lives in the same precious GPU memory as the model weights. On long contexts and big batches, the KV cache, not the model, becomes the thing that runs you out of memory. Managing it well is the central problem of modern LLM serving.

→ Worth knowing

The KV cache is why context length is expensive to serve, not just to train: double the context and you roughly double the cache each request holds. It's also why FlashAttention's memory savings matter so much — see the FlashAttention breakdown.

04

Continuous batching — keep the GPU full

Because moving the weights is the cost, you want as many requests as possible sharing each trip — that's batching. But naive static batching waits for the whole batch to finish before starting the next, so one long request holds up a dozen short ones and the GPU idles.

Continuous batching (popularized by vLLM) fixes this: it adds and removes requests from the running batch at every token step. The instant one request finishes, a waiting one takes its slot — the GPU never stalls.

GPU utilization
Static batch
idle gaps
~45%
Continuous batch
near-full
~90%
Continuous batching can multiply throughput several times over on mixed-length traffic.

This is the single biggest throughput win in modern serving, and it's why open-source servers like vLLM became the default. It costs nothing in quality — the outputs are identical; you're just scheduling the GPU better.

05

PagedAttention — no wasted memory

Continuous batching creates a new problem: requests come and go, each with a KV cache that grows unpredictably. Allocating one big contiguous block per request wastes huge amounts of memory to fragmentation and over-provisioning.

PagedAttention borrows the operating-system idea of virtual memory. It chops the KV cache into small fixed-size blocks (pages) that don't have to be contiguous, and keeps a lookup table mapping each request's logical sequence to its scattered physical blocks. Memory is handed out a page at a time, exactly as needed — so almost none is wasted, and you can fit far more concurrent requests on the same GPU.

→ Key insight

PagedAttention is the trick that makes continuous batching practical at scale. Together they're why one GPU can serve many more simultaneous users than a naive implementation — the difference between renting one GPU and ten.

06

Quantization — carry lighter weights

Since serving is memory-bound, storing the model in lower precision is a direct speedup: smaller weights mean less data to move per token, plus more room for the KV cache. Quantization converts 16-bit float weights down to 8-bit or even 4-bit integers.

PrecisionRelative memorySpeedQuality
FP16 / BF16100%baselinefull
INT8~50%fasternear-full
INT4~25%fastestsmall, usually acceptable loss

Going to 4-bit can shrink a model to a quarter of its size, often letting it run on a single consumer GPU with only a modest quality dip. The art is choosing what to quantize and how — weights are easy, activations are trickier — to keep the loss below what your product can notice.

07

Speculative decoding — guess ahead, verify in parallel

Decode is slow because it's sequential — one token, then the next. Speculative decoding breaks the sequence with a bet. A small, fast draft model guesses several tokens ahead; then the big model checks all of them in a single forward pass. Verifying in parallel is cheap, so:

One big-model step

Draft model guesses

  • Small & fast, proposes 4–5 tokens
  • Cheap to run
  • Often right on easy tokens ("the", "of")

Big model verifies

  • Checks all guesses in one pass
  • Accepts the correct prefix for free
  • Rejects the rest, continues normally
When the draft is right, the big model emits several tokens in the time it used to emit one.

The crucial property: the output is exactly what the big model would have produced alone — verification guarantees it. You get lower latency with zero quality change, as long as the draft model is right often enough to pay for itself.

08

Latency vs throughput — the knob you're really turning

Every serving decision trades one against the other. Knowing which you're optimizing is half the job.

You want…Turn this upCost
Higher throughput (cheaper per token)Bigger batchesHigher latency per request
Lower latency (snappier)Smaller batches, speculative decodingLower GPU utilization / higher cost
Bigger model on the GPUQuantizationSmall quality loss
More concurrent usersPagedAttention + continuous batchingEngineering complexity

A chat UI optimizes for TTFT and streams tokens so the wait feels short; a bulk document-processing job optimizes for raw throughput and happily runs huge batches. The last lever is routing: send easy requests to a small cheap model and only escalate hard ones to the big model — the job of an LLM gateway.

→ Interview tip

When asked to "make the LLM faster," don't jump to a trick. First ask: is this latency-sensitive or throughput-sensitive? TTFT or tokens/sec? Prefill-bound or decode-bound? The right optimization falls out of the answer.

Frequently asked

Quick answers

Why is serving an LLM slow?

Generation is autoregressive and every token requires reading the whole model from GPU memory, so it's memory-bandwidth-bound, not compute-bound. The optimizations are all about moving less memory.

What is the KV cache?

Stored Key/Value vectors for every previous token so attention doesn't recompute them each step. It makes decode fast but grows with sequence length and batch size, dominating GPU memory.

What is continuous batching?

Adding and removing requests from the running batch every token step (vLLM), so a finished request is instantly replaced — keeping the GPU full and multiplying throughput.

What is quantization?

Storing weights in int8/int4 instead of 16-bit floats — less memory to move means faster generation, at a small, usually acceptable quality loss.

What is speculative decoding?

A small draft model guesses several tokens; the big model verifies them in one parallel pass. Correct guesses are free, cutting latency with no change to the output.

The LLM Serving Handbook · Vibe Engines · 2026
Finished this one? 0 / 29 Handbooks done

Explore the topic

See this alongside everything else on the same subject — handbooks, system designs, challenges and tools, in one place.