The useful part, up front

What you’ll take away

  • Cached autoregressive decoding reuses stored keys and values; the attention scores for a new query still have to be computed [1][3].
  • For an explicitly simplified full-prefix model, KV payload grows with retained token count and independent sequence count. Payload estimates exclude weights and allocation overhead [1][3].
  • Local or sparse attention changes model connectivity. It is not evidence that an arbitrary full-attention cache can safely drop old entries [2].
  • Paging concerns storage layout, offloading concerns placement, and quantization concerns representation. Supported combinations and actual performance require checking [1][3].
  • Use the worked numbers only as hypothetical arithmetic. The vLLM design reference is historical, and actual deployments need version-specific measurement [3].
01

The reader problem: the model stays the same, but the conversation does not

Imagine you open a chat and ask a short question. The assistant answers in a few sentences and the exchange ends. Now imagine a long conversation that continues for many turns, with the user adding details, correcting earlier statements, and asking the assistant to revise its answer. The underlying model has not been retrained and its weights have not changed, yet the system may need much more memory to continue. That extra memory is not a copy of the model. It is working state created for this particular conversation, and it grows as the conversation grows [1].

This distinction matters because people often picture an AI system as a single fixed object: load the model, ask a question, get an answer. In practice, generation also creates temporary data that depends on the exact prompt, the earlier turns, and the tokens already produced. A short exchange may need very little of this state. A long exchange may need a great deal, especially when several conversations are active at the same time. The cache is therefore best understood as a notebook for the current conversation, not as part of the model itself [1].

The practical question is not only whether the model fits on a device. It is also whether the cache for the current sequence fits alongside the model, the input, and any other active sequences. When it does not fit, the system may fail, slow down, move data elsewhere, or refuse to continue. Understanding that difference helps explain why two requests to the same model can behave very differently: one is short and isolated, while the other is long, detailed, and competing for memory with other work [1].

Scope matters here. This explanation uses a full-attention decoder that retains its processed prefix. Other attention patterns exist, and the later attention section explains why that qualification matters [2]. The vLLM reference used for tensor shapes and blocks explicitly labels itself a historical design document; it is useful for understanding the mechanism, but it does not describe the current vLLM implementation [3]. The numerical example below is our own hypothetical calculation, not a product specification or a measured result.

What the simplified KV-payload estimate counts. A dimensional model for a homogeneous full-prefix cache; padding, metadata and other memory are extra.
A dimensional model for a homogeneous full-prefix cache; padding, metadata and other memory are extra. · Ameer Journal — original explanatory diagramOriginal editorial illustration; no third-party artwork reused.
02

Autoregressive generation: one token at a time

Autoregressive generation means the model produces text one token at a time. A token may be a word, part of a word, punctuation, or another small unit of text. After producing one token, the model uses it, together with everything before it, to predict the next token. Then it repeats the process. This step-by-step method is simple to describe, but it creates a repeated question at every step: how should the new token relate to all the earlier tokens? [1]

Without any stored state, the model would have to recompute its internal representations of the earlier tokens again and again. Each new prediction depends on the previous tokens, so the same earlier material would be processed repeatedly as the answer grows longer [1]. That repeated work would waste time. It would also make long responses increasingly expensive, because the amount of earlier material to reprocess would keep increasing with every new token.

A cache offers a way to avoid some of that repetition. Instead of rebuilding everything from scratch for each token, the system can keep certain intermediate results from earlier steps and reuse them. The idea is similar to keeping notes while reading a long document. You do not reread every page from the beginning each time you want to answer a question about page three. You keep useful notes and return to them when needed. The KV cache plays an analogous role inside the model [1].

03

What keys and values actually are

Inside the model, each token is represented by numbers. Processing it produces several useful representations. A query can be thought of as the question the current position asks: which available information is relevant now? A key supplies numbers against which that query is compared. A value supplies numbers that contribute to the attention output according to the weight assigned to that position. These labels are an analogy for numerical operations, not a claim that the cache understands a question or stores a readable answer [3].

Queries and keys determine attention scores; the resulting attention weights determine how values are combined. It would be misleading to say that the cache simply stores the attention scores. A later token brings a different query, so its scores against earlier keys must be worked out for that step. The reusable part is the earlier keys and values themselves. The historical vLLM explanation separates its query-key calculation from the later value calculation, making this distinction visible [3].

A useful analogy is a library index. The key is like a label that helps the system find a relevant item quickly. The value is like the contents that are actually brought back once the item is found. The cache keeps both the labels and the contents for earlier tokens. That is why it is called a key-value cache: it stores the keys used for matching and the values used for retrieval, organized by token position and by layer [1].

Model parameters and runtime cache have different roles. Ordinary inference keeps model parameters fixed while an application manages compatible cache state.
Ordinary inference keeps model parameters fixed while an application manages compatible cache state. · Ameer Journal — original explanatory diagramOriginal editorial illustration; no third-party artwork reused.
04

