Skip to content
GenAI Learn/LLM Inference Internals
Browsing as a guest. Sign in to save your progress and earn XP as you complete chapters.

The KV Cache & Memory Math

5 min read

You'll learn to

  • -Explain what the KV cache stores and why it exists
  • -Compute the KV cache size per token from layers, KV heads, and head size
  • -Estimate how many concurrent sequences a GPU can hold
  • -Explain what grouped-query attention and PagedAttention each save

Weights are the part of an LLM's memory footprint that everyone knows about. The part that actually limits how many users you can serve is another one: the KV cache. This chapter shows what it is and how to calculate it on the back of an envelope, which is a question that comes up in nearly every serving interview.

An Analogy: The Meeting Note-Taker

Imagine a note-taker at a long meeting. Each time someone speaks, the note-taker writes down the key points of that statement. When a new question arrives, they answer it by looking over their notes, not by replaying the entire recording. The notes take space, and the longer the meeting, the more space. The KV cache is that set of notes.

What Is Cached

In attention, every new token compares itself with all earlier tokens, using a key and a value that each earlier token produced at each layer. Those keys and values for old tokens never change. Recomputing them on every step would repeat a huge amount of work, so the server stores them. Prefill fills the cache for the prompt, and each decode step adds one more entry to it, per layer.

How Big Is It?

KV cache bytes for one token
2 × layers × KV heads × head size × bytes per value
The 2 is for keys and values. Multiply by the number of tokens in the sequence for one request's cache.

The Llama 3 paper lists 8 key-value heads for its 8B and 70B models, even though they have 32 and 64 query heads. Sharing a KV head among several query heads is called grouped-query attention, and it shrinks the cache. The 8B model has 32 layers and the 70B model has 80, both with a head size of 128. With 16-bit values, 2 bytes each, that gives 2 × 32 × 8 × 128 × 2 = 131,072 bytes, or 128 KiB, per token for the 8B model, and 320 KiB per token for the 70B model.

The code turns that into capacity. It takes an 8B model on one 80 GB GPU and a 70B model on four, keeps 10% of memory free, subtracts the weights, and divides what is left by the KV cache of one sequence at different context lengths. Press Run and read the last column, then the final line.

Press Run: context length, not weights, decides how many users fit on a GPU

On one GPU, the 8B model has about 56 GB left after its 16 GB of weights. At a context of 8,192 tokens, one sequence needs 1.07 GB, so about 52 fit. Stretch the context to 32,768 tokens and only 13 fit. At 131,072 tokens, just 3. The 70B model on four GPUs has 147 GB free and shows the same pattern: 54 sequences at 8,192 tokens, 3 at 131,072. The last line shows why grouped-query attention matters. Without it, the 70B model would need 2,560 KiB per token, eight times more, and its capacity would shrink to a fraction.

Use the demo below to try other models and settings. Change the context length, the number of GPUs, or how the numbers are stored, and see how many conversations fit once the weights are loaded.

How Many Conversations Fit on the GPUs?

The KV cache grows with every token of context and with every user. Choose a model, how many GPUs it runs on, how its numbers are stored, and the context length, and see how many users fit.

Model

Weights stored as

KV cache stored as

1
8,192 tokens

KV cache per token

128 KiB

8 KV heads

One conversation

1.07 GB

8,192 tokens

Left after weights

56 GB

weights 16 GB

Fit at once

52

conversations

Grey: weights. Blue: KV cache for the conversations that fit. The rest is the 10% reserve and any remainder.

After 16 GB of weights, about 56 GB is left. One 8,192-token conversation needs 1.07 GB of KV cache, so 52 fit at once. Context length, not the weights, decides how many users share the GPUs.

What Fills the Rest of Memory

  • -Weights: fixed, and the first thing you subtract.
  • -KV cache: grows with every token of every active request, so it varies with load and context length.
  • -Activations and overhead: temporary buffers, kept as a margin of safety.

PagedAttention and Quantizing the Cache

A simple server reserves one large contiguous block per request, sized for the longest possible answer. Most requests use far less, so most of the reservation is wasted, and memory fragments. The vLLM paper by Kwon and colleagues proposed PagedAttention, which stores the cache in small fixed-size pages, like an operating system does with memory, so nothing is reserved ahead of need and pages can be shared. They report 2 to 4 times higher throughput than earlier systems at the same latency. The earlier chapter on serving covers this in more detail, and the chapter on quantization shows how to shrink the cache itself by storing keys and values in fewer bits.

When someone asks how many users one GPU can serve, do not start with weights. Start with this chain: free memory after weights, divided by KV cache per sequence, gives the number of concurrent requests. Then ask what the context length is.

Interview Signal is part of Pro

See a real weak answer next to a real strong one for this exact topic.

Quiz is part of Pro

Test what you just read with a short quiz, and bank the XP.

Discussion0

Join the Discussion

Sign in to leave comments, reply to others, or like insights.

Sign In to ScaleDojo

No comments yet. Be the first to start the thread!