Context Engineering: Why Compaction Is the Wrong First Lever
TL;DR
Context editing and compaction are both server-side API features. On the Claude API you get clear_tool_uses_20250919 behind the context-management-2025-06-27 beta header, which defaults to firing at 100,000 input tokens and keeping the last 3 tool uses, and compact_20260112 behind compact-2026-01-12, which summarises server-side from a 50,000-token minimum trigger. Reach for the clearing strategy before the summarising one, and for either before you write a summariser yourself. Anthropic's own long-running-agent team went further than either: their harness uses full context resets between sessions rather than in-place compaction, because compaction produces what they call context anxiety — models wrapping up prematurely near their perceived limit (Anthropic Labs, 24 March 2026). The measured case for pruning is stronger than the case for summarising alone. On a 50-task hotel expense benchmark running GPT-5, full conversation history scored 71.0% task completion on 1,480,996 tokens over 14.56 hours; pruning to the last five tool interactions scored 79.0% on 535,274 tokens in 5.39 hours; pruning plus automated summarisation scored 91.6% on 553,374 tokens (arXiv 2606.10209, 8 June 2026). More context made the agent both slower and worse. The first lever is not compressing tokens after the fact. It is never admitting them.
Context Editing vs Compaction on the Claude API: Which One to Use
Context editing is a server-side feature of the Messages API. You send the full, unmodified conversation. The server decides what to strip out before inference and tells you what it removed. Your client keeps the complete history on disk, untouched. Two clearing strategies are documented: clear_tool_uses_20250919 and clear_thinking_20251015, both behind the context-management-2025-06-27 beta header. The same context_management parameter also carries compact_20260112, the server-side summariser, behind its own compact-2026-01-12 header (context editing docs↗).
Compaction summarises the conversation so far and continues from the summary. It used to be a client-side pattern you wrote yourself. Since 12 January 2026 it is also a server-side API feature: the compact_20260112 edit in context_management, behind the compact-2026-01-12 beta header, with a 50,000 input-token minimum trigger and a 150,000-token default (compaction docs↗). Anthropic's own docs call it "the recommended strategy for managing context in long-running conversations and agentic workflows. It handles context management automatically, without client-side summarization code." The Python SDK v1.0, released 20 August 2026, removed the client-side compaction_control argument from the tool runner in favour of that server-side path.
So the practical answer to "context editing or compaction" is: start with context editing. Both are server-side and cheap to turn on now, but only one of them leaves your history intact. Reach for compaction when the reset boundary cannot fall where a session boundary falls.
Most posts treat context management as one decision. It is four, and they are not equally valuable:
| Lever | What it removes | Cost to adopt | Typical saving |
|---|---|---|---|
| Tool definition deferral | Definitions you never call | One flag per toolset | Over 85% of definition tokens |
| Large-result spill to file | Tool output bodies | Automatic on the platform | Everything above ~25K tokens per result |
| Server-side context editing | Old tool results, old thinking | One config block | Bounded by your trigger |
| Compaction | Everything, lossily | One beta header and a trigger, server-side | Whatever you dare throw away |
Work down that list, not up it. Every team I have seen struggle started at the bottom.
The Failure Compaction Causes Has a Name: Context Anxiety
Anthropic's engineering post on harness design for long-running application development↗ (Prithvi Rajasekaran, Anthropic Labs, dated 24 March 2026 on the engineering blog index) is the only primary source I have found that states the tradeoff plainly. Their harness does not compact. It resets.
The stated reason, verbatim: "Some models also exhibit 'context anxiety,' in which they begin wrapping up work prematurely as they approach what they believe is their context limit." The fix is not summarising in place: "Context resets—clearing the context window entirely and starting a fresh agent, combined with a structured handoff that carries the previous agent's state and the next steps—addresses both these issues." And on why compaction is not the same thing: "While compaction preserves continuity, it doesn't give the agent a clean slate, which means context anxiety can still persist."
That failure mode is not the one people expect. The usual worry with a long context is that the model forgets something. Context anxiety is the opposite. The model still remembers — it can see how full the window is, and it starts behaving like someone with ten minutes left in an exam. It stops opening new threads. It declares the task finished.
In-place compaction makes that worse, because after compaction the model still sits in a window that reads as the continuation of something long. A fresh session with a handoff document reads as the beginning of work.
The same post gives the economics of the harness around it. A retro game maker built by a single agent with no harness took 20 minutes and $9 and produced broken gameplay. The same brief through the full generator/evaluator harness took 6 hours and $200 and shipped working mechanics. A DAW built with Opus 4.6 broke down across three build-and-QA rounds as: planner 4.7 minutes and $0.46, build 3 hours 20 minutes and $113.85, QA 25 minutes and $10.39 — total 3 hours 50 minutes and $124.70.
The line I keep coming back to in architecture reviews: "Every component in a harness encodes an assumption about what the model can't do on its own." A compaction layer assumes the model cannot start fresh. Check that is still true before you keep paying for it. Anthropic dropped the sprint decomposition Opus 4.5 needed once they moved to Opus 4.6.
The Measurement: Pruning Plus Summarisation Beat Full History by 20.6 Points on 63% Fewer Tokens
The strongest published number here is Less Context, Better Agents↗ (Lodha, Varnosfaderani, Chakraborty and Mithal, arXiv 2606.10209, 8 June 2026). GPT-5, a 50-task hotel expense benchmark, three context policies.
| Policy | Task completion | Total tokens | Wall clock |
|---|---|---|---|
| Full conversation history | 71.0% | 1,480,996 | 14.56 hrs |
| Pruned to last 5 tool interactions | 79.0% | 535,274 | 5.39 hrs |
| Pruned plus automated summarisation | 91.6% | 553,374 | 5.79 hrs |
The completion column is the paper's "complete itemization" rate. On the pruned-plus-summarised run the agent also itemised 99.64% of the expense amount on average, which is the figure the paper reports alongside it.
Three things in that table are worth separating.
First, pruning alone — just dropping everything but the last five tool interactions — beat full history by 8 points while using 64% fewer tokens. No summariser involved. That is the cheapest win in agent engineering and most teams have not taken it.
Second, summarisation on top of pruning added 12.6 further points for almost no extra tokens (535,274 to 553,374). Summarisation is useful. It is useful as a second step applied to an already-pruned window, not as a way to survive an unpruned one.
Third, the full-history run was 2.7 times slower in wall clock than pruning alone, and 2.5 times slower than pruning plus summarisation. A user-facing agent taking 14.56 hours across 50 tasks instead of 5.39 is not a cost problem, it is a product problem.
This is one paper, one benchmark, one model, and I would not build a company on it alone. But it points the same direction as Anthropic's harness decision: more context made the agent worse, not just more expensive.
The companion work is LOCA-bench (Zeng, Huang and He, arXiv 2602.07962, 8 February 2026), which builds controllable, effectively unbounded context growth while holding task semantics fixed, so agent context degradation can be measured rather than inferred from needle-in-a-haystack scores. Its abstract states qualitatively that performance degrades as environment state grows and that context management substantially improves success rate. It publishes no headline percentage and I will not invent one. The repeated claim that "safe effective context sits four to ten times below the advertised window" is not something I could trace to a primary source. Treat it as folklore until someone publishes the run.
The Token Budget Is an Engineering Constraint, Not a Bill
There used to be a pricing argument against long contexts on Claude. There is not any more.
Anthropic's pricing page states that Claude 4.6 and later models include the full 1M token context window at standard pricing, and spells out the consequence: "A 900k-token request is billed at the same per-token rate as a 9k-token request." Prompt caching and batch discounts apply at standard rates across the full window. The old surcharge tier above 200K is gone.
That matters more than it looks. Every remaining reason to keep a context small is an engineering reason — degradation, latency, context anxiety — not a finance one. You can no longer justify context discipline by pointing at the invoice. You justify it by pointing at the completion rate, which is what the table above gives you.
The tool-use system prompt is billed and it varies by model. Anthropic publishes the counts: 286 tokens on Opus 5 with tool_choice auto or none (406 with any or tool), 290/410 on Opus 4.8, 675/804 on Opus 4.7, 497/589 on Opus 4.6, 354/474 on Sonnet 5, 496/588 on Haiku 4.5. The newest generation cut that overhead by more than half against Opus 4.7.
Server toolsets are much larger. computer_toolset_20260801 costs roughly 4,500 input tokens, and disabling zoom removes about 410 of them. browser_toolset_20260801 costs roughly 6,600, with all four optional members adding about 880. The bash tool is 325 tokens on Opus 5, 4.8 and 4.7 against 244 on earlier models. text_editor_20250429 is 700.
Use the token-counting endpoint to get the exact figure before you ship. I go deeper into what these numbers do to a real bill in Tokens Per Task: The Real AI Cost Model in 2026, including the tokenizer change from Claude 4.7 onward that makes cross-generation price comparisons misleading.
Never Admit the Tokens: Tool Definitions Are the First Cut
Here is the lever almost nobody pulls first, and it is the biggest one.
Anthropic's tool search documentation states it directly: "A typical multiserver setup (GitHub, Slack, Sentry, Grafana, and Splunk) can consume ~55k tokens in definitions before Claude does any work. Tool search typically reduces this by over 85 percent, loading only the 3-5 tools Claude needs" (tool search tool docs↗).
Fifty-five thousand tokens, before the first user message. That is over half the default 100,000-token trigger on clear_tool_uses_20250919, spent on definitions for tools that will mostly never be called.
The cost is not only tokens. The same docs state: "Claude's ability to pick the right tool degrades once you exceed 30-50 available tools." So the fleet of MCP servers you bolted on is buying you worse tool selection and a smaller working window at the same time.
The mechanism is worth understanding because it interacts with caching. Setting defer_loading: true keeps a definition out of the system-prompt prefix, but you still send it on every request. When Claude discovers a tool, it arrives as a tool_reference block expanded inline — so the cached prefix is left intact. That is the design decision that makes this cheap rather than a cache-buster. Limits to know: 10,000 deferred tools, 5 results returned by default, 200-character regex queries and 500-character BM25 queries.
The ablation numbers behind this shipped earlier, in Anthropic's advanced tool use write-up (24 November 2025). Traditional loading consumed around 77K tokens before work began, against 8.7K with tool search. Anthropic calls that an 85% reduction; the two figures as published work out to 89%. Accuracy on the same task set went from 49% to 74% on Opus 4, and from 79.5% to 88.1% on Opus 4.5. Loading fewer tools made the model more accurate, not less.
If you are running an aggregated MCP fleet, this is where your context went. I cover what the July 2026 stateless spec changes about how those servers should be built in MCP Went Stateless: Migrating Your Server, and the basics of the protocol in MCP servers and standard tool integration.
Tool Results Are the Second Cut
Definitions are what you send. Results are what comes back, and on a long agent run results are the bulk of the window.
Two platform behaviours handle most of this for you now.
Automatic spill to file. Since 19 May 2026, inside Claude Managed Agents, large outputs from agent_toolset and MCP tools exceeding 100K characters — roughly 25K tokens — are automatically spilled to a file in the sandbox instead of being placed in context. The agent gets a truncated preview plus the file path, not the full payload, and reads back only the slice it needs. This is context engineering moved into the platform, and it happens whether or not you asked for it.
Programmatic tool calling. Instead of the model emitting one tool call, receiving the result into context, and emitting the next, it writes code that orchestrates the calls. The intermediate results never enter the window. Anthropic's documentation is unusually honest about where this helps and where it does not (programmatic tool calling docs↗):
- On a 75-tool project-management agent benchmark, enabling it reduced billed input tokens by roughly 38% with no change in task accuracy.
- Across production API traffic, requests whose
toolsarray contains 10 to 49 definitions see typical token savings of 20% to 40%. - On BrowseComp and DeepSearchQA it improved performance by an average of 11% while using 24% fewer input tokens.
- On tau-squared-bench, where each turn makes one or two sequential tool calls, it left scores unchanged and cost roughly 8% more.
That last bullet is the one to keep. A vendor publishing the null result next to the win is rare, and it tells you the shape of the decision: this is a fan-out optimisation. If your agent makes one call, looks at it, then makes the next, you are paying 8% for nothing.
One security note, because it is stated in Anthropic's docs and I have seen it misread twice. The allowed_callers field on a tool "controls how the tool is presented to Claude and is validated against tool_choice, but it is not a hard API-level block on direct invocation... Do not rely on allowed_callers as a security boundary." Authorisation lives in your tool handler or it does not exist. Also: tools with a recursive $ref in input_schema cannot be enabled for programmatic calling at all — you get a 400 with "Circular $ref detected".
How clear_tool_uses_20250919 Actually Behaves
Once definitions and results are under control, turn on server-side context editing. The documented strategies and parameters:
| Strategy | Parameters | Behaviour |
|---|---|---|
clear_tool_uses_20250919 | trigger, keep, clear_at_least, exclude_tools, clear_tool_inputs | Clears older tool uses and results once input tokens cross trigger, retaining keep most recent |
clear_thinking_20251015 | keep (thinking_turns: N or all) | Clears older thinking blocks |
The defaults on clear_tool_uses_20250919 are a 100,000 input-token trigger, keeping the last 3 tool uses.
{
"edits": [
{
"type": "clear_thinking_20251015",
"keep": { "type": "thinking_turns", "value": 2 }
},
{
"type": "clear_tool_uses_20250919",
"trigger": { "type": "input_tokens", "value": 100000 },
"keep": { "type": "tool_uses", "value": 3 }
}
]
}Both trigger and keep take a typed object rather than a bare integer, so a request that sends "trigger": 100000 is rejected. Two rules are easy to miss: thinking-clearing must be listed first when you combine the two strategies, and the beta header context-management-2025-06-27 must be on the request.
The response reports what happened under context_management.applied_edits, including cleared_input_tokens. Log that field. It is the only way to know whether your trigger fires at a useful point or never fires at all.
Context editing pairs with the memory tool (memory_20250818). Claude gets an automatic warning before a clear runs, which gives it a turn to write anything worth keeping into a memory file. That pairing is the most principled way to shrink a window on the API: the model chooses what survives before the window is cut. It beats a summariser guessing from outside, because the model knows which tool results it still intends to use.
The Cache Interaction Nobody Mentions
Context editing and prompt caching fight each other. Anthropic's context-editing docs say so in one line — "Invalidates cached prompt prefixes when content is cleared" — and hand you clear_at_least as the mitigation. Almost nothing written about either feature works through what that line costs you.
Clearing tool results invalidates your cached prefix. Thinking-clearing preserves the cache only when blocks are kept. So a context edit that fires at the wrong moment can hand you a full cache miss on a 100,000-token prompt — and at that size, the miss costs more than the tokens the edit saved.
The prompt caching docs↗ explain the machinery well enough to reason about this. Three facts do most of the work:
- Minimum cacheable prompt length varies by model, from 512 to 4,096 tokens, and below the minimum caching is silently skipped with no error. 512 on Fable 5.1, Mythos 5.1, Opus 5, Fable 5 and Mythos 5; 1,024 on Opus 4.8, Sonnet 5, Sonnet 4.6, Sonnet 4.5, Opus 4.1 and Opus 4; 2,048 on Mythos Preview, Opus 4.7 and Haiku 3.5; 4,096 on Opus 4.6, Opus 4.5 and Haiku 4.5.
- The lookback checks at most 20 block positions, and it looks for prior cache writes, not for stable content. A run of consecutive
tool_useblocks counts as one position, as does a run of consecutivetool_resultblocks. The worked example in the docs: turn 1 writes at block 10, turn 2 at 15 blocks walks back and hits, turn 3 at 35 blocks checks positions 35 down to 16 and misses the turn-2 entry at block 15 entirely. This is the most common reason a cache silently never hits, and it has nothing to do with your prompt being unstable. - TTL is measured from the start of the writing request, not the end of its response. A four-minute stream leaves about one minute of a five-minute TTL. Invalidation cascades tools to system to messages, and
tool_choice, images, the speed setting, web-search and citations toggles all invalidate.
Detection is simple: if both cache_creation_input_tokens and cache_read_input_tokens come back 0, nothing cached. Since 13 May 2026 you do not have to bisect the prompt by hand to find out why. Pass diagnostics.previous_message_id on a Messages request with the cache-diagnosis-2026-04-07 beta header, and the API returns a cache_miss_reason explaining exactly where the prefix diverged from the previous turn. The prompt caching docs mention it in a single cross-reference and move on, and almost nothing written about caching outside the docs picks it up.
The practical rule: set your context-editing trigger well above the point where the stable prefix stops growing, so edits fire rarely and each one buys a lot. Frequent small edits are the worst configuration available.
Retrieval Over Stuffing
Everything above is about not carrying tokens you have. Retrieval is about not loading tokens you might need.
Anthropic's Scaling Managed Agents: Decoupling the brain from the hands↗ (Lance Martin, Gabe Cemaj and Michael Cohen, 8 April 2026) is the clearest statement of the pattern. It treats the session as a durable, queryable log that lives outside the context window. The harness fetches event slices with getEvents() and calls execution environments through a stateless execute(name, input) -> string interface. That decoupling cut p50 time-to-first-token by about 60% and p95 by more than 90%, because containers are provisioned only when needed.
The shape generalises. Session history, tool output, documents and codebase state belong in something you can query. The window holds the current task, the plan, and the slices retrieved for this step. That is the discipline of a retrieval pipeline over a vector store, applied to the agent's own transcript — I walk through the mechanics in RAG systems explained.
The counter-argument you will hear is that 1M-token windows made retrieval unnecessary. They did not. They made it cheaper to be lazy. The pricing penalty is gone; the completion-rate penalty in the table above is not.
When Compaction IS Correct
I have argued against compaction as a first lever. It is not never-correct. Three cases where I turn it on anyway:
One task genuinely cannot be reset. A refactor across a hundred files where step ninety depends on a decision made at step four has no clean session boundary. Compaction with a model-authored handoff is the honest option. Use the memory tool pairing so the model writes the handoff before the clear, rather than a summariser reconstructing it after.
Human-in-the-loop conversations with long gaps. A support agent someone returns to after a day has no natural reset, and the user expects continuity. Summarise, but summarise a pruned window.
Cost ceilings on a hard SLA. If you must finish inside a fixed token budget and the task will not fit, lossy beats failing. Say out loud that it is lossy and measure what it costs in completion rate.
Outside those three, reset. And note what actually left the "build it yourself" column: the Python SDK v1.0 migration guide removes client-side compaction_control "in favour of server-side compaction, which summarises the conversation inside the API instead of with an extra client round-trip." When a vendor moves a feature out of your code and into theirs, that is a loud opinion about who should own it — and it means the compaction you reach for in these three cases should be compact_20260112 with a custom instructions string, not a summariser you wrote and now maintain.
The Order I Apply These Levers
For a new agent going to production, cheapest and highest-yield first:
- Count the definitions. Token-count a request with your real toolset attached before any user input. If it is five figures, you have found the problem. Defer everything you are not certain gets called.
- Cut the toolset to under 30. Selection accuracy degrades past 30-50 tools regardless of what you do about token count.
- Check that large results are spilling. On Managed Agents, anything over 100K characters should be landing in the sandbox as a file, not in the window. On the raw Messages API nothing spills for you, so truncate large results and hand back a path yourself.
- Enable programmatic tool calling if the workload fans out. If it is sequential single calls, skip it — it costs about 8% more.
- Turn on `clear_tool_uses_20250919`. Log
cleared_input_tokensand check your trigger fires at a sensible point. - Verify the cache still hits. Both usage counters non-zero. If not, use
cache_miss_reasonrather than guessing. - Prune aggressively before you summarise anything. Last-N tool interactions, then summarise the pruned window if you need the earlier detail.
- Only then consider compaction, and only for the three cases above.
Steps 1 through 4 cost you configuration. Step 8 costs you a lossy summary you cannot audit after the fact, even when the API writes it for you. That asymmetry is the argument.
If you are also splitting work across multiple agents, the same reasoning applies a level up — decomposition should follow context boundaries, not job titles. I make that case in Multi-Agent Systems Are a Context Decision, Not an Org Chart. And if you are trying to work out whether a model change or a harness change explains a score you are looking at, Your Agent Benchmark Number Is Mostly Your Harness covers how much of the spread is scaffold.
Key Takeaways
- Context editing and compaction are both server-side and free to adopt.
clear_tool_uses_20250919defaults to a 100,000-token trigger keeping the last 3 tool uses, behind thecontext-management-2025-06-27beta header;compact_20260112sits behindcompact-2026-01-12with a 50,000-token minimum trigger. - Anthropic's long-running-agent harness resets rather than compacts, to avoid context anxiety — models wrapping up prematurely near their perceived limit (24 March 2026).
- Pruning to the last five tool interactions beat full history by 8 points on 64% fewer tokens; adding summarisation on top reached 91.6% against 71.0% on a 50-task benchmark running GPT-5 (arXiv 2606.10209, 8 June 2026).
- A five-server MCP setup can burn around 55,000 tokens in tool definitions before the agent does any work, and tool selection accuracy degrades past 30-50 available tools.
- Programmatic tool calling cut billed input tokens roughly 38% on a 75-tool benchmark but cost about 8% more on sequential single-call workloads. It is a fan-out optimisation, not a default.
- Clearing tool results invalidates your cached prefix. Set the trigger high so edits fire rarely, and use
cache_miss_reasonwith thecache-diagnosis-2026-04-07header instead of bisecting prompts by hand. - The 1M window on Claude 4.6 and later carries no long-context premium — a 900k-token request bills at the same per-token rate as a 9k one, so every remaining reason to keep context small is an engineering reason.
About the Author
I'm Uvin Vindula — a Web3 and AI engineer based between Sri Lanka and the UK. I build production agents on the Claude API and spend more time deleting tokens from prompts than adding them, which is usually where the completion rate was hiding. You can see my work at iamuvin.com or reach out about a project at hello@iamuvin.com↗.
If your agent is getting slower and worse as it runs longer, let's talk about your project.
Working on a Web3 or AI project?
More in AI & Machine Learning
- Your Agent Benchmark Number Is Mostly Your Harness
- Tokens Per Task: The Real AI Cost Model in 2026
- Multi-Agent Systems Are a Context Decision, Not an Org Chart
- MCP Went Stateless: Migrating Your Server

Uvin Vindula
Web3 and AI engineer based in Sri Lanka and the UK. Author of The Rise of Bitcoin. Founder of ASI Research Labs. Director of Blockchain and Software Solutions at Terra Labz. Founder of uvin.lk — Sri Lanka's Bitcoin education platform with 10,000+ learners.