Why cache memory grows with every token

The cache grows because each new token needs its own key and value entries in every layer. A short prompt creates a small set of entries. As the model generates more tokens, it adds more entries. The process is additive: token one adds a set, token two adds another set of the same size, token three adds another, and so on. After many tokens, the total is much larger than it was at the beginning, even though each individual addition was modest [1].

This growth is easy to underestimate because the per-token addition feels small. One token's worth of keys and values may seem negligible. But a long conversation contains thousands of tokens, and the model may have many layers. The total is the per-token size multiplied by the number of tokens and by the number of layers. That multiplication is what turns a small increment into a large memory requirement over a long sequence [1].

The same logic applies to the prompt itself. A long initial prompt already creates a large cache before generation begins. Generated tokens then extend it further. In a chat, the history of earlier turns is part of that growing sequence, so a conversation that has accumulated many turns carries a larger cache than a fresh conversation with a single short question. The cache therefore records the length of the current sequence in memory, not just its content [1].

There is an important boundary to this rule. Hugging Face's attention guide describes Longformer using small local windows, together with selected tokens that have global access. It also explains that stacking local-attention layers can let information travel beyond one small window [2]. This shows that models can use different patterns of communication between positions. It does not mean that deleting old entries from an ordinary full-attention model is an equivalent memory-saving switch. An attention pattern belongs to the model's design; a cache's allocation policy is a separate question. Check the model's actual rules before assuming every layer must keep the same amount of history.

05

Model weights versus cache state: two different kinds of memory

Model weights are the trained numbers that define how the model behaves. They are created during training and then loaded for inference. They do not change when a user asks a question, and they are shared by every conversation that uses the same model. If you load a model once, its weights stay in memory while many different prompts are processed. The weights are the model's long-term, learned behavior [1].

Cache state is different. It is created from a particular token sequence and is useful while that sequence, or a compatible shared prefix, is being continued. Two different prompts generally require different state even when they use the same model weights. An application can release a cache it no longer needs or deliberately retain a reusable prefix. The cache is working state for generation, while the weights are the trained foundation underneath it; a conversation ending does not itself prove that an application has immediately freed every cached allocation [1].

This difference explains a common surprise. A model may load successfully and answer a short prompt, yet run out of memory on a long one. The weights fit, but there is not enough remaining room for the longer request and its working state. Releasing an unneeded cache can make room for another request while the model remains loaded [1]. Treat that as an application decision: clearing the visible chat window is not evidence about what a server has retained or how its memory manager behaves.

06

A clearly hypothetical dimensional calculation

The following calculation is entirely hypothetical. It uses invented numbers to show how the pieces multiply together. It is not a measurement of any real model, and it should not be used to predict the speed or memory use of a specific product. The purpose is only to make the growth pattern concrete. Assume, purely for illustration, a model with 24 layers, 8 key-value heads per layer, a head dimension of 128, and 2 bytes per stored number. Assume also a sequence length of 1,000 tokens and a single active sequence [1][3].

Using the formula from the previous section, the cache size is 2 times 24 times 8 times 128 times 1,000 times 2 bytes. That equals 98,304,000 bytes, or about 94 mebibytes in this invented example. The arithmetic is straightforward: each token adds the same amount, and 1,000 tokens add that amount 1,000 times. If the sequence grew to 4,000 tokens under the same invented assumptions, the cache would be about four times larger, because the token count is four times larger [1][3].

Now change only the number of concurrent sequences. If 10 such hypothetical sequences were active at once, each with 1,000 tokens, the aggregate cache would be about 10 times the single-sequence figure. The model weights would not change at all. This illustrates why a serving system can run out of memory from many medium-length conversations even when no single conversation is extremely long. The hypothetical numbers are illustrative, but the multiplication pattern is the real lesson [1][3].

Dynamic and static cache allocation. Hugging Face describes a trade-off between changing shapes and reserved maximum capacity.
Hugging Face describes a trade-off between changing shapes and reserved maximum capacity. · Ameer Journal — original explanatory diagramOriginal editorial illustration; no third-party artwork reused.
07

Dynamic growth versus fixed-size allocation

The default DynamicCache described in Hugging Face Transformers grows dynamically as generation progresses. It starts small and adds space as new tokens arrive. This is flexible because the system does not need to know in advance how long the response will be. A short answer uses little space, and a long answer uses more. The trade-off is that the size is not known ahead of time, which can make some optimizations harder [1].

A fixed-size cache takes the opposite approach. It reserves a specific maximum amount of space up front and generates within that limit. Knowing the size in advance can make the computation more predictable and can help certain compiler optimizations. The trade-off is waste: if the actual sequence is much shorter than the reserved maximum, the unused portion still occupies memory, and tokens beyond the intended length may need to be masked so they do not affect attention [1].

