Claude Code context window: what fills it before you type, and the 33 edits I wasted in July
- claude-code
- context-engineering
- agent-ops
The Claude Code context window is everything the model can see in your session. That means the system prompt, your CLAUDE.md, the auto memory index and tool descriptions, plus every file it reads and every reply it writes. It fills from the first message, and it fills before you type anything. The docs now show that startup cost with numbers, and the numbers explain most of what went wrong for me in July.
- What it is. One token budget per request, holding instructions, history, files and answers together. The generic version is in the glossary; this post is the Claude Code specific one.
- What loads first. System prompt, CLAUDE.md, the first 200 lines or 25KB of MEMORY.md, MCP tool names, skill descriptions. In the docs' representative session the system prompt alone is about 4,200 tokens before your first prompt.
- How to see it.
/contextfor a live breakdown, or a status line readingcontext_window.used_percentageafter every message. - What happens when it is full. Older tool outputs are cleared first, then the conversation is summarized. A fixed list of things comes back from disk; the rest survives only as summary.
- What I got wrong. 33 wasted edit calls in one week in July, before the rule went into my CLAUDE.md: read the file again in the current window before you edit it.
The one setting I look at more than any other is the status line from the statusLine post; it is where the percentage in this post comes from. The running verdict on the tool itself lives in the Claude Code entry of my tool list.
How big is a 200K context window?
200,000 tokens, where a token is a piece of a word, not a word or a line. In Claude Code that budget holds the system prompt, project instructions, memory, tool descriptions, every file the model reads and every reply it writes. In the docs' representative session the system prompt alone takes about 4,200 of them before your first prompt.
The rest is arithmetic against your own files. My project CLAUDE.md is 244 lines and
24 KB. My auto memory index, MEMORY.md, is 101 lines and 19.9 KB. Per
the memory docs only its first 200 lines or
25KB load at all, so the 538 files in that memory directory cost nothing until Claude
reads one. I have 56 skills installed, and their one-line descriptions load as a
list. None of that is the conversation yet. If tokens are fuzzy, start with
what a token is.
Does Claude code have a 1 million context window?
Yes, on specific models. Per the model configuration docs,
Fable 5.1, Fable 5, Sonnet 5, Opus 4.6 and later, and Sonnet 4.6 support a 1 million
token context window. On the Anthropic API, Fable 5.1, Fable 5, Sonnet 5 and Opus 4.7
and later run at 1M by default. Select it with a [1m] suffix such as
/model opus[1m].
Two details matter before you flip it. First, the plan. The docs' table gives Opus
with 1M as included on Max, Team and Enterprise, while Sonnet 4.6 with 1M requires
usage credits on those plans; on Pro both require usage credits; on the API and
pay-as-you-go both are full access. Sonnet 5 on the API always runs at 1M, with no
[1m] suffix to select and no usage credits required on any plan. Second, the
opt-out. CLAUDE_CODE_DISABLE_1M_CONTEXT=1 makes Claude Code treat a native 1M model
as a 200K one, and with auto-compaction on, "sessions compact at the 200K boundary".
A bigger window is not a smaller conversation. The context window docs put it plainly: "Compaction works the same way at the larger limit." What changes is how long you go before it runs, and how much sits in front of the model on every turn.
What fills the window before you type
The context window docs walk a full session as a timeline with representative token counts. I am quoting the representative numbers, not measurements of my machine. Before the first prompt:
| Loaded at startup | Representative size | Notes from the docs |
|---|---|---|
| System prompt | about 4,200 tokens | "Always loaded first. You never see it." |
Auto memory (MEMORY.md) | about 680 tokens | first 200 lines or 25KB, whichever comes first |
| Environment info | about 280 tokens | directory, platform, shell, OS, git state as a separate block |
| MCP tool names | about 120 tokens | schemas stay deferred and load on demand via tool search |
| Project CLAUDE.md | about 1,800 tokens | representative; rules without paths: load with it |
User ~/.claude/CLAUDE.md | about 320 tokens | representative |
| Skill descriptions | your list | one line per skill; skill bodies load only when used |
Two rows deserve a second look. The MCP row is small because tool definitions are
deferred by default; per how Claude Code works,
"only tool names and server instructions consume context until Claude uses a
specific tool". The skill row has a twist I covered in
the disable-model-invocation post: a skill with
disable-model-invocation: true is not in the startup list at all, so it costs zero
context until you type its slash command.
An output style or text from --append-system-prompt goes into the system prompt
the same way. So does the size of your CLAUDE.md. The memory docs say to target
under 200 lines per file; mine is 244, and a chunk of that is rules I wrote after
the incidents in this post. That is not a contradiction, it is the bill.
How to show context window in Claude code?
Run /context. The docs describe it as a live breakdown by category, with
suggestions and the list of memory files that actually loaded.
It is the only view that tells you what is in the window rather than what the
timeline predicts. For a number that stays on screen, a status line can print
context_window.used_percentage after every assistant message.
Mine does. The statusLine setting runs a script with a JSON snapshot of the session
on stdin, and that snapshot carries context_window.used_percentage next to the
model, cost and rate limits. My script draws a 10-cell bar with the percent and
used/size, so the number is in the corner of the terminal all day. There is no plugin
to install for this; the field is in the payload Claude Code already sends.
The trap I fell into was the tool I used before writing my own. It computed usage by
scanning my session history, 916 files and 763 MB at the time, on every render. Each
refresh took 13 to 20 seconds, and with its cache on, the counter froze at a stale
value while the real window kept filling. A context gauge that lags is worse than no
gauge, because you stop checking /context once you trust the bar.
What happens when the context window in Claude Code is full?
The session does not end. Per how Claude Code works, Claude Code "clears older tool outputs first, then summarizes the conversation if needed." The docs add: "Your requests and key code snippets are preserved; detailed instructions from early in the conversation may be lost." The compacted session then reloads a fixed set of things from disk and continues from the summary.
The reload list is the part worth memorizing, because it decides what you can rely on after the pass. From the context window docs, condensed:
| Mechanism | After compaction |
|---|---|
| System prompt and output style | Unchanged; not part of message history |
| Project-root CLAUDE.md and unscoped rules | Re-injected from disk |
| Auto memory | Re-injected from disk |
| The plan written in plan mode | Re-injected from disk |
Rules with paths: frontmatter, nested CLAUDE.md | Reloaded when Claude reads matching files again |
| Files Claude read or edited | Up to five re-read, most recently modified first; a file over 5,000 tokens comes back as a path reference |
| Invoked skill bodies | Re-injected, capped at 5,000 tokens per skill and 25,000 total, oldest dropped first |
| Context that hooks added earlier | Summarized with the rest |
SessionStart hooks matching the compact source | Run again, output added to the compacted context |
Three consequences follow. Anything you said only in conversation is now a summary of
itself, which is why the docs repeat "put persistent rules in CLAUDE.md". The skill
descriptions list is not re-injected, only the bodies of skills you invoked, so the
startup index shrinks after the pass. And a large file you edited earlier may come
back as Referenced file rather than Read, which is one of the cases behind
the 33 edits below.
When compaction runs depends on the model and on whether you set a window yourself.
Per the model configuration docs, if you do not set an auto-compact window, sessions
compact when the conversation reaches the model's context limit, with named
exceptions: cloud sessions compact as the conversation approaches the limit, Sonnet
4.6 and Opus 4.6 without extended context compact at the 200K boundary, and so do
models with a native 1M window when CLAUDE_CODE_DISABLE_1M_CONTEXT=1 is set.
Sonnet 5 compacts at the threshold for its own configuration. One failure mode is
documented too: if a single file or tool output is so large that the
window refills right after each summary, Claude Code stops auto-compacting after a few
attempts and shows an error instead of looping.
claude code compact
/compact is the manual version of the automatic pass, and it takes instructions.
The docs' example is /compact focus on the auth bug fix: the summary keeps what you
name rather than what the automatic pass would pick on its own. The other standing
option is a "Compact Instructions" section in CLAUDE.md, which shapes every
compaction in that project.
When deciding whether to choose summarization or checkpoint recovery, identify whether the problem is conversation length, unwanted file edits or both.
Four more controls sit next to it:
/rewind, then pick a message and choose "Summarize from here" or "Summarize up to here". That compacts part of the conversation rather than all of it./autocompact 500ksets how full the window gets before the automatic pass. The docs accept a plain token count such as200000, akorMsuffix, or a bare number from 100 to 1000 meaning thousands; the window can range from 100K to 1M. The value is saved to your user settings asautoCompactWindow. The same knob exists asclaude --autocompact 500kfor one launch and as theCLAUDE_CODE_AUTO_COMPACT_WINDOWenvironment variable for scripts. The docs give the precedence: environment variable, then flag, then command, then setting./clearbetween unrelated tasks. The docs' reasoning is blunt: old conversation "crowds out the files you need next and costs tokens on every message".- A subagent for large reads. It works in its own window; only a summary and a small metadata trailer come back to yours. I lean on this daily, and the post on Claude Code subagents is the longer version.
If your model ID is a gateway alias Claude Code does not recognize, the window it
assumes may be wrong; CLAUDE_CODE_MAX_CONTEXT_TOKENS declares the real one, with
the caveats the model configuration page lists per ID type.
What I got wrong after compaction
The edit that needs a fresh read. The edit tool refuses to change a file it has not read in the current window. After compaction, a file you edited an hour ago may be back only as a path reference, and the tool treats that as unread. In the week of 9 to 16 July I logged 33 wasted edit calls before I wrote the rule down. The fix is a single line in my CLAUDE.md: read the file again, even a fragment, before you edit it. That covers three cases. Any edit after compaction. A return to a file you edited earlier in the session. A retry after a "modified since read" error. Do not assume you know the content because you wrote it; the tool counts reads per context window, not per session.
The read that was too big. Reading one large file in a single call came back as "Output too large (109.9KB)", and I did not get the whole file at all. The rule that followed: read on purpose, not in bulk. Anything over roughly 20 KB gets a search for its headings and a read of the one section that matters. The window is a budget, and a truncated read spends it twice, once for the read and once for the wrong conclusion.
The gauge that lied. Covered above: 13 to 20 seconds per render, then a cached counter frozen at a value the window had long passed. I replaced it with a script that reads only the stdin payload and returns in a median of 41 ms.
The index that is the whole memory. 538 memory files on disk, one index in
context. Claude Code loads the index and reads topic files on demand, which is the
right design, and it means a memory the index does not point to does not exist for
the session. The size limit on MEMORY.md is the size limit on what the session can
recall unprompted.
The judge that starts fresh on purpose. On this site the draft is written by a fork that inherits the whole conversation, and the review by a subagent with an empty window and only the brief, so the debate that produced the text cannot sway it. Same tool, opposite reason for choosing the window.
Codex CLI: /status and context left
The same question on the other terminal agent. The
Codex CLI docs list /status as "show
current session configuration". The same page shows an interface footer that reads
100% context left. The page does not say the command prints that figure, so I am
reporting two separate lines from one page. That page does not document a /compact
command or a compaction pass; I did not find one there, and I am not claiming it does
not exist elsewhere. Cursor and
Copilot were not checked for this post.
The rules I keep
- Look at
/contextonce per session before the real work, and read the status line after that. If the bar is stale, trust/context. - Rules go in CLAUDE.md, not in the conversation. Conversation is what compaction summarizes; the project-root file is what it reloads.
- Fresh read before an edit after compaction. Every time.
- Read the section, not the file, above about 20 KB.
- Send large reads to a subagent and keep the summary.
/compactwith a focus before a long new task;/clearwhen the task is unrelated.- Flag skills you only invoke by hand with
disable-model-invocation: true, and let the startup list shrink. - The 1M window is a longer runway, not a different airplane.