Compaction is a reliability event, and you are not measuring it

New research on long-horizon agents finds context compression degrades execution, not knowledge. Treat every compaction as a state transition and instrument it.


Diagram: an agent run crossing a compaction boundary, with narrative facts preserved and execution state lost

Here is a bug report I have now heard three separate versions of:

“The agent works fine for about twenty minutes. Then it starts redoing things it already did.”

Every time, the team’s first instinct is that the model got confused, or the prompt needs work, or the task was too hard. Every time, the actual answer is that the run crossed a compaction boundary and nobody was looking.

Compaction is the most consequential thing happening in your agent runtime that you almost certainly have no telemetry for.


The thing that happens quietly

When a long-running agent’s conversation approaches the context window, something has to give. The standard answer is to summarize the earlier history into a compact form and drop the raw turns. Anthropic’s server-side compaction triggers by default around 150K tokens and returns a compaction block that replaces the compacted history on subsequent requests. Most frameworks do their own version. Most do it automatically, and most do it silently.

From the outside it looks like an optimization. A memory-management detail. The kind of thing you would be pleased the platform handles for you.

It is not an optimization. It is a state transition in the middle of a running job, and it is the only state transition in your agent runtime that fires without anyone deciding it should.


What the research found

There is now a decent empirical answer to what compaction costs you.

An August 2026 study of long-horizon agents — Min, Wu, Darbari, Chen, and Hong, submitted August 6 — looked specifically at recurrent context compression and execution instability. Their finding, tested on AppWorld:

Compression diminishes the influence of recent interactions, and the observable consequences are:

  • Blocked actions — the agent attempts something that cannot proceed given state it no longer remembers
  • Repeated exploration — it re-investigates ground it already covered
  • Multi-run inconsistency — the same task, run repeatedly, produces meaningfully different outcomes

They trace this to execution-state mislocalization. The agent does not lose the facts. It loses its place.

That distinction is the whole article, so let me sit on it.


Narrative survives. Bookkeeping does not.

Ask a summarizer to compress twelve turns of an agent transcript, and it will do what summarizers are trained to do: preserve the narrative. What was the goal, what was learned, what is the situation.

What it will not reliably preserve:

  • I have already edited handlers.py and config.yaml, and not the other four files
  • The /v2/accounts endpoint returned 403 twice — that is a permissions problem, not a transient one, do not retry it
  • I tried the batch approach and ruled it out because of the rate limit
  • Step 4 of 9 is done; step 5 is in progress and half-applied

None of that is narratively interesting. All of it is what the next action depends on.

This is why the failure looks like amnesia about actions rather than amnesia about facts. Ask the post-compaction agent what it is working on and it will tell you correctly. Ask it to take the next step and it may take a step it already took.

The related finding worth pairing this with is Chroma’s Context Rot work, which showed model performance degrading as input token count grows, across models, even on deliberately controlled tasks. Put the two together and you get an uncomfortable shape: performance degrades as you approach the window, and then degrades differently when you compact to escape it. There is no comfortable region — only a set of tradeoffs you should be choosing deliberately rather than inheriting.

I argued in context engineering: the window is a budget that you should treat the window as a resource you allocate rather than a bucket you fill. This is the operational sequel: the moment your allocation runs out is an event, and events get instrumented.


Instrument it like the state transition it is

Here is the concrete ask. Three things.

1. Emit a span for every compaction.

Not a log line. A span, on the same trace as the run, following the OTel GenAI conventions you are hopefully already using for the agent loop. Attributes worth carrying:

AttributeWhy
pre_compaction_tokensHow much was squeezed
run_idCorrelate to the parent run
step_indexWhere in the plan it happened
compaction_countWhich compaction this is for this run
tool_calls_droppedHow much execution history went into the summary

Anthropic’s Managed Agents surface already emits an agent.thread_context_compacted event carrying pre_compaction_tokens — if you are on that runtime, you are being handed this for free and you should be routing it somewhere.

2. Track three derived metrics.

  • Compaction rate per run. How often does a typical run compact? If your p50 run compacts zero times and your p95 compacts four, you have two different reliability populations wearing the same SLO.
  • Post-compaction step failure rate vs. baseline step failure rate. This is the one that proves the cost. Compare the failure rate of the N steps immediately after a compaction against the run’s overall step failure rate. A gap is your compaction tax, in numbers, on your workload.
  • Repeated-action rate in the post-compaction window. Hash the action — tool name plus normalized arguments — and count repeats within a run. Repeats clustering right after a compaction boundary is the signature the research describes, and you can detect it without reading a single transcript.

3. Alert on the second one moving.

Not on compaction happening — compaction happening is fine and normal. Alert when the post-compaction failure gap widens, because that means either your workloads got longer or your summarizer got worse, and both are things you want to know about before a customer tells you.


The bug that gets everyone

Before the sophisticated stuff, the unglamorous one.

If you are on the Anthropic API and using server-side compaction, the compaction state comes back inside the response content. You must append the full response.content to your message history. Not the extracted text — the content.

# Wrong — silently loses compaction state
text = next(b.text for b in response.content if b.type == "text")
messages.append({"role": "assistant", "content": text})

