Explainer
RedKnot, explained: most attention heads can reuse their cache
Long prompts are slow because every attention head re-reads every token. Most heads only look nearby, so most of that work can be reused.
TL;DR
Language models have many attention heads. We found that only a small share of them (about 3–17%) need to read the whole prompt. The rest look at the start and at the last few hundred tokens.
RedKnot recomputes the few heads that need the whole prompt and reuses cached work for all the others. The first token arrives 1.6–5.2× sooner, one GPU holds 4.7–7.8× more sessions, and answers stay close to full recomputation (on some long-context tests they get better). No retraining is needed.
Why long prompts are slow
Today's LLM apps send very long prompts. A RAG system pastes in dozens of retrieved documents. A coding agent includes files, tool outputs, and earlier steps. Prompts of 10K to 100K+ tokens are common.
Before the model can write its first word, it has to read the whole prompt. This step is called prefill, and the wait it causes is the time to first token (TTFT). For example, prefill of a 64K-token prompt on Llama-3.3-70B with 4 GPUs takes about a minute.
While it reads, the model writes notes about every token, called the KV cache. A natural fix is to save these notes and reuse them. Today's engines do this with prefix caching, but it only works when a new prompt starts with exactly the same text as an old one.
Reused documents rarely sit at the same place in the prompt
Two RAG requests that share Doc B. A prefix cache can only reuse the part before the first difference.
So there is a lot of work to save, if we can reuse a document's cache wherever it appears. This is called position-independent caching. The catch is that each document's cache was computed alone, without seeing the text that now comes before it. The cached notes are slightly wrong, and something has to repair them.
Why fixing tokens one by one falls short
Earlier systems (for example CacheBlend and ProphetKV) repair the cache by picking a small set of tokens and recomputing them. The idea makes sense: if only a few tokens matter, fix those.
The problem is that a model has many attention heads, and each head cares about different tokens. A token-level fix recomputes a token for all heads at once, so it has to cover every token that any head cares about. Try it:
Each head cares about different tokens
Each row is one attention head and each column is one token. Red cells are the tokens that head needs fixed.
In real models the effect is strong. In shallow layers, the union of tokens that matter to some head covers nearly every token. A token-level method then has two bad options. It can recompute almost everything and lose the speedup, or recompute too little and leave errors in some heads. Those errors also spread: a token recomputed on top of stale neighbors is still slightly wrong.
Insight 1: heads have different jobs
So we stopped asking "which tokens?" and asked "which heads?" When we tested heads across five very different models, we found two kinds:
- Global heads look across the whole prompt. Their output changes when the text before a document changes.
- Local heads look at a few tokens at the very start (the "sink") and a short recent window. Text far away barely affects them.
Most attention heads are local
Share of KV heads in each model that are local (reusable) vs. global (must be recomputed). Found with needle-in-a-haystack tests.
That gives RedKnot's main rule. For each reused document:
- Global heads are recomputed in full. They are few, so this is cheap, and they are exactly the heads that the new context changes.
- Local heads reuse the cache. We only refresh what they can actually see: the sink tokens plus a short window before each token.
For example, with a window of w = 256, token 1000 of a local head only needs tokens 744–1000 and the sink. Everything else is reused.
One more detail: a reused document has moved to a new position. Modern LLMs encode position as a rotation (RoPE), so moving a document just means rotating its cached keys by the difference. This step is exact and cheap:
RedKnot is also careful about where it saves work. Shallow layers are sensitive, and errors there spread to every later layer, so they stay close to dense. Deep layers are more selective, so that is where most of the reuse happens.
Insight 2: attention is not the only cost
Each transformer layer has two parts: attention, where tokens look at each other, and the feed-forward network (FFN), which processes each token on its own. Caching only helps attention. But how much of prefill time does attention take?
The FFN takes most of the prefill time
Share of prefill time spent in the FFN, at a short and a long prompt.
So even a perfect attention cache leaves more than half the time on the table. RedKnot uses the attention it just computed as a signal for which tokens matter. In deep layers, only those tokens go through the FFN. The others skip it and pass through the layer's residual connection unchanged.
Insight 3: savings must show up in memory
The last problem is less obvious. Standard engines (PagedAttention) store the KV cache in blocks of tokens, with all heads packed together. To tell a local head to skip most tokens, you have to add a mask. On GPUs, a mask turns off the fastest attention kernel (FlashAttention), and the masked path is 4.9–7.6× slower. The math is saved on paper, but the kernel still runs on the slow path.
RedKnot's SegPagedAttention stores the cache per head. A global head keeps pages for the whole prompt. A local head keeps pages only for its sink and window. No mask is needed, and every head stays on the fast path. It also means local heads use far less GPU memory, so more requests fit at once.
Per-head storage keeps attention fast as prompts grow
Time for attention prefill over 64 layers (shaped like Qwen3-32B). Lower is better.
The same idea on DeepSeek-V4
DeepSeek models use multi-head latent attention (MLA). Instead of one cache per head, all heads share one compressed cache, so the per-head cache that RedKnot splits does not exist. Splitting it by force would undo MLA's memory savings.
RedKnot-MLA splits the heads logically instead. DeepSeek-V4 groups its heads in sets of 8. In each group, 1 head stays global and is recomputed for the request, and 7 heads are local and reused. Each document is processed once offline, starting at position 0. At request time we rotate the query to the document's position instead of rewriting the cache. The two parts are then added together before the layer's shared output projection:
When the cached part is exactly what full recomputation would give, this sum is exact. Any error comes only from local heads now sitting in a new context. Global heads and a small set of protected tokens (the query, the edges of each document, and tokens DeepSeek's own indexer marks as important) correct it.
How much work can this skip? On DeepSeek-V4-Flash, 37 of 43 layers are reusable and 56 of 64 heads per layer are local:
Results
Every number below compares RedKnot with recomputing the whole prompt on the same model, the same GPUs, and the same input tokens. Speedup means time with full recomputation ÷ time with RedKnot, so 1× means no gain and 3× means the first token arrives in a third of the time.
Faster first token than token-level methods
TTFT speedup on three dense models
Higher is better. Each group is one model, dataset, and prompt length. The dashed line at 1× is full recomputation.
…while staying much closer to the original answer
Does the model still predict the same next token?
How often each method agrees with full recomputation on the first generated token. Higher is better; 1.0 = always the same.
DeepSeek-V4-Flash: long contexts, up to 440K tokens
RedKnot-MLA TTFT speedup on DeepSeek-V4-Flash (8× H200)
Higher is better. Cached documents are already built ("hot"), which is the normal case when documents are reused. The dashed line at 1× is full recomputation.
Answer quality at 256K tokens on DeepSeek-V4-Flash
Change in F1 score (answer word overlap) vs. full recomputation, in percentage points. Right of zero = RedKnot-MLA is better.
More users per GPU
Concurrent sessions that fit in one GPU's memory
Higher is better. Standard dense KV storage vs. RedKnot with per-head SegPagedAttention.
Why it can beat full recomputation
Some results above beat the baseline. That sounds odd for a method that skips work, but there is a reason. As prompts grow, attention focuses on fewer tokens, and the rest acts like noise. Full recomputation lets that noise into every layer. RedKnot's sparse steps keep the tokens and heads that carry the signal. On Qwen3.5-397B and DeepSeek-V4-Flash, full recomputation loses accuracy as context grows, while RedKnot stays steady and overtakes it at long context.
Like the idea? Cite us and build with us.
If RedKnot is useful for your research or product, please cite our papers. It helps the project and the people who build it.
RedKnot is fully open source (Apache-2.0) and belongs to its contributors. We would love your help:
- Try it: one command reproduces the DeepSeek-V4-Flash results.
- Open an issue: bug reports, questions, and requests for the next model to support are all welcome.
- Send a pull request: there is open work on hybrid models (Qwen3.5 → Qwen4, GLM-5.3), DeepSeek-V4-Pro, the vLLM port, and the Ascend NPU port.
Meaningful contributions earn a bigger voice in the community.
@article{liu2026redknot,
title = {RedKnot: Efficient Long-Context LLM Serving with Head-Aware KV Reuse and SegPagedAttention},
author = {Liu, Yang and Luo, Zhaokai and Jin, Huayi and Wang, Zhiyong and He, Ruozhou and Wang, Boyu and Chen, Guanjie and Liu, Yifei and Xie, Tao and Hu, Junhao},
journal = {arXiv preprint arXiv:2606.06256},
year = {2026}
}
@article{liu2026redknotmla,
title = {RedKnot-MLA: Multi-Head Offline-Online Reuse for DeepSeek-V4 Long-Context Serving},
author = {Liu, Yang and Luo, Zhaokai and Jin, Huayi and He, Ruozhou and Hong, Chenchen and Ma, Mingxiao and Zhang, Biao and Wang, Zhiyong and Wang, Boyu and Chen, Guanjie and Liu, Yifei and Xie, Tao and Hu, Junhao},
journal = {arXiv preprint arXiv:2609.07008},
year = {2026}
}