Claude Code Idle Compaction: What It Does and How to Stop It
If you leave a long Claude Code session open over lunch and come back to a line that says Compacted while idle, before the prompt cache expired, you have met idle compaction. Claude Code summarized your conversation while you were away, and your next message will be sent on top of that summary instead of the full history.
The changelog entry for 2.1.299 describes it in one line: a conversation of 200K or more tokens, left idle for about 54 minutes, is compacted before its one-hour prompt cache expires. This page covers the rest: the conditions that decide whether it fires, what it saves, what it costs you, and the three ways to turn it off. Verified on 2026-10-29 against the Claude Code docs and the 2.1.312 binary (we read the code path; we did not run an idle session, see How we checked).
The short version
| Question | Answer |
|---|---|
| What fires it | About an hour of idle time (default 54 minutes) on a conversation of at least 200,000 tokens |
| Where it runs | Interactive terminal, the VS Code chat panel, and the desktop app's Code tab when the session runs on your machine or over SSH |
| What it needs | Auto-compaction on, the one-hour cache TTL, and feature flags fetched from Anthropic |
| What it does not touch | claude -p, SDK runs and CI jobs: the docs list only interactive surfaces |
| How to turn it off | "idleCompaction": false, the Idle compaction row in /config, or DISABLE_AUTO_COMPACT=1 |
| How to tune it | CLAUDE_CODE_IDLE_COMPACT_MIN_TOKENS, floor of 100,000 |
Why it exists
Every turn re-sends the whole conversation, and the prompt cache is what makes that affordable: a cache hit reads the history at a fraction of the input price. The cache has a lifetime. On the one-hour TTL, a session that sits for more than an hour comes back to nothing cached, and the next turn pays to write the entire history again. In our prompt caching guide that is the "miss" that costs the most.
Idle compaction attacks the problem from the other side. Instead of keeping the history warm, it shrinks the history just before the cache would have expired, while the summarizing request can still read the old prefix from the cache. The docs describe the effect: your next message sends a summary instead of the whole conversation.
When it fires
The settings reference lists the conditions, and all of them must hold:
- You are in an interactive terminal session, the VS Code chat panel, or the desktop app's Code tab (local or SSH).
autoCompactEnabledis on.- The conversation is on the one-hour prompt cache TTL.
- Claude Code can fetch feature flags from Anthropic.
- The context has reached the threshold, 200,000 tokens by default.
- About an hour has passed since the last request and your computer stayed awake until then.
Condition 3 is the one that surprises people. Per the prompt caching docs, Claude Code requests the one-hour TTL by default only on a Claude subscription, within your plan's included usage. On an API key, or a cloud provider, the main conversation defaults to the five-minute TTL, so idle compaction never applies unless you set promptCacheTtl to 1h yourself. If you move to usage credits after hitting a plan limit, Claude Code drops the main conversation to five minutes, and idle compaction stops applying there too.
Where the 54 minutes comes from
The changelog says "about 54 minutes", and the binary shows why. The timer is set at a fraction of the cache's remaining life, measured from the last activity: lastActivityAt + (expiresAt - lastActivityAt) * fraction. The default fraction in code is 0.9. Ninety percent of a 60 minute lifetime is 54 minutes. The fraction is also read from a server-side flag and clamped between 0.5 and 0.95 in the client, so the real number on your account can differ from
- Treat the changelog figure as the default, not a guarantee.
What makes it skip
The check that runs when the timer goes off has an explicit list of reasons to do nothing. Reading the 2.1.312 code, these are the ones a user can reason about:
| Skip reason (our paraphrase) | What triggers it |
|---|---|
| Disabled | The server-side mode for your account is off |
| Compaction off | Auto-compaction is disabled |
| Idle compaction off | idleCompaction is false |
| Not on the one-hour cache | The conversation is on the five-minute TTL |
| Prefix changed | There is no unchanged cached prefix to build the summary on |
| Lapsed | The timer fired more than 60 seconds late, for example because the machine slept |
| Small | The context is under the token threshold |
| Newer request | Another request went out after the timer was set |
| Near limit | Your usage status is not "allowed", so you are close to or past a limit |
The "lapsed" row is worth remembering. If your laptop sleeps through the 54 minute mark, the timer fires late, and the code skips the run instead of compacting. Our reading is that this avoids spending a request on a prefix that may no longer be cached. This matches the docs' wording that your computer has to stay awake until then.
One more thing the code shows: the behavior is gated by a server-side mode with three non-off values, named log, compact and compact_on_return. We can tell from the names and the skip logic that log records what would have happened without compacting, and that compact_on_return is a variant that involves a precomputed summary and a swap. That is our reading of the code, not documented behavior, and we do not know which mode any given account is on. It is one more reason two people on the same version may see different results.
What it saves, with the assumptions shown
We could not run an hour-long idle session without an API key, so the numbers below are arithmetic from the published rates, not a measurement. The assumptions are ours.
Rates for Opus 5.5 on the prompt caching pricing table: base input $4 per million tokens, one-hour cache writes $8, cache hits $0.20, output $20.
Assume a 300,000 token conversation and you return after two hours.
| Without idle compaction | With idle compaction | |
|---|---|---|
| Summary request at about 54 min | none | 300K read from cache: $0.06 |
| Summary output (assume 8K tokens) | none | $0.16 |
| First turn after you return | 300K written cold at $8: $2.40 | 20K (assumed system prompt, tools and summary) written cold: $0.16 |
| Each later turn, cache read | 300K at $0.20: $0.06 | 20K at $0.20: about $0.004 |
| First-return total | $2.40 | about $0.38 |
The shape matters more than the exact figures: the summary request is a cache read, which is cheap, and every later turn reads a much smaller prefix. If your summary is bigger than 8K tokens, or the post-compaction prefix is bigger than 20K, move the numbers accordingly. On a subscription you are not billed per token, but the same ratio shows up as a smaller draw on your usage limit and a faster first reply after you come back.
What it costs you
Compaction is lossy. After it runs, Claude is working from a summary, and the details of tool output, file contents and earlier reasoning that were in the old history are gone unless the summary kept them. The context window docs describe what survives compaction.
Two situations make that a real cost:
- You were mid-debug. A long investigation where exact log lines and file contents from forty turns ago still matter is the worst case to summarize.
- You come back early. If you return at 56 minutes, the cache was still warm for four more minutes, and you would have paid almost nothing to keep the full history. Idle compaction cannot know you were about to return.
If the work in that session is the kind you would have run /compact on at a natural break anyway, idle compaction does it for you at the cheapest possible moment. If it is the kind where you would rather pay the cold-cache price than lose detail, turn it off.
Turn it off, or tune it
Any one of these stops it:
{
"idleCompaction": false
}
Put that in ~/.claude/settings.json (any settings file works, and a managed or project value overrides your user file). Inside a terminal session, /config has an Idle compaction row that writes the same key to your user settings and applies immediately; the row needs 2.1.302 or later. The key needs 2.1.290 or later, and on an older version the docs say to turn off autoCompactEnabled instead.
DISABLE_AUTO_COMPACT=1 also turns idle compaction off, along with auto compaction. DISABLE_COMPACT=1 disables compaction entirely, including manual /compact.
To keep it but make it apply less often, raise the threshold, or lower it to include smaller conversations. The default is 200,000 and values under 100,000 are raised to 100,000:
{
"env": {
"CLAUDE_CODE_IDLE_COMPACT_MIN_TOKENS": "150000"
}
}
Setting idleCompaction to true does not turn the feature on where the conditions above are not met. The in-app text for the setting says the same.
A related warning from 2.1.304
If you resume a session that has sat idle, 2.1.304 added a warning on Pro and Max plans when resuming "would use a noticeable share of your 5-hour usage limit", with the choice to resume anyway or start a new conversation. That is the same cold-cache cost showing up from the other direction: a session that idle compaction did not shrink. If you see that warning regularly, check whether the conditions above are blocking idle compaction for that session.
FAQ
Does idle compaction run in claude -p or on a schedule?
The docs list the interactive terminal, the VS Code chat panel and the desktop Code tab. Headless runs are not on the list, so a scheduled job does not get idle compaction. Long unattended sessions should manage their own context.
I use an API key. Do I get it?
Not by default. The main conversation uses the five-minute cache TTL on an API key, and idle compaction requires the one-hour TTL. Set promptCacheTtl to 1h if you want the longer cache, which also makes the conversation eligible.
How do I know it ran?
In the terminal, a line starting Compacted while idle, before the prompt cache expired appears in the conversation. In VS Code and the desktop app the notice reads Compacted using a summary written while you were away.
Can I get the old history back?
Compaction replaces the history in the conversation Claude works from. The docs do not describe an undo for an idle compaction, and we did not test whether the transcript view keeps the earlier turns. If you need the exact earlier text, keep it in a file before you walk away.
Is the 54 minute figure fixed?
No. The code default is 90 percent of the one-hour lifetime, and the fraction can be set by a server-side flag within 50 to 95 percent.
How we checked
- Docs: the
idleCompactionsection of the settings reference, theCLAUDE_CODE_IDLE_COMPACT_MIN_TOKENSandDISABLE_AUTO_COMPACTentries in the environment variable reference, and the cache TTL and compaction sections of the prompt caching page, all fetched 2026-10-29. - Changelog: the 2.1.299, 2.1.302 and 2.1.304 entries.
- Code: we read the idle compaction scheduler and its skip checks in the 2.1.312 binary: default threshold 200000, floor 100000, default fire fraction 0.9 clamped to 0.5 to 0.95, the 60 second lateness limit, and the skip reasons in the table. We did not execute an idle session, so the actual timing and the summary quality on a real conversation are unmeasured here.
- Pricing: the rates in the cost table are from the platform prompt caching pricing table on the same date. The totals are our arithmetic on assumed token counts.
If you measure an idle compaction on your own account, the number worth recording is the cold-turn cost the next morning against the same session with idleCompaction off.