Neither choice is universally better. Dynamic growth is natural when sequence lengths vary widely, because it avoids reserving a large buffer for every request. Fixed allocation can be attractive when many sequences have similar lengths, because the reserved size is likely to be used efficiently. The right choice depends on the workload, the hardware, and whether the system values flexibility or predictability more highly [1].

08

Paging: storing the cache in blocks instead of one large slab

Paging organizes cache data into blocks. The vLLM document in our references illustrates a historical design in which each key or value block holds a fixed number of token positions for a head. It explicitly warns that it no longer describes the code used by vLLM today [3]. Use it as a clear model of the idea: a long sequence can be represented by smaller storage units rather than understood only as one uninterrupted slab. The source's cache blocks are also different from GPU thread blocks, which organize executing threads.

A block has capacity, and its useful contents need not fill that capacity perfectly. For a simple invented packing example, suppose a block can hold 16 token positions and one sequence needs 17. If that sequence alone occupies its blocks, it needs two blocks, leaving some capacity unused in the second. That is an illustration of rounding up to whole blocks, not a measurement of a serving system. The reference defines a fixed token count per block; the packing arithmetic follows from that definition [3].

Blocks do not make the retained keys and values disappear. The computation still needs to locate the right block, head and token offset. The historical document shows those pieces in the address calculation for reading a key [3]. Organizing data this way changes its layout and allocation granularity. How a current server allocates, shares, frees or schedules those blocks depends on its implementation. This explanation promises no particular speed-up or memory-saving percentage.

A historical paged-cache address uses several indices. The vLLM historical example combines a physical block number, KV-head index and token offset to find key data.
The vLLM historical example combines a physical block number, KV-head index and token offset to find key data. · Ameer Journal — original explanatory diagramOriginal editorial illustration; no third-party artwork reused.
09

Offloading and quantization: moving or shrinking the cache

Offloading changes where cache data is kept. The Hugging Face cache guide describes keeping most layers' caches in CPU memory, bringing the current layer's working cache to the GPU and prefetching the next layer. The processed cache is moved back as computation advances. This can reduce the cache's GPU-memory demand, but transfers still take work, and the guide warns that generation throughput can decrease depending on the model and generation settings [1]. It is a capacity trade-off to assess, not free extra GPU memory.

Quantization changes how cache numbers are represented. The guide describes lower-precision cache storage as another way to reduce memory requirements. It also warns that cache quantization can harm latency when context is short and there is already enough GPU memory [1]. Therefore, saving bytes does not by itself prove that a particular conversation will finish faster. The retrieved guide provides no quality measurement for our hypothetical model, so no numerical accuracy or quality promise follows from this explanation.

Keep the choices separate when comparing systems. Paging concerns block layout, offloading concerns device placement, and quantization concerns numerical representation. That distinction does not mean every library supports every combination. The guide explicitly describes offloading for its DynamicCache and StaticCache classes; verify the chosen model, cache class and software version before assuming that another combination works [1]. For an ordinary full-prefix cache, retaining more token positions still adds logical entries even if their placement or representation changes.

10

Limits, edge cases, and a practical checklist

Several edge cases deserve attention. A very long prompt can create substantial cache state before the first generated answer token, and multiple active sequences add to demand. Generation choices such as beam count also affect memory and offloading throughput; the cache guide includes a multi-beam example that retries after an out-of-memory error [1]. Do not assume a single short request represents multi-user operation. Conversely, do not assume every candidate duplicates every prefix: that depends on how the implementation manages shared or copied state.

Another edge case is the end of a sequence. When a conversation ends, its cache should be released so that memory can be reused. If caches are retained longer than necessary, memory can fill with stale state from finished sequences. Conversely, if a system needs to resume a conversation, it may need to retain or reconstruct the cache. The decision to keep, discard, or rebuild cache state is part of managing the overall memory budget [1].

A practical checklist can help. First, estimate the cache size for the longest expected sequence, not just the average. Second, account for the number of concurrent sequences. Third, decide whether dynamic growth, fixed allocation, paging, offloading, or quantization fits the workload. Fourth, test with long prompts and multiple simultaneous requests, not only with short examples. Finally, monitor memory use during generation, because the cache grows over time and peak usage may occur near the end of a long response [1].

Cache offloading moves state as layers are processed. A conceptual transfer sequence from the cache guide; it does not specify exact peak device memory.
A conceptual transfer sequence from the cache guide; it does not specify exact peak device memory. · Ameer Journal — original explanatory diagramOriginal editorial illustration; no third-party artwork reused.
Follow the evidence

Sources & further reading

Explore the references behind this guide. External pages may change after our review.

  1. Cache strategies · Hugging Face
    Hugging Face · Accessed 6 Nov 2026
  2. Attention mechanisms · Hugging Face
    Hugging Face · Accessed 6 Nov 2026
  3. Paged Attention - vLLM
    vLLM · Accessed 6 Nov 2026

Article updated 6 Nov 2026.

Found something we should revisit?

Good explanations get better with thoughtful feedback.

Suggest a correction