{"slug": "claude-code-auto-compact-12-of-22-drops-were-real-half-were-one-turn", "title": "Claude Code Auto-Compact: 12 of 22 Drops Were Real, Half Were One Turn", "summary": "A developer analyzing Claude Code transcripts found that only 12 of 22 sudden context drops across two projects were real auto-compactions, and half of those 12 were triggered by a single large turn rather than gradual context accumulation — all six surge cases involved calls to a stronger advisor model consulted with the full conversation. The team developed a classification method based on absolute cache_write values (roughly 50,000 or more for real compactions, 10,000 or less for advisor round-trips, and zero for resume artifacts) after a cache_write/context-after ratio proved unreliable, ranging from 0.58 to 1.00 because it measured cache state rather than compaction events.", "body_md": "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.\n\nThat 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](https://my-blog.org/claude-code/post/claude-code-autocompact-single-turn?utm_source=devto&utm_medium=referral&utm_campaign=claude-code-autocompact-single-turn).\n\nAuto-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.\n\nOf 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.\n\nOur 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.\n\nThe 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.\n\nAn absolute `cache_write` value separates the cases cleanly:\n\n| Verdict | Condition | What it is | \n|---|---|---|\n| Real compaction | cache_write of roughly 50,000 or more | The conversation was actually summarized | \n| Advisor round-trip | cache_write of roughly 10,000 or less | Context swelled briefly and came back | \n| Resume artifact | cache_write 0 and context-after 0 | A recording artifact of resuming a session | \n\nTranscripts 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.\n\n``` python\ndef ctx_of(u):\n    # field names depend on your transcript schema\n    return u[\"input\"] + u[\"cache_read\"] + u[\"cache_creation\"]\n\ndef classify(cw, ctx_after):\n    if cw == 0 and ctx_after == 0:\n        return \"resume artifact\"\n    if cw >= 50_000:\n        return \"real compaction\"\n    if cw <= 10_000:\n        return \"advisor round-trip\"\n    return \"undecided\"\n\nseen, rows = set(), []\nfor row in transcript_rows:        # one line = one assistant response\n    if row[\"requestId\"] in seen:   # same request is logged 2-3 times\n        continue\n    seen.add(row[\"requestId\"])\n    rows.append(row)\n```\n\nRun 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.\n\nAn 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.\n\n| Regime | Advisor calls | Outcome | \n|---|---|---|\n| After setting a cap | 5 | 5 compactions | \n| Before the cap (trigger at the model limit) | 4 | 3 reverted, 1 compacted | \n\n\"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.\n\nSetting 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.\n\nWe 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.\n\nThe floor is a project constant driven by your fixed head (global instructions, project instructions, memory), so do not copy someone else's numbers:\n\n|  | Project A | Project B | \n|---|---|---|\n| Fixed head | 89KB | 69KB | \n| Floor after compaction | about 130,000 | about 91,000 | \n| Headroom (T minus floor) | about 35,000 | about 102,000 | \n| Cost per compaction | about 125,000 | about 85,000 | \n\nOne compaction costs roughly 25k of summary output plus rewriting the floor. With about 35,000 of headroom, reading one 123KB file whole fills it.\n\nRaising the cap is not at the top of the list.\n\nTwo settings worth pairing with the cap:\n\n```\n{\n  \"autoCompactWindow\": 240000,\n  \"showClearContextOnPlanAccept\": true\n}\n```\n\nIf 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.\n\nThe 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.\n\nThe 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](https://my-blog.org/claude-code/post/claude-code-autocompact-single-turn?utm_source=devto&utm_medium=referral&utm_campaign=claude-code-autocompact-single-turn).\n\n*Free tools I keep on my own site: [34 calculators and how-to guides](https://my-blog.org/tools?utm_source=devto&utm_medium=referral&utm_campaign=claude-code-autocompact-single-turn) - loans, severance pay, take-home salary, savings vs deposits. New ones go out in one email, no ads.*", "url": "https://wpnews.pro/news/claude-code-auto-compact-12-of-22-drops-were-real-half-were-one-turn", "canonical_source": "https://dev.to/sungwoo_lee_e0f26be4a29fd/claude-code-auto-compact-12-of-22-drops-were-real-half-were-one-turn-1aab", "published_at": "2026-10-27 23:33:33+00:00", "updated_at": "2026-10-27 23:41:16.902931+00:00", "lang": "en", "topics": ["ai-tools", "large-language-models", "ai-agents", "developer-tools"], "entities": ["Claude Code", "Anthropic"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/claude-code-auto-compact-12-of-22-drops-were-real-half-were-one-turn", "markdown": "https://wpnews.pro/news/claude-code-auto-compact-12-of-22-drops-were-real-half-were-one-turn.md", "text": "https://wpnews.pro/news/claude-code-auto-compact-12-of-22-drops-were-real-half-were-one-turn.txt", "jsonld": "https://wpnews.pro/news/claude-code-auto-compact-12-of-22-drops-were-real-half-were-one-turn.jsonld"}}