Auto-compact is Claude Code summarizing your conversation when the context window gets close to full, so a long session can keep going. This guide covers when it runs, how to turn it off with the autoCompactEnabled setting, how /compact and /clear differ, and what survives a compaction. Claude Code has no setting that warns you before it compacts, though. So the last part shows how to get that warning: a statusline script you can write yourself, or anotifier 1.6.0 and later, once per chat at 85% by default. Unlike usage-limit warnings it needs no Claude.ai subscription, so it works on API-key and proxy sessions too. For an alert when Claude finishes or needs you, see the Claude Code notifications guide.
Rather skip the manual setup? One command wires every agent you have installed to desktop toasts, phone push, and Slack, Discord or Telegram:
Updated 2026-10-16 · also see the Claude Code notifier and the full docs
When the context window approaches its limit, Claude Code clears older tool outputs first, then summarizes the conversation so the session can continue instead of ending. That is auto-compact. /compact does the same on demand, and /context shows what is filling the window right now.
By default it runs when the conversation reaches the model's context limit, with these exceptions:
CLAUDE_CODE_DISABLE_1M_CONTEXT=1 makes them compact at 200K instead.How full the window gets before Claude Code compacts is the auto-compact window, and you can move it:
/autocompact 500k saves a window for the current model, and /autocompact auto returns to the default. It accepts 100K to 1M tokens and needs Claude Code v2.1.221 or later.autoCompactWindow in a settings file, such as "autoCompactWindow": 200000 in ~/.claude/settings.json, sets it for every model.claude --autocompact 500k applies for one launch without changing your saved setting.CLAUDE_CODE_AUTO_COMPACT_WINDOW sets it in scripts and cloud environments, as a plain integer such as 500000. While it is set it overrides the command, the flag and the setting.CLAUDE_AUTOCOMPACT_PCT_OVERRIDE sets a percentage from 1 to 100 of the window at which compaction triggers. It can only lower the point, not raise it, and applies only in sessions that compact before the model's context limit.The switch is the autoCompactEnabled setting, a boolean that defaults to true. It appears in /config as Auto-compact, and toggling it there writes the key to your user settings. You can also set it by hand in any settings file, for example ~/.claude/settings.json:
{
"autoCompactEnabled": false
}For one session or script, use the environment variable instead, either exported in your shell or in the env block of a settings file:
{
"env": {
"DISABLE_AUTO_COMPACT": "1"
}
}DISABLE_AUTO_COMPACT=1 overrides autoCompactEnabled, so setting the key to true does not turn auto-compact back on while the variable is set./compact command keeps working.DISABLE_COMPACT=1 is stronger: it disables all compaction, including /compact.autoCompactEnabled to true (or toggle it in /config) and remove the environment variable./compact replaces the conversation history with a summary and keeps the same session going. It takes optional focus instructions, so the summary keeps what you choose instead of what the automatic pass guesses matters:
/compact
/compact focus on the auth bug fix
/compact Focus on the API changesCLAUDE.md, such as "When compacting, always preserve the full list of modified files and any test commands", and it applies to every compaction.Esc twice or run /rewind, pick a message, and choose Summarize from here or Summarize up to here.| Compare | /compact | /clear |
|---|---|---|
| What it does | Replaces the history with a summary | Starts a new conversation with empty context |
| Same session? | Yes, the conversation continues | No. The old conversation is saved, and /resume brings it back |
| What Claude keeps | The summary, plus what is re-loaded from disk (see below) | Nothing from the conversation. Project memory still applies |
| Arguments | /compact [instructions]: what the summary should focus on | /clear [name]: a label for the old conversation in the /resume picker. Aliases: /reset, /new |
| Use it when | You are mid-task and the context is filling up | You are switching to unrelated work |
In short: compact to carry on with the same task, clear to start a different one. Old conversation crowds out the files you need next and costs tokens on every message, so clearing between unrelated tasks is the cheaper habit.
The conversation becomes a summary. What else carries over depends on how it was loaded:
| What | After compaction |
|---|---|
Project-root CLAUDE.md and unscoped rules | Re-injected from disk |
| Auto memory | Re-injected from disk |
| Files Claude read or edited | Up to five are re-read, most recently modified first. A file over 5,000 tokens comes back as a path reference |
| Invoked skills | Re-injected, capped at 5,000 tokens per skill and 25,000 in total. The oldest are dropped first |
Rules with paths: frontmatter, nested CLAUDE.md | Reloaded on demand. What was loaded earlier is summarized away |
| Background commands and subagents | Keep running |
SessionStart hooks that match compact | Run again, and their output is added to the compacted context |
| Instructions you gave only in the chat | Summarized with the rest, and may be lost |
So anything that must survive belongs in the project-root CLAUDE.md, not in a message. The automatic pass works the same way as /compact.
Claude Code has no setting that warns you before it auto-compacts a chat. It does pass the chat's context size to your statusLine command as context_window.total_input_tokens on stdin, while hook input carries no context_window field. So a warning has to live in a statusline script: compare that number with the auto-compact window and send a notification when the chat gets close.
There are two ways to get one. Write the script yourself, or let anotifier do it. Both need to know which window to measure against, because the auto-compact window can sit below the model's full window. How anotifier finds that window is below.
Claude Code runs your statusLine command and writes a JSON session object to its stdin. These fields matter here:
{
"session_id": "3f9a1c2e-0000-0000-0000-000000000000",
"model": {
"display_name": "Opus"
},
"context_window": {
"total_input_tokens": 174000,
"context_window_size": 200000
}
}total_input_tokens counts input plus cache creation plus cache read tokens, and is 0 before the first API response of a session.context_window_size is the model's full window, not the auto-compact window./compact, at session start, and on a few other events. A new run cancels one that is still going, so keep the script fast.This Node script prints a short status line and sends an ntfy push once per chat when it passes 85% of the auto-compact window. It reads the window from CLAUDE_CODE_AUTO_COMPACT_WINDOW when that is set in the statusline's environment, otherwise it uses the model's window, and it never reads the /autocompact setting, so if you changed that, lower the 85 or read the setting yourself. It remembers each warned session_id in .context-alert.json in your Claude config folder (CLAUDE_CONFIG_DIR, or ~/.claude), and records one only after the send succeeds, because a cancelled run would otherwise lose the warning for good. It needs Node 18 or later. Save it as ~/.claude/context-line.mjs:
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
const input = JSON.parse(fs.readFileSync(0, "utf8"));
const model = input.model?.display_name ?? "Claude";
const tokens = input.context_window?.total_input_tokens;
const full = input.context_window?.context_window_size;
if (!(tokens > 0) || !(full > 0) || !input.session_id) {
process.stdout.write("[" + model + "]\n");
} else {
const env = Number.parseInt(process.env.CLAUDE_CODE_AUTO_COMPACT_WINDOW, 10);
const clamped = Math.min(1000000, Math.max(100000, env));
const window = Math.min(full, env > 0 ? clamped : full);
const exact = Math.min(100, (tokens / window) * 100);
const pct = Math.round(exact);
process.stdout.write("[" + model + "] ctx " + pct + "%\n"); // print first
const dir = process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), ".claude");
const file = path.join(dir, ".context-alert.json");
let warned = {};
try {
warned = JSON.parse(fs.readFileSync(file, "utf8"));
} catch {}
if (exact >= 85 && !warned[input.session_id]) {
const res = await fetch("https://ntfy.sh/your-secret-topic", {
method: "POST",
headers: { Title: "Claude Code context at " + pct + "%", Priority: "high" },
body: "Close to auto-compact. Wrap up or run /compact.",
signal: AbortSignal.timeout(3000),
}).catch(() => null);
// Record it only after a successful send, so a cancelled run retries.
if (res?.ok) {
warned[input.session_id] = Date.now();
try {
fs.mkdirSync(dir, { recursive: true });
fs.writeFileSync(file, JSON.stringify(warned));
} catch {}
}
}
}Then point Claude Code at it in ~/.claude/settings.json:
{
"statusLine": {
"type": "command",
"command": "node ~/.claude/context-line.mjs"
}
}npx anotifier@latest setupanotifier sends one notification per chat when its context passes 85% of the auto-compact window. The title carries the percentage, such as Claude Code · context at 87%, and the body names the chat and the size: my-app [3f9a1c2e] is at 87% of its auto-compact window (174K of 200K tokens). It will compact soon — wrap up or /compact now. Priority is high.
session_id warns once and never again, even after /compact brings its context back down. /clear starts a new session, which can warn again. Warned chats are remembered in ~/.anotifier/.context-alerts.json and forgotten after 14 days.autoCompactEnabled: false in the settings files it reads, and DISABLE_AUTO_COMPACT or DISABLE_COMPACT when the variable is set in the environment the statusline runs in.It uses the same statusline wiring as the usage limit warnings: setup points the Claude Code statusLine at anotifier's statusline.mjs, wraps a statusline you already have so it still prints your line, and npx anotifier uninstall restores it. anotifier status shows whether the context warning is on and its threshold.
Change the threshold or turn the warning off in ~/.anotifier/config.json. This is the default:
{
"contextAlerts": {
"enabled": true,
"threshold": 85
}
}threshold is a percentage above 0 and at most 100. An invalid value is reported and 85 applies. Set enabled to false to stop the checks; the statusline and the usage warnings keep working.
A percentage measured against the model's full window runs low, because auto-compact can fire earlier. Claude Code's own context_window.used_percentage is measured against the full window, not the auto-compact window, so anotifier does not use it. It works out the auto-compact window in this order, and stops at the first hit:
CLAUDE_CODE_AUTO_COMPACT_WINDOW environment variable, clamped to 100,000 to 1,000,000 tokens. It overrides the setting.autoCompactWindow setting that /autocompact writes, clamped the same way. A per-model value (modelSettings.<model id>.autoCompactWindow, written by Claude Code 2.1.288 and later) wins over the top-level key in the same file. Files are read in this order: <project>/.claude/settings.local.json, <project>/.claude/settings.json, then settings.json in $CLAUDE_CONFIG_DIR (default ~/.claude).context_window.context_window_size.The result never goes above the model's window. If auto-compact is switched off (DISABLE_AUTO_COMPACT or DISABLE_COMPACT set to a true value such as 1, true, yes or on, or autoCompactEnabled: false in the first settings file that defines it), nothing will compact and nothing is sent.
--autocompact command-line flag and managed (enterprise) settings never reach it, so with either in play the warning can come late or not at all.refreshInterval on statusLine.contextAlerts.threshold to match, for example 40 for an override of 50.Checked on 2026-10-16. Docs change, so confirm a setting there before you rely on it.
Auto-compact is Claude Code summarizing your conversation when the context window approaches its limit. It clears older tool outputs first, then summarizes the rest, so a long session keeps going instead of ending. /compact does the same on demand.
By default when the conversation reaches the model's context limit. Sonnet 4.6 and Opus 4.6 without extended context compact at the 200K boundary, and models with a native 1M window compact at about 967K tokens. You can move the point with /autocompact, the autoCompactWindow setting, the --autocompact flag or the CLAUDE_CODE_AUTO_COMPACT_WINDOW environment variable.
Set autoCompactEnabled to false in a settings file such as ~/.claude/settings.json, or switch Auto-compact off in /config. For one session set the environment variable DISABLE_AUTO_COMPACT=1. The manual /compact command keeps working. DISABLE_COMPACT=1 turns off all compaction, /compact included.
It is a boolean that defaults to true. When false, Claude Code does not compact the conversation automatically, and idle compaction turns off too. It works in any settings file, and /config writes it to your user settings. DISABLE_AUTO_COMPACT=1 overrides it, so the setting cannot turn auto-compact back on while that variable is set.
/compact replaces the conversation with a summary and continues the same session, and takes optional focus instructions such as /compact focus on the auth bug fix. /clear starts a new conversation with empty context; the old one is saved and /resume brings it back. Compact to carry on with a task, clear to switch to another.
Not with a setting, but it passes the chat's context size (context_window.total_input_tokens) to your statusLine command, so a script there can send a notification. anotifier 1.6.0 and later does this for you, once per chat at 85% of the auto-compact window it finds from your settings, and sends nothing when auto-compact is off. Change the percentage with contextAlerts.threshold in ~/.anotifier/config.json.
No. Each chat warns once and never again, even after /compact. /clear starts a new session, which can warn again.
One command wires every agent you have installed: Claude Code, Codex CLI, Cursor, and Gemini CLI.
npx anotifier@latest setup