Compact Now, Pay Later

Auto-compaction in Claude Code and Cursor rewrites the cached prefix, so the next turn pays full price instead of a 50 to 90 percent cache discount. Nearly every coding agent harness now auto-compacts context when a session nears its window limit, summarizing history and replacing it with a shorter synopsis so the session keeps running instead of dying at the wall. It reads as pure upside. A closer look at the economics says otherwise: one analysis puts the break-even at roughly $0.55 per million cached tokens, below which keeping the full, uncompacted history is the cheaper choice. A June 2026 paper, SelfCompact, measured the other failure mode directly: compacting on a fixed token threshold costs 30 to 70 percent more per question than letting the model decide when to compact itself, while scoring lower on math and agentic-search benchmarks. This post breaks down when compaction saves money, when it quietly adds a second bill on top of the first, and ships a minimal decision-based trigger to prototype.

Published 2026-09-10 by Dor Amir on the Nadir blog.

Filed under Caching.

Claude Code, Cursor, and nearly every coding agent harness now auto-compact context when a session nears its window limit: they summarize the conversation, discard the raw history, and keep going instead of dying at the wall. It reads as pure upside, shorter context, longer sessions, no configuration required. A closer look at the economics says otherwise. Summarizing rewrites the prefix the provider would otherwise serve from a cache at a 50 to 90 percent discount, so the very next turn re-pays full price for tokens that were already paid for once. One analysis puts the break-even at roughly $0.55 per million cached tokens, below which keeping the full, uncompacted history is the cheaper choice, not the more expensive one. A June 2026 paper measured the other half of the problem directly: compacting on a fixed token threshold, the default in most agent scaffolds, costs 30 to 70 percent more per question than letting the model decide when to compact itself, while scoring lower on the benchmarks that matter. This post breaks down when compaction saves money, when it quietly adds a second bill on top of the first, and what a decision-based trigger looks like to prototype.

The feature that looks free.

Claude Code's auto-compact is a good example because the trigger is public and precise: it fires when a session's token count crosses the context window minus roughly 33,000 tokens of reserved headroom, which works out to about 167,000 tokens on a 200K-token model. Past that line, the harness summarizes the conversation, extracting the files touched, the decisions made, and the state of the current task, and replaces the raw back-and-forth with that summary. The session keeps running instead of erroring out. Cursor, Windsurf, and most other agent products ship a version of the same idea, and this blog has already covered the eviction-and-paging approach some scaffolds use instead, pinning and evicting content without generating a summary at all.

Compaction, the generative kind, is the one worth pricing carefully, because the summarization step is itself an LLM call, and what it does to the turns that follow is not neutral.

Why the summary call isn't free.

Prompt caching works by matching a byte-identical prefix against what the provider already has stored. The moment a harness summarizes, compresses, or otherwise rewrites the history, the provider sees a new prefix. Every token in it gets billed at the full input rate, not the cached rate, on the very next call, and on every call after that until the prefix stabilizes again.

That matters because cache discounts are large. DeepSeek prices a cache hit at roughly $0.0028 per million tokens against a $0.14 standard rate, a 50x gap; Gemini's cached rate runs about 90% off list. The cache write tax already covered the asymmetric side of this: writing to cache can cost more than a plain input token depending on the provider and TTL. Compaction adds a second asymmetry on top: a summarization pass is a full rewrite, not a write extension, so it forfeits the discount on the entire history at once rather than paying a premium on the marginal new tokens.

The crossover point works out to a specific number: keeping full, uncompacted history wins on cost as long as the cached input rate is under roughly $0.55 per million tokens, a threshold most frontier and mid-tier providers clear today. Below that line, letting a session's history grow, paying full price only once per token and cache-hit price on every re-read after, beats summarizing it, even though summarizing sends fewer tokens on the wire.

