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
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:
- 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 + on the nearest assistant message. Median divergence is ~1.00×,
usage.cache_creation_input_tokens
but the tail reaches 6.34×, so compaction fires when the actual prompt is small.
- 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.