# Right — compaction blocks are preserved
messages.append({"role": "assistant", "content": response.content})

The first version does not error. It does not warn. The conversation just stops working the way you think it does, and you spend a day blaming the model.

I mention it because in a codebase that has been through a few refactors, “extract the text and append it” is an extremely natural thing for someone to write.


Compaction and context editing are not the same thing

Worth being precise, because these get conflated and they fail differently.

CompactionContext editing
What it doesSummarizes old history into a condensed blockClears stale tool results or thinking blocks outright
What is lostPrecision — the summary may distortThe content — but nothing is distorted
Failure modeAgent misremembers its own stateAgent has no record at all
Best forRuns that need the arc of what happenedRuns where old tool output is genuinely dead weight

On the Anthropic API these are separate features with separate beta flags — compaction under compact-2026-01-12, context editing under context-management-2025-06-27 with strategies like clear_tool_uses_20250919. Mixing up the strategy type and the beta header is a common and confusing failure.

The design instinct I would offer: clear what is dead, summarize what is narrative, and externalize what is state. Old tool results from a resolved sub-task are dead — clear them. The arc of the investigation is narrative — summarize it. Which files you have edited is state, and state does not belong in the context window at all.


The structural fix: stop putting execution state in the transcript

The research paper’s own contribution is TRACE, a verifier-guided framework that evaluates individual compaction events by running paired continuations from the same environment state and optimizing the compression prompt against which summary actually continues better — all with the models frozen. That is a genuinely clever evaluation design, and it reports gains on task performance, multi-run reliability, and context-execution efficiency over existing compression baselines.

But notice what it is optimizing: how well the summarizer preserves the things the next step needs.

The more robust move is to stop asking a summarizer to preserve them.

Give the agent an explicit, external, structured record of execution state:

  • A task ledger — steps, status, evidence for each. Written to a file or a store, not accumulated in the conversation.
  • Idempotent tools where you can manage it, so a repeated action after compaction is wasteful rather than wrong.
  • A re-orientation step immediately after compaction: the first thing the agent does post-compaction is read the ledger.

The ledger survives compaction because it was never in the window to begin with. The agent reads it back in, deliberately, as a tool call. That is a durable structure, versus a summarizer you are hoping keeps the right details this time.

This is the same reasoning behind treating agentic memory as a typed thing rather than “whatever is in the transcript.” Execution state is a specific type with specific requirements, and the transcript is a bad store for it.


Why I think this matters more than it sounds

Agent runs are getting longer. That is the direction of the whole field — more delegation, more autonomy, longer horizons. Which means more runs will cross compaction boundaries, and more of them will cross several.

If your reliability model treats an agent run as one unit that either succeeds or fails, you will not see this. You will see a success rate that sags as tasks get longer, and you will attribute it to task difficulty, because that is the available explanation.

The available explanation is wrong. Some meaningful fraction of it is a state transition your platform performs automatically, without telling you, at a moment nobody chose.

Emit the span. Compare the failure rates. Then you will know.


Sources: Toward Reliable Context Compression for Long-Horizon Agents (arXiv:2608.06503) · Anthropic: compaction and context editing documentation

Frequently asked questions

What is context compaction?

When a long-running agent's conversation approaches the model's context window, the earlier history is summarized into a compact form and the raw turns are dropped. Anthropic's server-side compaction, for example, triggers by default around 150K tokens and returns a compaction block that replaces the compacted history on subsequent requests. Most agent frameworks do something equivalent, and most do it automatically.

How is compaction different from context editing?

Compaction summarizes — it replaces old turns with a condensed representation. Context editing prunes — it clears stale tool results or thinking blocks outright, without replacing them. They solve related problems and have different failure modes: compaction can lose precision in the summary, editing loses the content entirely but never distorts it. On the Anthropic API they are separate features with separate beta flags, and confusing them is a common mistake.

What does the research actually show?

An August 2026 empirical study of long-horizon agents on AppWorld found that recurrent context compression diminishes the influence of recent interactions, producing more blocked actions, repeated exploration after compaction, and inconsistent performance across repeated runs of the same task. The failure is traced to execution-state mislocalization — the agent loses track of where it is in its own plan rather than losing facts.

Why does compaction hurt execution more than knowledge?

Summarizers optimize for narrative coherence, which is what summarization training rewards. Execution state is not narrative — it is bookkeeping. Which of six files have I already edited, which endpoint returned 403 and does not need retrying, which approach did I try and rule out. That bookkeeping reads as low-salience detail to a summarizer and is exactly what the next step depends on.

What should platform teams instrument?

Emit a span for every compaction with the pre-compaction token count, the run id, and the step index. Then track three things: compaction rate per run, post-compaction step failure rate compared to the baseline step failure rate, and repeated-action rate in the window after a compaction. If the second or third rises, compaction is costing you reliability and you can prove it.

What is the most common implementation bug?

Dropping the compaction block. Anthropic's API returns compaction state inside the response content, and you must append the full response content back into your message history — not just the extracted text. Teams that pull out the text string and append that lose compaction state silently. There is no error; the conversation just quietly stops working the way it should.

Comments