Context engineering is four mechanisms, not one
Context engineering on the Claude platform is not a setting. It is four mechanisms at four points in the pipeline, and the one everybody enables first pays for context window with prompt cache.
Updated on September 21, 2026
On this page
Quick answer
As of September 2026, context engineering on the Claude Developer Platform is not one setting you turn on. It is four separate mechanisms that intervene at four different points in the request pipeline, documented on four different pages, and two of them are gated behind two different beta headers.
The one almost everybody reaches for first is tool result clearing, and the thing its own documentation says out loud is the thing nearly every write-up about it leaves out: clearing invalidates your cached prompt prefix at the point where it clears. That is why the clear_at_least parameter exists. It is not a tuning nicety. It is there so the cache write you just paid for buys back more than it cost.
The second thing that took me longest to believe: the edit happens server side and your client keeps the full, unmodified history. You do not sync anything. I had written synchronisation code before I read that sentence.
The moment
I had an agent loop that read a lot of files. Nothing exotic, just a long run of read calls whose results piled up until the window got tight. I turned on tool result clearing, watched the input token count drop by about forty thousand, and felt clever for roughly one billing period.
Then I looked at the cache read numbers. They had fallen off a cliff on exactly the requests where clearing fired. I had been treating context editing as a way to reclaim window space, which it is, and I had not noticed it was also a way to throw away the cached prefix I was relying on to keep the run cheap. The window got roomier and each clearing request got more expensive, and because the two effects live in different columns of the usage object I had not put them next to each other.
The documentation had told me. I had read the page. I had read the parameter list and skipped the paragraph.
Finding 1: four mechanisms, four insertion points, four pages
The vendor's own comparison page frames this better than any summary I could write. Four approaches, each reducing something different:
- Tool search reduces tool definitions loaded upfront. It keeps schemas out of the window until Claude asks for them, trading one extra turn of latency for a smaller baseline.
- Programmatic tool calling reduces
tool_resultroundtrips, by collapsing a chain of calls into one script that runs in a sandbox so the intermediate results never enter history at all. - Prompt caching reduces the cost of tokens rather than their number.
- Context editing reduces old
tool_resultblocks already sitting in history.
Those are not four brands of the same thing. Prompt caching does not free a single token of window, and tool search does nothing for results you have already accumulated. Picking the wrong one means paying for a mechanism that cannot touch where your tokens actually went.
The same page gives an ordered adoption sequence, which is the most practically useful thing on it: caching on tool definitions from day one, tool search once the toolset passes roughly twenty tools, context editing once individual conversations run long enough that early results stop mattering, and programmatic tool calling if you spot repetitive chains of small calls. The order is not arbitrary. It runs cheapest-to-adopt first.
Finding 2: clearing spends prompt cache to buy context
Here is the sentence, from the context editing page, September 2026:
Verbatim: "Tool result clearing: Invalidates cached prompt prefixes when content is cleared. To account for this, clear enough tokens to make the cache invalidation worthwhile. Use the clear_at_least parameter to ensure a minimum number of tokens is cleared each time. You'll incur cache write costs each time content is cleared, but subsequent requests can reuse the newly cached prefix."
Read that as an economic statement rather than a caveat. A clearing event is a transaction: you hand back some cached prefix, you pay a cache write, and you receive window space. If the clearing event is small, you paid the write for almost nothing. clear_at_least sets a floor on what you get, so the transaction is worth doing.
This is also why default-on clearing with a low trigger can be worse than no clearing at all on a workload with a stable prefix and modest growth. You end up rewriting the cache repeatedly to reclaim slivers.
The cache side of this has its own literature, and the cost patterns where caching stops paying are worth reading separately if you are optimising a high-volume loop, because the failure modes compose: three caching workload patterns and two anti-patterns where caching costs more than it saves is the treatment I keep going back to.
Finding 3: you do not sync your client
Verbatim, same page: "Context editing is applied server-side before the prompt reaches Claude. Your client application maintains the full, unmodified conversation history. You do not need to sync your client state with the edited version."
I want to underline how much this saves you. The naive mental model is that the API has mutated your conversation and you now have two divergent copies to reconcile. That model leads directly to writing a mirror of the clearing logic on your side so your stored transcript matches what the model saw. That code is not merely unnecessary, it is actively wrong: your full history is the thing you want to keep, for audit, for replay, for showing a user what happened.
What the server does is construct an edited view per request. Your transcript stays whole. The divergence is intentional and it is one directional.
Finding 4: the response hands you both numbers
Because the two views differ, you would otherwise be guessing at what happened. You are not. Clearing reports itself:
{
"context_management": {
"applied_edits": [
{
"type": "clear_tool_uses_20250919",
"cleared_tool_uses": 8,
"cleared_input_tokens": 50000
}
]
}
}
And the token count you are billed for arrives alongside the count you would have been billed for:
{
"input_tokens": 25000,
"context_management": {
"original_input_tokens": 70000
}
}
input_tokens is post-edit. original_input_tokens is pre-edit. Logging both is how you find out whether clearing is earning its keep, and it is the pair I wish I had been recording from the start instead of reconstructing after the fact.
The token counting endpoint accepts context management too, so you can preview the post-edit number before you spend anything on a real call. If you are deciding whether to enable this at all, that is the cheap experiment: count the same conversation twice, once with the edit configured and once without.
When you are streaming, the edits arrive in the final message_delta event rather than up front, which matters if you are parsing events and expected the accounting early.
Finding 5: the trigger has two units, and the defaults are not obvious
Minimal configuration, with the beta header that gates it:
resp = client.beta.messages.create(
model="claude-sonnet-5",
max_tokens=2048,
betas=["context-management-2025-06-27"],
messages=messages,
tools=tools,
extra_body={
"context_management": {
"edits": [
{
"type": "clear_tool_uses_20250919",
"trigger": {"type": "input_tokens", "value": 60000},
"keep": {"type": "tool_uses", "value": 5},
"clear_at_least": {"type": "input_tokens", "value": 8000},
}
]
}
},
)
edits = resp.context_management.applied_edits if resp.context_management else []
Defaults, September 2026: the trigger is 100,000 input tokens and keep is 3 tool uses. clear_at_least has no default, which is the one I would set first given Finding 2.
The part that changes how you reason about it: trigger is not tokens-only. It takes a type, and that type can be tool_uses instead of input_tokens. On a loop whose calls return wildly uneven payloads, counting tokens is the right trigger. On a loop whose calls are uniform and whose problem is sheer count, counting tool uses is both simpler and more predictable. I had assumed a token threshold was the only option because every example I had seen used one.
Finding 6: results go, inputs stay, unless you say otherwise
By default only tool results are cleared. The tool calls that produced them, with their parameters, remain. You can clear both by setting clear_tool_inputs to true.
That default is the right one more often than not. The call is usually small and it is the breadcrumb that tells the model what it already tried, which is exactly the context you do not want to destroy in an agent loop. The result is usually the large thing. Clearing results while keeping calls leaves the model able to see that it read a file without carrying the file.
exclude_tools is the other half of the control surface: name the tools whose output must never be cleared. The obvious candidates are the ones returning something the whole task depends on, a schema or a spec or a plan, where the payload is large and also load bearing.
Cleared content is replaced with placeholder text, so the model is told something was removed rather than silently finding a gap. Clearing runs oldest-first, in chronological order.
Finding 7: compaction is a different beta on a different page, and it can stop your request
This is the one I would not have found from the context editing page, because that page does not mention it. Its own summary describes the feature as being in beta "with support for tool result clearing and thinking block clearing". Compaction is a third strategy with its own documentation page and its own beta header.
The mechanism is categorically different. Clearing is surgical removal. Compaction has the model summarise the earlier conversation and replaces that history with the summary, returning it as a compaction content block ahead of the normal response.
Numbers as documented, September 2026: type string compact_20260112, beta header compact-2026-01-12, trigger default 150,000 input tokens with a stated minimum of 50,000, and an instructions parameter that completely replaces the default summarisation prompt when you provide one.
The behaviour worth knowing before you enable it is pause_after_compaction. Set it and the API can return stop_reason: "compaction", which lets your harness inspect or augment the summary before the conversation continues. That is genuinely useful and it is also a new terminal state your loop has to handle. If your code branches on stop_reason and treats anything unrecognised as an error, enabling compaction with that flag will look like a failure rather than a checkpoint.
Caching composes better here than you might expect: you can put a cache_control breakpoint on the compaction block, and the documented recommendation is a breakpoint at the end of the system prompt so the system prompt cache survives compaction and only the new summary needs writing.
Finding 8: one of these is universal and one is an allowlist
Context editing, per its page, is "available on all supported Claude models". Compaction publishes an explicit model list instead, naming eleven models including claude-opus-5, claude-sonnet-5, claude-sonnet-4-6 and the Fable and Mythos families.
So the two strategies do not have the same reach, and the asymmetry runs the way you would not guess: the more aggressive, more recently dated mechanism is the one with the narrower support. If you are writing a provider abstraction that picks a strategy per model, that is the branch to get right, and it is a fact worth re-reading at the source rather than trusting any summary including this one, because an explicit allowlist is exactly the kind of thing that grows.
Finding 9: a gateway can accept the knobs and ignore them
If you route through a proxy rather than straight at the API, check what it actually implements. LiteLLM's own Claude Code context management page documents native pass-through for Anthropic and Bedrock routes and a polyfill for everything else, and in the polyfill it lists both clear_tool_inputs and exclude_tools as accepted in the request and ignored.
That is honest documentation and it is also a trap if you skim it. A request carrying exclude_tools returns a success. Nothing errors. The tool output you carefully protected gets cleared anyway, and you find out when the model starts behaving as though it never saw the spec. Accepted is not the same as honoured, and a parameter silently dropped by a middlebox is the hardest class of this to debug because every layer reports fine.
Its table also lists thinking block clearing as not yet implemented, which is a second thing to know before you design around it.
Finding 10: thinking blocks are a third strategy with the same cache rule
clear_thinking_20251015 manages thinking blocks when extended thinking is on. Its keep takes either a count of thinking turns or the string all, so you can trade reasoning continuity against window space.
The cache behaviour follows exactly the same shape as Finding 2: keeping thinking blocks preserves the prompt cache and lets you hit it, clearing them invalidates the cache at the point of clearing. One rule, applied to a second kind of content. Once you see it that way the whole feature family gets easier to reason about, because every clearing strategy is the same trade in a different currency.
There is one model-specific wrinkle documented on the same page that I am recording rather than interpreting, because it names an account cutoff date and I have not exercised it: on Claude Fable 5.1, server-side context management never invalidates thinking blocks, while client-side edits to earlier turns can invalidate thinking blocks in every later assistant turn, and for accounts created on or after 31 August 2026 a request replaying an invalidated block is rejected unless you opt into dropping it.
What I changed
I set clear_at_least on every configuration that has clearing enabled, which I had previously left unset. I started logging input_tokens and original_input_tokens as a pair alongside cache read and cache write, in one line, so the trade is visible in one place instead of three. I deleted the client-side mirroring code. I moved one loop from a token trigger to a tool_uses trigger because its calls are uniform and counting them is easier to predict. And I put the compaction stop_reason into the loop's terminal-state handling before enabling it anywhere, which I would not have thought to do if I had not read its page separately.
The thing I did not change is the default of clearing results but not inputs. Every time I have talked myself into clearing inputs as well, the reason was window pressure that tool search or a different trigger unit would have solved more cheaply.
For the client-side story, which is a genuinely different mechanism from all four of these, my notes on what the CLI's own compaction actually drops are the contrast I keep coming back to: summarising a transcript in the client and clearing tool results on the server look similar in a diagram and behave nothing alike.
What I did not verify
I did not run a controlled cost experiment. Everything in Finding 2 is the documented cache behaviour plus my own before-and-after observation on one workload, which is an anecdote rather than a measurement, and I did not isolate cache write cost from the token reduction.
I did not exercise pause_after_compaction end to end, so I have not seen what a real compaction block looks like on a long transcript or how good the default summary is.
I did not test the Fable 5.1 thinking-block behaviour or the account cutoff, and I have no way to test the account-creation-date branch at all.
I did not benchmark tool search or programmatic tool calling. I am reporting where the vendor's comparison page says they intervene, not what they cost in practice.
I did not test LiteLLM's polyfill myself. Finding 9 is a reading of its own published support table, September 2026, not an experiment, and a polyfill marked v0 is exactly the kind of thing that changes.
I did not cover the memory tool, which is part of the same broader story and is a different enough mechanism to deserve its own run.
Postscript: the parameter list is the easy part. The paragraph after the parameter list is where they tell you what it costs.
Written by
M. PatelFrequently asked questions
Does context editing change the conversation history my client stores?
No. Context editing is applied server side before the prompt reaches Claude, and your client keeps the full unmodified history. The documentation states you do not need to sync your client state with the edited version, so mirroring the clearing logic on your side is unnecessary and loses the transcript you want for audit and replay.
Why did enabling tool result clearing make my requests more expensive?
Because clearing invalidates the cached prompt prefix at the point where content is cleared, so you pay a cache write each time it fires. If each clearing event reclaims only a small amount, you paid the write for almost nothing. The clear_at_least parameter sets a floor on how much is cleared so the cache write is worth making.
What are the default trigger and keep values for clear_tool_uses_20250919?
As documented in September 2026 the trigger defaults to 100,000 input tokens and keep defaults to 3 tool uses. clear_at_least has no default. The trigger is not tokens only: its type can be tool_uses instead of input_tokens, which is the better choice on a loop whose calls are uniform in size.
Is server-side compaction the same thing as context editing?
No, and it is documented on a separate page behind a separate beta header. Context editing removes old tool results surgically. Compaction has the model summarise earlier history and returns that summary as a compaction content block. Its trigger defaults to 150,000 input tokens with a stated minimum of 50,000, and pause_after_compaction makes the API return a stop_reason of compaction so your harness can inspect the summary first.
How do I measure whether context editing is actually saving me anything?
Log the pair. The response reports applied_edits with cleared_tool_uses and cleared_input_tokens, and it reports input_tokens next to original_input_tokens, which are the post-edit and pre-edit counts. The token counting endpoint also accepts context management, so you can preview the post-edit number without spending anything on a real call.
Keep reading
Claude Code auto compact: what it costs and what you lose (2026)
Claude Code auto compact fires on a per-model token boundary, not a percentage. What it costs is set by prompt cache warmth rather than context size, and a path-scoped rule does not come back afterwards until Claude reads a matching file again.
Context rot: two guards, split by model, and one model gets neither
Context rot is real and Anthropic now names it in its own docs. The useful question in 2026 is narrower: your Claude model ships with one of two self regulation mechanisms, or with neither, and they do not overlap. Sonnet and Haiku get context awareness free and automatic. Opus needs a beta header. Opus 4.6 gets nothing.
Your task budget caps a turn, not a task, and Continue. buys a fresh one
A task budget is not a per-task cost ceiling. It resets whenever you send a user message carrying no tool results, which is exactly what most harnesses do when Claude finishes gracefully.