Assistants How-to

Claude Code now compacts your idle session before the cache expires. Here's when that saves money and when it costs you

Leave a 200K-token conversation alone for about 54 minutes and Claude Code summarises it while the cache is still warm. The conditions, the two knobs, and a cost model for the trade.

A wireframe terrain ridge sinking into a smooth bowl of glowing contour lines

You step away from a long Claude Code session for lunch. An hour and a bit later you type a one-line follow-up, and that single message reprocesses the whole conversation from scratch, because the one-hour prompt cache lapsed while you were gone. At 400,000 tokens of context on Sonnet 5.5, that one line costs about $1.60 before the model has said anything.

Claude Code now tries to prevent this on its own. Per the settings reference, idle compaction summarises a long conversation that you’ve stepped away from, shortly before its prompt cache expires, so your next message sends a summary instead of the whole history. It’s on by default, it needs Claude Code v2.1.290 or later, and it only fires in a specific set of circumstances. Knowing which ones tells you whether it’s helping you or quietly replacing your context with a summary you didn’t ask for.

When it fires

The docs list five conditions, and all of them have to hold:

  1. You’re in an interactive terminal session.
  2. The conversation is on the one-hour prompt cache TTL.
  3. Claude Code can fetch feature flags from Anthropic.
  4. The context has reached the token threshold, 200,000 by default.
  5. About 54 minutes have passed since the last request, and your computer is awake at that point.

Condition 2 is the one that decides whether you ever see it. According to the Claude Code cost docs, the main conversation gets a one-hour lifetime on a subscription, and drops to five minutes once you’re drawing on usage credits. On an API key or a cloud provider the default is five minutes. A five-minute cache can’t be compacted “shortly before it expires” in any useful way, so API-key sessions simply don’t get this behaviour unless they’ve opted into the longer lifetime. The earlier piece on idle gaps and cache TTLs covers the promptCacheTtl setting that does that.

Condition 5 explains the odd number. The cache lasts an hour, so compaction runs at about 54 minutes, early enough that the summarisation request still reads your history from the cache instead of paying to rewrite it. If the laptop is asleep at the 54-minute mark, nothing happens, and you’re back to the cold-cache resume.

When it has run, the conversation shows a line reading Compacted while idle, before the prompt cache expired. That line is the only sign you get, so it’s worth knowing what it means when you see it on return.

What the compaction request costs

Compaction isn’t free. The docs describe the mechanism: Claude Code sends a separate request with the same system prompt, tools and history as the conversation, plus a summarisation instruction, and the result replaces the message history. While the cache is warm, that request reads the prefix from the cache. After the cache has lapsed, the same request reprocesses the full history as uncached input, which the docs give as the reason /compact costs the most when you resume an old session.

So the whole feature is a bet on timing. Compact at minute 54 and you pay cache-read price for the history plus output price for the summary. Compact after minute 60 and you pay to rewrite everything first. Idle compaction exists to land on the first side of that line.

Here’s a small model to put numbers on it. It uses Sonnet 5.5 list prices from the Anthropic pricing page: $2 per million input tokens, $10 per million output, $4 for a one-hour cache write and $0.10 for a cache read. The 15,000-token summary is an assumption, because the real size varies by session. Each case includes 20 further turns of 3,000 new tokens each after the break.

# Sonnet 5.5 list prices, USD per million tokens
READ, WRITE_1H, OUT = 0.10, 4.00, 10.00

def usd(tokens, rate):
    return tokens * rate / 1e6

def resume(context, summary, later_turns=20, step=3_000):
    """Cost of coming back after a break longer than one hour, plus later turns."""
    # Without idle compaction: the 1h cache has lapsed, so the whole history is rewritten.
    a = usd(context, WRITE_1H)
    ctx = context + step
    for _ in range(later_turns):
        a += usd(ctx, READ) + usd(step, WRITE_1H)
        ctx += step
    # With idle compaction at ~54 minutes: the summary request reads the warm prefix,
    # generates the summary, and the next turn writes only the summary.
    b = usd(context, READ) + usd(summary, OUT) + usd(summary, WRITE_1H)
    ctx = summary + step
    for _ in range(later_turns):
        b += usd(ctx, READ) + usd(step, WRITE_1H)
        ctx += step
    return a, b

for context in (200_000, 400_000, 800_000):
    a, b = resume(context, summary=15_000)
    print(f"context {context:>7,}: no idle compaction ${a:5.2f}  idle compaction ${b:5.2f}")

# Cost of an unwanted compaction: back at 56 minutes, cache still warm
ctx = 400_000
print(f"compaction you didn't need at 400,000: ${usd(ctx, READ) + usd(15_000, OUT):.2f} before the first message")

Run it and it prints:

context 200,000: no idle compaction $ 1.50  idle compaction $ 0.56
context 400,000: no idle compaction $ 2.70  idle compaction $ 0.58
context 800,000: no idle compaction $ 5.10  idle compaction $ 0.62
compaction you didn't need at 400,000: $0.19 before the first message

The saving grows with the size of the conversation, because the summary is roughly the same size whatever it replaced. Most of the gap isn’t the resume turn alone. After the break, every later turn re-reads the context, and a 15,000-token context is a lot cheaper to re-read than a 400,000-token one.

Two caveats on those numbers. The model ignores output tokens from the model’s replies, and it assumes the summary is 15,000 tokens. A bigger summary narrows the gap, and a conversation that’s about to end after one more message benefits less than one you’ll work in for another hour.

The cost you can’t price

Look at the last line of the output. If you come back at minute 56 instead of minute 75, the cache would still have been warm. Resuming would have cost a few cents of cache reads on a 400,000-token history. Instead, you paid about 19 cents for a compaction nobody asked for, and the conversation is now a summary.

The dollar figure is the small part. A summary drops detail, and the detail it drops is whatever the summariser judged unimportant: the exact error text from an hour ago, the reason you rejected the second design, a file path you’d mentioned once. For a session that’s mid-investigation, that can be worth far more than 19 cents. The docs make the same point about compaction in general: it works in your favour when the context you discard is content you no longer need.

That suggests a rule of thumb, which is opinion rather than documented behaviour. Idle compaction is a good deal for sessions that have gone quiet because the task is finished or parked. It’s a poor deal for a session that is mid-debug and you’ll be back in an hour with the same question open.

Tune it or turn it off

There are two controls. Both are documented, and neither was run for this article, since they only show up in a live interactive session.

To change the size at which it applies, set CLAUDE_CODE_IDLE_COMPACT_MIN_TOKENS in the env block of any settings file. It takes a positive whole number, and anything below 100,000 is raised to 100,000, the lowest threshold:

{
  "env": {
    "CLAUDE_CODE_IDLE_COMPACT_MIN_TOKENS": "350000"
  }
}

Raising the threshold trades saving for detail. In the model above, a break saves about 94 cents at 200,000 tokens and about $4.50 at 800,000, so the larger the conversation, the stronger the case for letting it compact. An opinion: 350,000 leaves the mid-sized sessions with their full history and still catches the expensive ones.

To switch it off, set idleCompaction to false:

{
  "idleCompaction": false
}

Two related switches are worth knowing. DISABLE_AUTO_COMPACT turns idle compaction off along with auto-compaction, and so does turning auto-compact off in settings. The manual /compact command keeps working in both cases, so you can still compact deliberately at a natural break.

Work out whether it’s firing for you

Before changing anything, check whether you’re on the path where it can fire. Claude Code 2.1.251 or later adds a Prompt cache (main) line to the Session block of /usage. The docs show its shape:

Prompt cache (main):   14 requests · 91% of input tokens from cache · 2 misses (last 6m 10s ago, 310.2k tokens re-cached) · 1 expected rebuild (compaction or tool-result clearing) · warm (1h TTL, last activity 40s ago)

Two parts matter here. The TTL in the final clause tells you whether condition 2 holds: 1h TTL means you’re eligible, 5m TTL means this feature will never run for the session. And “expected rebuild” is how the line counts a compaction, which separates a cache miss you caused from one the cache expiry caused.

If you’re on a 5m TTL and regularly leave long sessions idle, you have a choice to make that’s bigger than this feature. Either set the longer lifetime on the main conversation, which makes idle compaction available, or keep sessions short and /clear between tasks, which makes the problem go away without a summary. The cost docs list clearing between unrelated tasks as the cheapest option, because /clear costs nothing.

What to do with a compacted session

When you come back to a conversation that says it compacted while idle, don’t assume the agent still knows what you were doing. Ask it to restate the state before it acts. A prompt like this works:

You were compacted while I was away. Before continuing, list: the task, what's
done, what's still failing and the exact error, and the next step you were
about to take. Don't edit anything yet.

If the restatement is wrong or thin, the summary dropped something that mattered, and you’ve found that out for the price of one short turn rather than after a bad edit. Paste back whatever’s missing, then continue.

Pair that with writing durable state to disk for any session you expect to park. A PROGRESS.md or a short plan file survives compaction, a /clear and a fresh start alike, and it makes the summariser’s choices less important.

Don’t bother if

Skip tuning entirely if your sessions rarely pass 200,000 tokens, or if you work on an API key with the default five-minute cache. In both cases the feature never fires, and there’s nothing to adjust.

Turn it off rather than tune it if you run long investigations that you leave and return to, because you’ll value the exact history over the saving. Otherwise, the first change to try this week is the threshold: set it to 350,000, then check /usage after your next long break to see whether the cache was warm or cold.