Claude Code waits until 967K tokens to compact. Pick the window yourself
On a 1M-context model, a long session drags a near-million-token history through every turn. One command sets a smaller auto-compact window, and a cost model shows where it pays off.

A Sonnet 5.5 session that has been running since the morning stand-up is probably carrying several hundred thousand tokens of old file reads, test output and abandoned approaches. Claude Code won’t touch that history until it nears the model’s limit. For models with a native 1M window, Anthropic’s docs put the default compaction point at about 967K tokens.
That default is a choice, and it’s one you can override in a few seconds. A smaller window makes sessions cheaper, because every turn re-reads the whole history, and it makes compaction happen while the model still has a clear view of what you were doing. It also costs you detail, since a summary is lossy. This piece shows the setting, the four places it can live, the one environment-variable trap, and a cost model for choosing a number.
What the default does
Fable models, Sonnet 5 and later, Haiku 5.5 and Opus 4.7 and later run with a 1M-token window. According to the Claude Code docs, sessions on those models compact “before the window fills”, at about 967K tokens. Sonnet 4.6 and Opus 4.6 without extended context compact at 200K.
Two things follow. First, a long session on a 1M model can live for hours without a single compaction, and every request in that time sends the full history. Prompt caching makes the re-read cheap, but cheap isn’t free: a cache read is billed per token, and the history is the biggest thing in the request.
Second, compaction at 967K is compaction at the worst moment. Anthropic’s own session-management guide, written by Thariq Shihipar in April 2026, defines context rot as model performance degrading as context grows, and says that’s why the model is least capable at the moment it has to summarise. Its advice is to compact proactively, with a description of what you plan to do next, instead of waiting for the automatic pass.
Set a window in one command
Inside a session, run:
/autocompact 300k
Claude Code saves the value to your user settings under the current model and applies it to the session at once. The accepted forms are a plain token count (300000), a k or M suffix (300k, 1M), or a bare number from 100 to 1000 meaning thousands, so 300 also sets 300,000. Run /autocompact auto to go back to the window Claude Code tunes for the model. With no argument, the command opens a dialog showing the current window.
The valid range is 100K to 1M. Outside it, the launch flag refuses with a clear message. Run claude --autocompact 50k --version and it prints:
error: option '--autocompact <auto|tokens>' argument '50k' is invalid. It must be 'auto', or between 100k and 1M (e.g. 500k, 200000, or 200 as shorthand)
Four places to put it
The window can be set in more than one place, and the order matters when two disagree.
/autocompactsaves per model. Since v2.1.288 each model keeps its own window, so switching from Sonnet to Opus doesn’t carry the number across. Before v2.1.288, the command wrote one window for every model.- The
autoCompactWindowkey in any settings file sets it for every model:"autoCompactWindow": 300000in~/.claude/settings.json. A window saved for a model with/autocompactwins over this key in the same file. - The
--autocompactflag overrides your saved setting for one launch without changing it. It needs v2.1.221 or later. - The
CLAUDE_CODE_AUTO_COMPACT_WINDOWenvironment variable beats all three. It’s meant for scripts and cloud environments.
A per-model entry in settings.json looks like this, using the canonical model name Claude Code writes itself. This is the documented shape rather than something run for this article:
{
"modelSettings": {
"claude-sonnet-5-5": { "autoCompactWindow": 300000 },
"claude-opus-5-5": { "autoCompactWindow": "auto" }
}
}
A managed-settings window from a higher-priority scope outranks your saved value. In that case /autocompact still saves your number, but says the session keeps the other scope’s window.
The environment-variable trap
The command and the flag understand 300k. The environment variable doesn’t. It takes a plain integer only, and the docs spell out what happens otherwise: a value like 500k reads as 500 and clamps to the 100K minimum.
# wrong: compacts at 100K
export CLAUDE_CODE_AUTO_COMPACT_WINDOW=500k
# right
export CLAUDE_CODE_AUTO_COMPACT_WINDOW=500000
There’s a second side effect. While the variable is set, the status line’s used_percentage still measures against the model’s full context window, so it no longer tells you how close compaction is. A status line that reads 31% can already be at the edge of a 300K window. Use /context for a live breakdown instead.
Choosing a number with a cost model
Picking a window by feel gives you 200K because it sounds round. A short script gives a better starting point. It models 1,000 turns on Sonnet 5.5, using the prices on Anthropic’s pricing page: $2.50 per million tokens for a five-minute cache write, $0.10 for a cache read and $10 for output. Sonnet 5.5 includes the full 1M window at standard pricing, so the per-token price doesn’t change as the prompt grows.
Every other number is an assumption: 30,000 tokens that always survive compaction (system prompt, CLAUDE.md, tools), 3,000 new tokens a turn, 1,000 output tokens a turn, a 15,000-token summary, and 8,000 output tokens to write it. Swap in figures from your own sessions.
READ, WRITE_5M, OUT = 0.10, 2.50, 10.00 # USD per MTok, Sonnet 5.5
BASE, SUMMARY, STEP, REPLY, SUMMARY_OUT, TURNS = 30_000, 15_000, 3_000, 1_000, 8_000, 1_000
def run(window):
ctx, cost, compactions = BASE, 0.0, 0
for _ in range(TURNS):
cost += (ctx * READ + STEP * WRITE_5M + REPLY * OUT) / 1e6
ctx += STEP
if ctx >= window:
cost += (ctx * READ + SUMMARY_OUT * OUT) / 1e6 # summary request, warm cache
cost += (BASE + SUMMARY) * WRITE_5M / 1e6 # next turn rebuilds the cache
ctx = BASE + SUMMARY
compactions += 1
return cost, compactions
for w in (967_000, 500_000, 300_000, 200_000, 100_000):
c, n = run(w)
print(f"{w:>9,} {n:>12} ${c:.2f}")
Run it and it prints:
window compactions cost
967,000 3 $66.16
500,000 6 $45.13
300,000 11 $36.76
200,000 19 $33.60
100,000 52 $35.21
Read the shape, not the dollars. About $17.50 of every row is output and cache writes for new tokens, and no window changes that. The rest is the cost of re-reading history, which grows with the square of how long a context is allowed to get. Dropping from 967K to 300K cuts the total by roughly 44% in this model. Going below 200K starts to cost more, because the compactions themselves aren’t free: each one is a full-prefix request plus a cache rebuild.
The curve is flat between about 200K and 300K. That’s the range to start from, and it’s opinion drawn from this model, not a measurement of your sessions.
What the model leaves out
It assumes the cache is always warm. A compaction after a break longer than the cache lifetime reprocesses the whole history as uncached input, according to the prompt-caching docs, which is why the docs name /compact as most expensive when you resume an old session. A lower window shrinks that bill too, since there’s less history to reprocess.
It also treats compaction as free of consequences. It isn’t. The summary replaces the history, and details the summary drops are gone. The cost table says nothing about that, which is why the cheapest row isn’t automatically the right one.
Haiku 5.5 is the exception to the flat pricing. Anthropic charges higher prices for any Haiku 5.5 request whose prompt is over 100,000 tokens, counting cache reads and writes. The minimum auto-compact window is also 100K, so a Haiku-heavy workflow is the one place where a window at or near the floor makes sense on price alone. That’s reasoning from the two documented numbers, not something tested.
Make compaction less lossy
A smaller window means more compactions, so the quality of each one matters more. Three habits help.
Compact on your own schedule when you can. Run /compact focus on the auth migration and the failing integration test at a natural break and the summary keeps what you chose, instead of what the automatic pass guesses is important. The prompt-caching docs also recommend a task boundary over a mid-task trigger.
Put standing instructions in CLAUDE.md under a # Compact instructions heading. The costs docs show this pattern: a line telling Claude to focus on test output and code changes when compacting.
Use /clear between unrelated tasks. A window setting is for the long session you can’t split. If the work divides cleanly, a fresh session beats any summary, and Anthropic’s guide describes /rewind as often the better fix when an approach goes wrong, because it drops the failed attempt instead of summarising it.
Subagents get their own window
Claude Code 2.1.296 (9 October 2026) added autoCompactWindow to subagent frontmatter and to --agents definitions, so a subagent can compact earlier than the main conversation. The changelog line doesn’t give the value format, and the subagent reference page doesn’t list the field yet, so check /agents or the docs for the current syntax before relying on it. The idea is sound for a long-running reviewer or researcher subagent that reads a lot and only needs its last few findings.
When not to bother
Skip this if your sessions end before the context passes 200K, which is most of them when you /clear between tasks. A window above your usual context size does nothing. Skip it too if you’re on a subscription and don’t see per-token bills, though the quality argument for earlier compaction still applies.
Don’t set it as low as the cost table tempts you to if your work depends on exact details from early in the session, such as a long list of constraints or a migration checklist. Put those in a file the agent re-reads, not in the history a summary will squeeze.
Try it today
Run /autocompact 300k at the start of your next long session. Work normally, note when the “Conversation compacted” message appears, and check whether the agent still knows what it was doing. If it forgets, raise the number or add a compact instruction to CLAUDE.md. If it doesn’t, you’ve just cut the cost of every turn after the first few hundred thousand tokens.