Two-panel chart. Left: cost per turn on an 11-to-13-turn agent session, full history with an 87% cache hit rate at $0.11 per turn versus a summarization-based production preset at $0.24 per turn despite sending 41% fewer tokens. Right: session memory recall by strategy, full history at 92-100%, a production summarization preset at 38-58%, and aggressive summarization at 17-40%.
Two-panel chart. Left: cost per turn on an 11-to-13-turn agent session, full history with an 87% cache hit rate at $0.11 per turn versus a summarization-based production preset at $0.24 per turn despite sending 41% fewer tokens. Right: session memory recall by strategy, full history at 92-100%, a production summarization preset at 38-58%, and aggressive summarization at 17-40%.

The recall numbers are the part a pure cost analysis misses. The summarization strategies in that comparison didn't just cost more per turn, despite sending fewer tokens, they also recalled less of the session correctly. The context rot research this blog has covered before found long context degrading model quality even without compaction; a lossy summary compounds that risk by construction, since whatever the summarizer judged unimportant is now permanently gone, not just harder to find.

What compaction actually costs, at real session scale.

None of this means compaction is always the wrong call, agent sessions do eventually exceed even a 1M-token window, and paying full price forever isn't an option either. It means the naive version of the feature, fire a summarization call whenever a counter crosses a line, is running against your bill in a direction most teams never measure.

A 50-turn coding session runs roughly 1 million input tokens against 40,000 output tokens, a ratio near 25:1, with input tokens dominating around 85% of total session cost. That input-heavy shape is exactly what a cache-invalidating compaction event taxes the hardest: a rewrite mid-session doesn't just cost tokens, it resets the cache-hit rate that was carrying most of that 85% at a discount.

ModelCost per 50-turn sessionAnnual, 25-engineer team at ~1,000 sessions/month
Premium flagship tier~$6.00~$72,000
Mid-tier frontier~$3.10~$37,200
Fast/budget tier~$1.80~$21,600
Efficient budget tier~$0.60~$7,200

A roughly 10x spread between the top and bottom rows, before compaction strategy is even a variable, is the same lesson this blog's cost-stacking piece already made about optimization order: which model handles a session is usually a bigger lever than how its context gets managed. But a naive compaction trigger firing repeatedly across a long agentic session, the same sessions already shown to burn far more tokens than chat traffic, can turn a 10x model-choice gap into something worse on any tier, because a cache-invalidating rewrite taxes the expensive tier and the cheap tier by the same percentage.

The fix isn't "compact less," it's "compact on purpose."

A June 2026 paper from Johns Hopkins researchers, SelfCompact, tested the actual alternative to a fixed token threshold: let the model decide when to compact. The scaffold pairs two pieces, a compaction tool the model can call as an explicit action, and a lightweight rubric telling it when firing is safe, a sub-task has resolved, the trajectory is converging, and when to hold, mid-derivation, or stuck. The paper's own ablation makes the point sharply: the tool alone, without the rubric, gets invoked unevenly and often at the wrong moment; the rubric alone can't act without the tool. Neither works by itself.

Tested across six benchmarks in competitive math and agentic search, and seven models, with no fine-tuning required, decision-based compaction matched or beat fixed-interval summarization while using 30 to 70% less token cost per question, and it improved over a no-summarization baseline by up to 18.1 points on math and 5 to 9 points on agentic search, where fixed-interval compaction's quality gain over no summarization was smaller on the same tasks.

Two-panel chart. Left: per-question token cost, fixed-interval compaction at 100% baseline versus SelfCompact's decision-based compaction at 30-70% of that cost. Right: quality points gained over a no-summarization baseline, +18.1 on competitive math and +5 to +9 on agentic search.
Two-panel chart. Left: per-question token cost, fixed-interval compaction at 100% baseline versus SelfCompact's decision-based compaction at 30-70% of that cost. Right: quality points gained over a no-summarization baseline, +18.1 on competitive math and +5 to +9 on agentic search.

