◉CLAUDE LABJP
●2.1.302 — Fork subagents are now on by default in claude -p, the Agent SDK and the desktop app. Turn them off with CLAUDE_CODE_FORK_SUBAGENT=0 (10/16)●2.1.301 — Unattended retries now stop on their own when a usage limit is hit instead of waiting (10/15). Latest is 2.1.303 (10/18)●SONNET 4.5 — Retires on the Claude API on 11/30, 41 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST MODE — Opus 5.5 fast mode is out of research preview and no longer needs the beta header (10/15)●NEW — I Put a Ten-Line Promise File at the To…●2.1.302 — Fork subagents are now on by default in claude -p, the Agent SDK and the desktop app. Turn them off with CLAUDE_CODE_FORK_SUBAGENT=0 (10/16)●2.1.301 — Unattended retries now stop on their own when a usage limit is hit instead of waiting (10/15). Latest is 2.1.303 (10/18)●SONNET 4.5 — Retires on the Claude API on 11/30, 41 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST MODE — Opus 5.5 fast mode is out of research preview and no longer needs the beta header (10/15)●NEW — I Put a Ten-Line Promise File at the To…
Articles/Claude Code
⟐ Claude Code/2026-10-20Intermediate

You Stepped Away and Came Back to a Summary — Spotting Idle Compaction and Keeping the Details You Can't Lose

Since v2.1.299, Claude Code compacts a long conversation after about 54 idle minutes. Here is how to tell it happened, how to tune or switch it off, and how to move the assumptions you can't afford to lose into CLAUDE.md.

Claude Code268compactionprompt caching5troubleshooting95CLAUDE.md5settings.json10

I was reading the v2.1.299 changelog one morning when a single line stopped me: a conversation over 200K tokens that sits idle for about 54 minutes gets compacted before its one-hour prompt cache expires. As an indie developer, I step away from a long session and come back to it almost every day.

The first thing I want to say is that this is a feature, not a bug. But if Claude seems to have forgotten something you settled an hour ago, the cause may not be the model's mood. It may be this compaction.

What is actually happening

The changelog says that in the terminal, a conversation of 200K+ tokens left idle for roughly 54 minutes is compacted just before the one-hour prompt cache runs out, so your next message doesn't have to reprocess everything.

The goal is a shorter wait and a smaller bill when you return. The price is that the fine detail of the conversation is replaced by a summary. It only happens when all three of these hold:

ConditionDetail
WhereA terminal conversation
Size200K tokens or more (the default minimum)
Idle timeAbout 54 minutes, before the 1-hour cache expires

Short conversations and sessions you poke every few minutes are untouched. The longer you have nurtured a session, the more likely it is to qualify, which is the awkward part.

Checking whether it happened

A notice appears when compaction runs, and since v2.1.302 that notice also tells you how to turn it off. If you missed it, look for these signs:

  • The first reply after you return drops a file name, a rejected option, or a decision you had shared
  • A summary-like passage you didn't write appears in the middle of the conversation
  • Your Claude Code is older than v2.1.290, where the setting doesn't exist

This script checks the version and every settings layer at once, so you don't have to open each file by hand.

#!/bin/bash
# Report idle-compaction settings from user and project layers
echo "version: $(claude --version 2>/dev/null)"
for f in "$HOME/.claude/settings.json" ".claude/settings.json" ".claude/settings.local.json"; do
  [ -f "$f" ] || continue
  # "unset" means the default (enabled)
  v=$(jq -r 'if has("idleCompaction") then .idleCompaction else "unset" end' "$f")
  m=$(jq -r '.env.CLAUDE_CODE_IDLE_COMPACT_MIN_TOKENS // "unset"' "$f")
  echo "$f -> idleCompaction=$v, min_tokens=$m"
done

If everything says unset, compaction is on by default. Knowing which layer wins saves you from guessing when you add a setting later.

Narrowing the cause in three steps

When something feels forgotten, I check in this order, so I don't change settings in a hurry. First, how long was I away? Under about 54 minutes, it isn't idle compaction. Second, how big was the conversation? Under 200K tokens, it's out of scope. Third, run the script above: if idleCompaction is false, compaction didn't run and the cause is elsewhere. Only when all three fit do I treat idle compaction as the prime suspect. Blaming it without these checks can hide the real cause.

Turn it off, or just raise the bar

There are two ways to switch it off:

  1. Add "idleCompaction": false to settings.json (v2.1.290 or later)
  2. Use the "Idle compaction" row in /config (v2.1.302 or later)

Or keep it and raise the threshold with CLAUDE_CODE_IDLE_COMPACT_MIN_TOKENS:

{
  "idleCompaction": true,
  "env": {
    "CLAUDE_CODE_IDLE_COMPACT_MIN_TOKENS": "400000"
  }
}

I'd start with the threshold. Turning it off entirely means the first message after a long break pays the full cost of reprocessing an expired cache, and the longer the conversation, the heavier that message is. I'd rather reserve "off" for work where losing detail to a summary costs more than that.

The real fix: keep what you can't lose outside the conversation

Before touching settings, ask whether the information that hurt to lose lived only in the chat. I move three kinds of facts into a file every time:

  • Options I rejected, and why (so they aren't proposed again)
  • Files and directories that must not be touched
  • Where the work stands, and what comes next

I put them in a dated section at the end of CLAUDE.md, kept apart from permanent rules so cleanup is easy.

## Working notes (2026-10-20 — delete when done)
- Rejected: regenerating all files on every build (reason: a diff is enough)
- Do not touch: everything under scripts/legacy/
- Status: log formatting done. Next: retry limit on failure

Before I leave, I ask Claude to write the current working notes to the end of CLAUDE.md. For how I think about the file itself, see CLAUDE.md design.

How it ties to the cache

Idle compaction is built around the one-hour cache lifetime. If you want to design cache behavior more deliberately, prompt cache TTL and directory scope goes further. v2.1.300 also added cache_creation_5m_tokens and cache_creation_1h_tokens to the OpenTelemetry api_request event, so you can split cache writes by lifetime.

I don't yet have the records to say "switching it off paid for itself" in my own work. If you change the setting, I'd keep the same task running for a few days either side and write down the wait after you return and how many assumptions went missing.

One rule to take with you

What can't be lost goes in a file, not in the conversation. I keep to that whether compaction is on or off.

Today, before you step away, try writing one working note to the end of CLAUDE.md.

Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

⟐ Claude Code2026-10-19
If You Wrote MCP Allow Rules as Just `mcp__servername` — Three Lines to Recheck After v2.1.299
Claude Code v2.1.299 changed MCP allow rules to match only the server they name. Here is how to audit older entries in settings.json, with a short Python script that does it.
⟐ Claude Code2026-08-25
A One-Letter Typo in settings.json Is Ignored Without a Single Warning
I diffed claude doctor output between a settings.json with misspelled keys and a correct one. There was no difference at all. Here is what actually gets validated, what slips through, and a small check that catches typos before they cost you a day.
⟐ Claude Code2026-10-12
After Moving to SPM, My App Died the Moment It Launched — Reading One dyld Line with Claude Code
Right after moving from CocoaPods to Swift Package Manager, the build passed but the app died on launch. Here is how I traced one dyld line to its cause, the fix, and how to verify it.