anotifier / guides / claude-code-auto-compact-warning
[ GUIDE · CLAUDE CODE AUTO-COMPACT ]
Claude Code logo

Claude Code auto-compact: what it does, how to turn it off, how to get warned first

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:

$ npx anotifier@latest setup

Updated 2026-10-16 · also see the Claude Code notifier and the full docs

What auto-compact is and when it triggers

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:

  • Sonnet 4.6 and Opus 4.6 without extended context compact at the 200K boundary.
  • Models with a native 1M window, such as the Fable models, Sonnet 5 and later, Haiku 5.5, and Opus 4.7 and later, compact before the window fills, at about 967K tokens by default. Setting CLAUDE_CODE_DISABLE_1M_CONTEXT=1 makes them compact at 200K instead.
  • A model ID Claude Code does not recognize, such as an LLM gateway alias, compacts at the window Claude Code assumes for that ID.
  • Cloud sessions compact as the conversation approaches the model's limit.

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.

How to turn auto-compact off or on

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.
  • Turning auto-compact off also turns off idle compaction. The manual /compact command keeps working.
  • DISABLE_COMPACT=1 is stronger: it disables all compaction, including /compact.
  • To turn it back on, set autoCompactEnabled to true (or toggle it in /config) and remove the environment variable.

Manual /compact, with focus instructions

/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 changes
  • Compact at a natural break, such as before a long new task, rather than letting auto-compact fire in the middle of one.
  • Make the focus permanent. Add a line to CLAUDE.md, such as "When compacting, always preserve the full list of modified files and any test commands", and it applies to every compaction.
  • Compact only part of a chat. Press Esc twice or run /rewind, pick a message, and choose Summarize from here or Summarize up to here.

/compact vs /clear

Compare/compact/clear
What it doesReplaces the history with a summaryStarts a new conversation with empty context
Same session?Yes, the conversation continuesNo. The old conversation is saved, and /resume brings it back
What Claude keepsThe 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 whenYou are mid-task and the context is filling upYou 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.

What happens to your context after compaction

The conversation becomes a summary. What else carries over depends on how it was loaded:

WhatAfter compaction
Project-root CLAUDE.md and unscoped rulesRe-injected from disk
Auto memoryRe-injected from disk
Files Claude read or editedUp to five are re-read, most recently modified first. A file over 5,000 tokens comes back as a path reference
Invoked skillsRe-injected, capped at 5,000 tokens per skill and 25,000 in total. The oldest are dropped first
Rules with paths: frontmatter, nested CLAUDE.mdReloaded on demand. What was loaded earlier is summarized away
Background commands and subagentsKeep running
SessionStart hooks that match compactRun again, and their output is added to the compacted context
Instructions you gave only in the chatSummarized 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.

How to get warned before auto-compact runs

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.

DIY: a statusline script that reads total_input_tokens

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.
  • Claude Code runs the statusline again after each assistant message, after /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"
  }
}

With anotifier 1.6.0 and later

npx anotifier@latest setup

anotifier 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.

  • Once per chat. Each 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.
  • It reaches the channels you have on. Desktop toast, ntfy push and webhook. It never rings the terminal bell, because a statusline has no terminal of its own.
  • Snooze and quiet hours hold it back. While either is active nothing is sent and nothing is recorded, so a chat already over the line is warned once it ends, if a statusline refresh happens.
  • No subscription needed. The context numbers come with every statusline refresh, so API-key and proxy sessions are covered, unlike the usage-limit warnings.
  • Silent when auto-compact is off. If you turned it off (see how to turn auto-compact off), there is nothing to warn about, so nothing is sent. anotifier sees 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.

How anotifier finds the auto-compact window

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:

  • The CLAUDE_CODE_AUTO_COMPACT_WINDOW environment variable, clamped to 100,000 to 1,000,000 tokens. It overrides the setting.
  • The 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).
  • The model's own window, 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.

Limits worth knowing

  • Some settings are invisible to a statusline. The --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.
  • An idle chat is not checked. The statusline runs on Claude Code's own events, so a chat you leave alone does not warn until it next refreshes, unless you set refreshInterval on statusLine.
  • One warning, not a countdown. After the warning a chat is never warned again, even if you keep working past it.
  • `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE` is not read. If you set it to compact earlier, anotifier still measures against the full auto-compact window, so the warning can come after the chat has already compacted. Lower contextAlerts.threshold to match, for example 40 for an override of 50.

Official docs this page follows

Checked on 2026-10-16. Docs change, so confirm a setting there before you rely on it.

Claude Code auto-compact: common questions

What is auto-compact in Claude Code?

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.

When does Claude Code auto-compact?

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.

How do I turn off auto-compact in Claude Code?

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.

What does the autoCompactEnabled setting do?

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.

What is the difference between /compact and /clear?

/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.

Can Claude Code warn me before it auto-compacts?

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.

Will anotifier warn again after I run /compact?

No. Each chat warns once and never again, even after /compact. /clear starts a new session, which can warn again.

Try it

One command wires every agent you have installed: Claude Code, Codex CLI, Cursor, and Gemini CLI.

npx anotifier@latest setup

Other guides