The mechanism behind the win is intuitive once it's named: a token counter has no idea whether the agent is mid-derivation or between sub-tasks. Firing compaction at a bad moment doesn't just cost a summarization call, it risks discarding partial work the agent then has to redo, paying for the same reasoning twice. The trajectory-reduction work this blog covered earlier made a version of the same point about filtering agent history mid-run: what gets cut matters as much as how much gets cut, and a rule that ignores task structure will occasionally cut the wrong thing.

A minimal version to prototype.

The full SelfCompact scaffold trains no new weights, it's inference-time only, a tool definition plus a rubric prompt. A stripped-down version worth trying first replaces the token-threshold trigger with a cheap classification call that checks whether the current point in the trajectory looks safe to compact, before falling back to the threshold as a hard ceiling.

from dataclasses import dataclass

@dataclass
class CompactionDecision:
    should_compact: bool
    reason: str

def safe_to_compact(trajectory_tail: str, classify) -> CompactionDecision:
    """classify: a cheap model call returning one of
    'resolved' | 'converging' | 'mid_derivation' | 'stuck'
    for the last few turns of the trajectory."""
    state = classify(
        f"Classify the state of this agent trajectory's last few turns "
        f"as resolved, converging, mid_derivation, or stuck:\n\n{trajectory_tail}"
    )
    if state in ("resolved", "converging"):
        return CompactionDecision(True, f"safe: trajectory is {state}")
    return CompactionDecision(False, f"hold: trajectory is {state}")


class DecisionGatedCompactor:
    """Wraps a hard token ceiling around a decision-based trigger, so a
    stuck-forever trajectory still compacts eventually instead of hitting
    the context limit uncompacted."""

    def __init__(self, hard_ceiling_tokens: int, classify, summarize):
        self.hard_ceiling = hard_ceiling_tokens
        self.classify = classify
        self.summarize = summarize

    def maybe_compact(self, token_count: int, trajectory_tail: str, full_history: str):
        decision = safe_to_compact(trajectory_tail, self.classify)
        forced = token_count >= self.hard_ceiling
        if decision.should_compact or forced:
            reason = decision.reason if decision.should_compact else "forced: hit hard ceiling"
            return self.summarize(full_history), reason
        return None, decision.reason  # keep the cached prefix, don't rewrite it

Two choices in that snippet carry the actual savings. First, classify should run on the cheapest model that reliably tells "resolved" from "mid-derivation" apart, not the same frontier model running the agent, since this call fires on every turn near the threshold, not once per compaction event. Second, the hard ceiling stays in place: a decision-based trigger that never fires on a genuinely stuck trajectory would eventually blow the context window, so the token threshold survives as a backstop, not the primary signal.

What this doesn't solve.

SelfCompact's benchmark suite is competitive math and agentic search, both domains with a relatively clean notion of "sub-task resolved" the rubric can key off of. A long-running production coding session mixes exploration, half-finished refactors, and genuinely ambiguous stopping points more than a benchmark trajectory does, and the paper is explicit that the tool alone is unevenly used across open-weight models, some call it too rarely, some at unhelpful moments, which is exactly why the rubric has to be paired with it rather than treated as a nice-to-have. The cache-economics side has its own caveat: the $0.55-per-million break-even point moves with provider pricing, and a team on a provider with an unusually cheap cache-write rate or an unusually short cache TTL will land on a different number than the one measured here.

What to check before you change your compaction strategy.

Conclusion.

Auto-compaction reads as a free win because it makes a hard limit disappear. The bill tells a more specific story: rewriting the prefix a provider was about to serve at a 50 to 90% discount forfeits that discount on the entire history at once, with a real break-even point, and a summarization trigger fired by a token counter instead of task structure costs 30 to 70% more per question than one the model decides for itself, while losing quality points in the process. Neither finding argues for never compacting. Both argue for treating the trigger as a decision with its own cost, measured against your own cache-hit rate and your own trajectory shape, instead of a threshold a harness ships by default and nobody revisits.


