Auto-compaction INCREASES real on-wire context when preTokens diverges (up to 6.34x) and compaction fires below the rebuild floor — 133 net-negative events across 5,180 boundaries, worst +167,519 tokens, 12.9% of subagent compactions affected

Status Open
Reported on v2.1.225
Maintainer reply None cached
Activity 0 comments · opened Aug 10, 2026

Summary

Auto-compaction can increase the real on-wire context instead of reducing it. Measured across a
local corpus of 5,180 compaction boundaries in 47,019 transcript files, 133 subagent-family
compactions gained more than 50k tokens each
, the worst adding +167,519 tokens (30,029 → 197,548).

Two faults compound:

  1. The trigger counter (compactMetadata.preTokens) diverges from the real prompt size. Real

on-wire context here means usage.input_tokens + usage.cache_read_input_tokens +
usage.cache_creation_input_tokens
on the nearest assistant message. Median divergence is ~1.00×,
but the tail reaches 6.34×, so compaction fires when the actual prompt is small.

  1. Compaction rebuilds to a floor. When the pre-compaction prompt is already _below_ that floor,

compaction cannot reduce anything — it replaces a small context with a larger rebuilt one.

The predicate, which held without exception

Comparing each compaction against its regime's own rebuild floor (median post-compaction real
context among affected events):

| Regime | boundaries | rebuild floor | started below floor → grew | started above floor → grew |
| ----------------- | ---------: | ------------: | ------------------------------ | ------------------------------ |
| main session | 3,227 | ~523k | 110 / 2,096 (5%) | 0 / 1,131 (0%) |
| subagent | 738 | ~180k | 63 / 725 (9%) | 0 / 13 (0%) |
| workflow subagent | 870 | ~171k | 165 / 826 (20%) | 0 / 44 (0%) |

Starting above the floor was sufficient for a safe compaction — zero counter-examples in 1,188
cases.
Every net-negative event started below it.

It concentrates in subagents

12.9% of workflow-subagent compactions were materially net-negative, versus 0.1% of
main-session ones. The shape is consistent: real context 39k–100k, rebuilt to 175k–199k. Compacting
a 39k context against a ~171k floor cannot do anything but grow it.

Since 2026-07-01 alone, 71 such events added +5,882,340 tokens in total.

postTokens also looks wrong

In one main-session event, postTokens reported 660,853 for a rebuild whose preserved messages
totalled roughly 1,633 tokens (8 messages, from compactMetadata.preservedMessages.allUuids).
The counter appears unreliable on both sides of the boundary, not only before it.

Not a one-off

Material net-negative events by month: 2026-05 → 5, 2026-06 → 59, 2026-07 → 70, 2026-08 → 1 so far.
Median inflation is ~1.00–1.03× in every month since 2025-11, so the problem lives entirely in the
tail — sampling any single healthy session shows nothing. Observed on 2.1.x, including transcripts
written by 2.1.225 / 2.1.226.

A worked example

Three consecutive auto-compactions in six minutes on one session:

| # | preTokens | postTokens | real before | real after | delta | msgs kept | inflation |
| --- | --------: | ---------: | ----------: | ---------: | -----------: | --------: | --------: |
| 1 | 1,018,623 | 660,853 | 371,367 | 613,317 | +241,950 | 8 | 2.74× |
| 2 | 1,259,188 | 655,183 | 613,317 | 602,686 | −10,631 | 7 | 2.05× |
| 3 | 604,237 | 10,308 | 602,686 | 62,864 | −539,822 | 6 | 1.00× |

The first compaction grew the context; the second reclaimed almost nothing; the third worked. Note
inflation decaying 2.74× → 2.05× → 1.00× across the three, which is consistent with stale counter
state draining, though I could not confirm that.

Why user settings cannot work around it

CLAUDE_CODE_AUTO_COMPACT_WINDOW and CLAUDE_AUTOCOMPACT_PCT_OVERRIDE scale the threshold, not
the counter compared against it. A 2.7×-inflated counter defeats any threshold value. There appears
to be no user-facing setting that affects this.

What I could not determine

preTokens is assigned from a minified symbol whose own assignment I could not locate in 2.1.226,
and I found no reset site. I therefore cannot say why the counter diverges. Two hypotheses were
tested and ruled out for the sessions examined: subagent/sidechain token accounting (the worked
example above contains zero isSidechain messages), and the auto-loaded CLAUDE.md hierarchy being
too large (it measures ~24k tokens there, far too small to account for the growth).

Suggested mitigation, independent of root cause

Skip compaction when the current real prompt is already below the expected post-compaction size. In
the corpus, that single guard would have prevented every net-negative event without blocking any
compaction that actually reclaimed context.

How to reproduce the measurement

For each subtype: "compact_boundary" record in a transcript, compare compactMetadata.preTokens
against the summed usage fields on the nearest assistant messages either side. Note that
transcripts may be brotli-compressed (.jsonl.br), so globbing only *.jsonl silently skips whole
sessions.

Environment: macOS (arm64), Claude Code 2.1.22x. Happy to share the aggregate measurement script;
transcript contents are not included here as they contain private work.

View original on GitHub ↗