DEV Community

Sungwoo Lee
Sungwoo Lee

Posted on Originally published at my-blog.org

Claude Code Auto-Compact: 12 of 22 Drops Were Real, Half Were One Turn

If Claude Code keeps summarizing your session, the usual explanation is "the conversation got long." In our transcripts that was only half the story. We re-judged 22 sudden context drops across two projects (2026-08-09). Only 12 were real auto-compactions, and half of those 12 came from one large input landing in a single turn, not from slow accumulation. All six of those surge cases were turns where we had called the advisor, a stronger model consulted with the full conversation.

That changes the fix. Raising the context cap helps accumulation. It does nothing for a single turn that is big enough to cross the line again. Below is how we told the cases apart, what the trigger point turned out to be, and what we do first now. The full write-up, including the parts we got wrong twice, is in the original post on my-blog.org.

What counts as a real compaction

Of 22 context drops, 12 were real compactions, 7 were resume artifacts, and 3 were advisor round-trips

Auto-compact summarizes the conversation when context reaches a policy limit. It works in two stages: it first discards old tool output, and only if that is not enough does it summarize the conversation itself. That order matters later, because it means big tool output is exactly what gets thrown away first.

Of our 22 drops, 12 were real compactions, 3 were advisor round-trips that bounced back, and 7 were artifacts of session resume. If you count every dip in a context graph as a compaction, you will blame the wrong thing.

Do not classify by ratio

Our first attempt was a ratio. A compaction rewrites the prefix, so we expected cache_write / context-after to be close to 1. It wasn't. Across real compactions that ratio swung from 0.58 to 1.00.

The reason is the denominator. During back-to-back compactions the system prompt and tool schemas are cache hits, so the ratio drops to 0.6 to 0.75. On the first compaction after a long gap everything is rewritten and the ratio approaches 1.00. That cached portion was about 31.5k in both projects (116,310 minus 84,459 is 31,851; 92,999 minus 61,454 is 31,545). The ratio was measuring cache state, not whether a compaction happened.

An absolute cache_write value separates the cases cleanly:

Verdict Condition What it is
Real compaction cache_write of roughly 50,000 or more The conversation was actually summarized
Advisor round-trip cache_write of roughly 10,000 or less Context swelled briefly and came back
Resume artifact cache_write 0 and context-after 0 A recording artifact of resuming a session

The classification script

Transcripts record the same request on two or three rows. Deduplicate by requestId first, or usage is overcounted by about 1.9x. Then compute per-turn context as input + cache_read + cache_creation, find the adjacent-turn drops, and classify. The order of the checks matters, so resume artifacts are not mislabeled as advisor round-trips.

def ctx_of(u):
    # field names depend on your transcript schema
    return u["input"] + u["cache_read"] + u["cache_creation"]

def classify(cw, ctx_after):
    if cw == 0 and ctx_after == 0:
        return "resume artifact"
    if cw >= 50_000:
        return "real compaction"
    if cw <= 10_000:
        return "advisor round-trip"
    return "undecided"

seen, rows = set(), []
for row in transcript_rows:        # one line = one assistant response
    if row["requestId"] in seen:   # same request is logged 2-3 times
        continue
    seen.add(row["requestId"])
    rows.append(row)
Enter fullscreen mode Exit fullscreen mode

Run this outside the conversation. Reading a whole transcript inside the session inflates the very context you are trying to measure. We also had a PreCompact hook that archives the full transcript at each compaction, which let us cross-check seven verdicts against archive timestamps. All seven matched, with a 2 to 6 minute offset from the KST/UTC difference. Without a hook like that you are relying on the formula alone.

Why the advisor is the usual surge

An advisor call sends the whole conversation to a stronger model, so the turn's context becomes 2.05 to 2.20 times larger (six observed cases). The mechanism is simple: multiply your context at call time by 2.2. If the result is past the trigger line, compaction fires on the spot. If not, context returns to normal after the response.

Regime Advisor calls Outcome
After setting a cap 5 5 compactions
Before the cap (trigger at the model limit) 4 3 reverted, 1 compacted

"I used to call the advisor all the time and it was fine" is not a counterexample. It is a record from a regime where the trigger sat at 1M tokens, so 2.2x never reached it. The next largest turn-inflators are the same category: reading a 123KB file whole (about 35k tokens), full log reads, multi-page PDFs, big JSON dumps, ls -R, and unbounded database queries.

Where the trigger actually sits

Project A has a 89KB fixed head, floor about 130,000, headroom about 35,000, compaction cost about 125,000; Project B has 69KB, about 91,000, about 102,000, about 85,000

Setting a 240,000 cap does not mean compaction at 240,000. In our environment it fired at about 165,000 tokens, roughly 0.69 times the cap. We saw the transition from "not fired" to "fired" three times: 160,806 to 165,002, then 162,475 to 165,693, then 164,792 to 168,736.

We also made a mistake here. We overlaid the three observations and wrote "the trigger is above 164,792 and at most 165,002, a 210-token window." Nothing guaranteed the three observations shared the same conditions, and the trigger is not provably a function of the cap alone, since model and tool schema size are mixed in. We dropped the precision claim and kept two things: trigger T is about cap times 0.69, and headroom is T minus the floor after compaction.

The floor is a project constant driven by your fixed head (global instructions, project instructions, memory), so do not copy someone else's numbers:

Project A Project B
Fixed head 89KB 69KB
Floor after compaction about 130,000 about 91,000
Headroom (T minus floor) about 35,000 about 102,000
Cost per compaction about 125,000 about 85,000

One compaction costs roughly 25k of summary output plus rewriting the floor. With about 35,000 of headroom, reading one 123KB file whole fills it.

What to do, in order of effect

Raising the cap is not at the top of the list.

  1. Call the advisor less often. Drop the habitual "one more check." Keep it before irreversible work such as DDL, deploys, and external changes, where one bad DDL costs more than ten compactions.
  2. Cap the largest single-turn increase: no whole-file Reads, use offset/limit, and use Grep to locate things.
  3. Never take tool output whole. Use grep, head, and tail. Stage one of compaction discards exactly this output, so trimming output and the cap are one set.
  4. Raise the cap only if headroom is genuinely short.
  5. Shrink the fixed head. A lower floor reduces both headroom pressure and per-compaction cost.
  6. Write big artifacts to files and pull back only a summary line.
  7. Make subagents return conclusions only. A report stays in the parent context permanently, about 3.8k each as measured.

Two settings worth pairing with the cap:

{
  "autoCompactWindow": 240000,
  "showClearContextOnPlanAccept": true
}
Enter fullscreen mode Exit fullscreen mode

If compaction is already looping, look at what went into the previous turn before touching the cap, and do not call the same thing again. Otherwise the loop keeps spinning.

What does not transfer

The general parts are the shape of the classifier and the relations T about cap times 0.69 and headroom equals T minus floor. Everything else is our environment. The 50,000 threshold means "about one floor rewrite," so with a much thinner fixed head, lower it to match your own floor. The method also assumes transcripts with per-turn usage values. We have not observed the natural compaction cycle under a cap, which is why we manage the advisor by how many times we call it, not by when.

The original post, with the extra FAQ and the reasoning behind each number, is here: Claude Code auto-compact is caused by one turn, not a full context.


Free tools I keep on my own site: 34 calculators and how-to guides - loans, severance pay, take-home salary, savings vs deposits. New ones go out in one email, no ads.

Top comments (1)

Collapse
 
spobi profile image
Spobi •

This is why I use things like context carwash so when I compact I can see exactly what context it's saving.