Sources: [Li, Zhang, Jurayj, Wang, Jin, Farajtabar, Nalisnick, Khashabi, "Self-Compacting Language Model Agents," arXiv:2606.23525, submitted June 22, 2026](https://arxiv.org/abs/2606.23525). [Claude Code documentation: context window and auto-compact](https://code.claude.com/docs/en/context-window). [Louis Bouchard, "Context Engineering in 2026: Why We Stopped Compacting Our Agent's Context"](https://www.louisbouchard.ai/context-engineering-2026/). [Vantage, "The Hidden Cost Driver in Agentic Coding Sessions in 2026"](https://www.vantage.sh/blog/agentic-coding-costs). [The Cache Write Tax](/blog/cache-write-tax-prompt-caching-cost). [The Missing L2: Context Window as Virtual Memory](/blog/context-window-virtual-memory-demand-paging). [Coding Agents Burn 1,000x More Tokens Than Chat](/blog/coding-agents-burn-1000x-tokens-research).

More on caching

What Nadir is

Nadir is an LLM router. Nadir sends each prompt to the cheapest model that can handle it. A small decision model reads each prompt against your model menu and picks the lowest-cost model it expects to handle it. When the decision model is uncertain or unavailable, the request goes to the strongest model on the menu. The routing step makes no call to your model provider.

Nadir runs two ways. The decision API returns a model, reasoning-effort, cache, context, and policy recommendation without calling a model provider, beside the gateway you already run. That is how a shadow-mode evaluation works, and its projected savings stay advisory. The OpenAI compatible managed proxy executes the route, and migration is a two-line change: point the base URL at api.getnadir.com and set model to auto. On that path an optional verifier can score a complete non-streaming answer and escalate to a stronger model when it misses the configured bar. Streaming bypasses post-generation verification. BYOK is supported on every tier.

For coding agents, Nadir Auto is a terminal launcher for Claude Code or Codex that asks Nadir for the main-session model before each turn, with your configured model as the fallback and cost ceiling. Delegation integrations for Claude Code, Codex, or Cursor instead recommend a model tier for subagent work, and the agent decides; the Claude plugin can also move a main-thread turn to Haiku when Nadir's cache check prices it cheaper, unless its switch_main_model option is off. Either way inference runs on your own provider account, so Nadir holds no provider keys on that path.

What the numbers are, and what they are not

Nadir publishes each evaluation with its scope. On checkable code, run-check-escalate solved 392 of 395 common HumanEval and MBPP problems (99.2%), graded by running the canonical tests; that applies only to tasks with runnable deterministic tests. Nadir-Tumbler posts an arena_score of 72.3 on RouterArena's public scorer, 5th of 23 routers, which measures the routing decision on RouterArena's own model pool. A reference-assisted RouterBench evaluation over 11,420 held-out triples produced a 60% lower projected cost than always-Opus with about 98% retained quality and a 1.7% catastrophic-route rate. That experiment gave the verifier the expensive-model reference answer, which production does not have, so it is a research ceiling and not the deployed path.

None of these is a production guarantee, a universal savings rate, or a forecast for any particular workload. Customer savings are reported from measured execution against a declared baseline, and customer quality only from outcome-labelled traffic. Projected savings and realized savings are separate artifacts and are never blended.

Design-partner program

Three rungs, picked by risk appetite. Rung 0 Shadow runs advisory decision calls alongside live traffic and returns a projected receipt, with nothing in the request path changed. Rung 1 Hosted is the two-line swap on a production slice and returns a realized receipt. Rung 2 On-prem is a supervised six-week proof of concept inside the partner's VPC, where no prompt, response, or usage reaches Nadir. The commitments are the same at every rung. Apply for a rung directly: Rung 0 Shadow, Rung 1 Hosted, or Rung 2 On-prem. Not sure which fits? Start at getnadir.com/contact/?reason=design-partner.

Licensing

NadirClaw is the self-hosted core, source-available under the PolyForm Noncommercial License. Source-available is the correct label; NadirClaw is not open source. Nadir Route's hosted plan has no base fee and charges a variable fee only on measured savings from requests Nadir executed.

Pages on this site

Machine-readable summaries of this site: llms.txt and llms-full.txt.