Context Engineering: Memory, Compaction and the KV Budget
The thing that stops a local agent is almost never the model’s ability. It is that the transcript grew, the key-value cache grew with it, and the machine ran out of memory or the turns got slow enough that you stopped waiting.
By the end of this lesson you will be able to compute what a token of context costs for each of this course’s reference models, trace how a transcript grows over a realistic task, choose a context length for your memory tier before you start rather than after it fails, and apply the four techniques that keep the budget under control: compaction, notes outside the window, retrieval, and prefix caching.
What a token of context costs
Section titled “What a token of context costs”Part 4 derived the formula: bytes per token equals layers times key-value heads times head dimension times two tensors times bytes per element. The course model reference records the result for each model, so the arithmetic is a multiplication.
| Model | Layers | KV heads | Head dim | Bytes per token at 16-bit |
|---|---|---|---|---|
| Qwen3-4B and Qwen3-8B | 36 | 8 | 128 | 147,456 |
| Qwen3-14B | 40 | 8 | 128 | 163,840 |
| Qwen3-30B-A3B and Qwen3-Coder-30B-A3B | 48 | 4 | 128 | 98,304 |
| gpt-oss-20b | 24 | 8 | 64 | 49,152 |
Multiply by the context length and you have the cache. In gigabytes of 109 bytes, from the same figures:
| Model | 8k | 32k | 64k | 128k | 256k |
|---|---|---|---|---|---|
| Qwen3-4B, Qwen3-8B | 1.21 | 4.83 | 9.66 | 19.33 | 38.65 |
| Qwen3-14B | 1.34 | 5.37 | 10.74 | 21.47 | 42.95 |
| Qwen3-30B-A3B, Qwen3-Coder | 0.81 | 3.22 | 6.44 | 12.88 | 25.77 |
| gpt-oss-20b | 0.40 | 1.61 | 3.22 | 6.44 | 12.88 |
Two things fall out of that table immediately.
The mixture-of-experts models are cheaper per token of context than the dense 8B. Qwen3-30B-A3B has four key-value heads where Qwen3-8B has eight, so it costs two thirds as much per token despite being nearly four times the size. For an agent, where context is the scarce resource, that changes which model you want on a given machine.
A long context can cost more than the weights. Qwen3-8B at Q4_K_M is a 5.0 GB file. Its cache at 128k tokens is nearly four times that.
Qwen3-8B at Q4_K_M with a 128k agent context, on a 32 GB machine
- Weights, Q4_K_M
- 5 GB
- KV cache, 131,072 tokens at 16-bit
- 19.3 GB
- Engine buffers and activations
- 1.5 GB
- Free
- 6.2 GB
- Total
- 32 GB
Qwen3-Coder-30B-A3B at Q4_K_M with a 64k agent context, on a 32 GB machine
- Weights, Q4_K_M
- 18.6 GB
- KV cache, 65,536 tokens at 16-bit
- 6.4 GB
- Engine buffers and activations
- 2 GB
- Free
- 5.0 GB
- Total
- 32 GB
How a transcript actually grows
Section titled “How a transcript actually grows”Abstract growth is easy to ignore. Here is a concrete eight-message trace of a five-turn task, with plausible token counts for a coding-ish job on a small repository.
| After | Added | Transcript tokens | Prefilled this turn |
|---|---|---|---|
| System prompt and four tool schemas | 900 | 900 | — |
| The task | 60 | 960 | 960 |
| Turn 1: call, then a search result | 40 + 700 | 1,700 | 1,700 |
| Turn 2: call, then a directory listing | 40 + 1,200 | 2,940 | 2,940 |
| Turn 3: call, then a file read | 40 + 2,400 | 5,380 | 5,380 |
| Turn 4: call, then a test summary | 40 + 300 | 5,720 | 5,720 |
| Turn 5: the answer | 250 | 5,970 | — |
The transcript ends at under six thousand tokens, which sounds harmless. But look at the last column: the model prefilled 16,700 tokens over the task, for 5,970 tokens of distinct content. Every turn re-reads everything before it. That is quadratic in the number of turns, and it is why an agent that feels fine at turn three feels broken at turn fifteen.
Three separate costs come out of the same growth, and they are worth naming separately because they have different fixes:
- Prefill time, which is the re-reading above, and which prefix caching removes almost entirely.
- Cache memory, which is the transcript length times bytes per token, and which only compaction, retrieval or a quantised cache reduce.
- Attention, which nothing reduces except having less in the window. Anthropic’s context-engineering post names this directly, describing “context rot”: “as the number of tokens in the context window increases, the model’s ability to accurately recall information from that context decreases”, because models have “an ‘attention budget’ that they draw on when parsing large volumes of context”.
Four ways to keep it affordable
Section titled “Four ways to keep it affordable”Compaction
Section titled “Compaction”Anthropic’s post defines it as “the practice of taking a conversation nearing the context window limit, summarizing its contents, and reinitiating a new context window with the summary”. In an agent loop that means: when the transcript passes a threshold you choose, ask the model to write a short summary of what has been done and learnt so far, then start the next turn with the system prompt, the task, that summary, and the last one or two observations.
What to keep in the summary, in order of importance: the task as originally stated, decisions already made and why, facts discovered that are not re-derivable, files or identifiers touched, and what remains. What to drop: everything the agent read in full, every failed attempt whose lesson is already in the summary, and all reasoning text.
The threshold is a policy, not a constant. A reasonable starting point is to compact at about half the context length, because the summary turn itself needs room and because the second half of a window is where recall falls off fastest.
Notes outside the window
Section titled “Notes outside the window”Compaction is lossy by design. The complement is what the post calls structured note-taking, where
the agent “regularly writes notes persisted to memory outside of the context window” and pulls them
back “at later times”. Concretely, that is a write_note tool and a read_note tool over one
scratch directory. The agent writes what it found; the transcript keeps one line saying a note
exists; the content comes back only when it is needed.
This is the same idea as the post’s just-in-time approach, where agents “maintain lightweight identifiers (file paths, stored queries, web links, etc.) and use these references to dynamically load data into context at runtime using tools”. A file path is a dozen tokens. The file is two thousand.
Retrieval as memory
Section titled “Retrieval as memory”Part 10 built a document index with embeddings, a reranker and a query interface. In an agent that index is long-term memory: instead of putting the corpus in the context, the agent asks a question and gets back the three passages that answer it. The first lab’s third tool is exactly this, pointed at the Part 10 index if you built it and at a plain-text search if you did not.
The trade is worth stating plainly. Retrieval keeps the window small and puts a recall problem in its place: if the passage is not retrieved, the agent does not know it. That is a failure you can measure with the evaluation harness from Part 10, which is more than can be said for a fact lost somewhere in the middle of a hundred thousand tokens.
Prefix caching
Section titled “Prefix caching”Part 17 showed that a prefix cache reuses key and value vectors for a shared token prefix, exactly and without changing the output, but only from position zero and only on an identical prefix. An agent transcript is the ideal shape for it, because every turn is the previous turn plus an appendix.
Which makes the arrangement rules from that lesson load-bearing here. Four of them apply directly to a loop:
- Nothing variable at the top. A timestamp, a session id or a turn counter in the system prompt invalidates the entire cache on every single turn. This is the most common way an agent loses its cache, and the symptom is that every turn feels like the first one.
- A stable tool order. Serialise the tool list once and reuse the string. The MCP specification makes the same point from the server side, recommending that servers return tools deterministically because it “improves LLM prompt cache hit rates when tools are included in model context”.
- Append, never rewrite. Editing an earlier message, even to fix whitespace, discards the cache from that point on. Compaction deliberately breaks the prefix, which is one more reason to compact rarely rather than continuously.
- Stable retrieval ordering. If the same three passages come back in a different order, nothing matches.
With prefix caching working, the trace above costs about 5,970 tokens of prefill across the whole task instead of 16,700. Without it, you pay the whole transcript on every turn.
Choosing a context length for your track
Section titled “Choosing a context length for your track”Pick the number before you start, from your memory tier, the model you are serving and the length of task you intend to run. The table below is a starting point computed from the bytes-per-token figures above, leaving room for weights and an allowance for the engine and the rest of the machine.
| Tier | A reasonable agent model | Context to ask for | Why |
|---|---|---|---|
| 8 GB | Qwen3-4B at Q4_K_M | 16k | 2.4 GB of cache on top of 2.5 GB of weights; compaction will be frequent, so build it in from the start |
| 12–16 GB | Qwen3-8B at Q4_K_M | 32k | 4.8 GB of cache on top of 5.0 GB of weights; enough for a ten-turn task without compacting |
| 24 GB | Qwen3-8B at Q8_0, or gpt-oss-20b | 64k | Cheap cache on gpt-oss makes a long agent window affordable at this tier |
| 32 GB | Qwen3-Coder-30B-A3B at Q4_K_M | 64k | Four key-value heads keep the cache to 6.4 GB beside 18.6 GB of weights |
| 64 GB and up | Qwen3-Coder-30B-A3B at Q4_K_M or Q8_0 | 128k | Room for long file reads without compacting mid-task |
Two caveats. The context length you ask the engine for is not the model’s trained context window: Qwen3-8B’s card gives a native 32,768 tokens extensible to 131,072 with YaRN, while Qwen3-Coder-30B-A3B’s card gives 262,144 natively. Asking for more than the native window without the documented scaling is asking for degraded behaviour, not more memory. And a longer window that you actually fill is slower on every turn, so the right size is the smallest one your task fits in.
Preserve decisions and evidence when compacting
Section titled “Preserve decisions and evidence when compacting”Compaction is a lossy transformation of the conversation. Define what must survive: the user’s objective, constraints, authorised actions, current files or task state, unresolved questions and references to evidence. Long tool outputs can be replaced with summaries and stable paths, but a summary must not invent success for a step that failed.
Create a small test conversation with a changed requirement, a denied action and a partially completed task. Compact it, then ask the agent to continue. Check that it follows the latest requirement, preserves the denial and resumes from the actual state. Compare against continuation with the original context.
Store authoritative state outside prose where possible: task status, operation IDs and file hashes are easier to validate as structured records. Retrieved material and earlier model guesses should retain their provenance rather than becoming trusted instructions through summarisation. Context management is successful when the next action remains correct after the transformation, not merely when the token count becomes smaller.
A token of context costs layers times key-value heads times head dimension times two tensors times bytes per element, which is 147,456 bytes for Qwen3-8B at 16-bit and 98,304 for the 30B mixture-of-experts models, so the larger model is the cheaper one to give a long window to. An agent transcript grows by an observation per turn and is re-read in full on every turn, which costs prefill time quadratically, cache memory linearly, and attention in a way nothing but a smaller window fixes. Compaction replaces the history with a summary when it passes a threshold; notes and retrieval keep material outside the window and fetch it by name; prefix caching removes the re-reading entirely, provided nothing at the top of the prompt varies and the tool list is serialised in a stable order. Choose the context length from your memory tier before you start, keep it as small as the task allows, and remember that asking the engine for more than the model’s native window is not the same as the model being able to use it.
Check your understanding
Sources for this lesson
6 verified · checked 2026-09-09
- 01Anthropic — Effective context engineering for AI agents§ Context as a finite resource; compaction; note-taking; just-in-time retrieval; tool designanthropic.com/engineering/effective-context-engineering-for-ai-agents2026-09-09
- 02Qwen3-8B model card§ Context length; YaRNhuggingface.co/Qwen/Qwen3-8B2026-09-09
- 03Qwen3-Coder-30B-A3B-Instruct model card§ Context lengthhuggingface.co/Qwen/Qwen3-Coder-30B-A3B-Instruct2026-09-09
- 04llama.cpp — llama-server README§ --ctx-size; --cache-type-k and --cache-type-v; --cache-promptgithub.com/ggml-org/llama.cpp/blob/master/tools/server/README.md2026-09-09
- 05vLLM — Automatic Prefix Caching (usage)§ Multi-round conversation; limitsdocs.vllm.ai/en/latest/features/automatic_prefix_caching2026-09-09
- 06Model Context Protocol — Tools§ Deterministic ordering of tools/listmodelcontextprotocol.io/specification/2026-07-28/server/tools2026-09-09
Every technical claim on this page was checked against the official documentation of the tool, vendor or model publisher on the date shown, at the version pinned for the course. Where the course disagrees with folklore, the source is how you can tell which one to trust.