Add --max-context flag to cap context window usage
Status Fixed / completed
Maintainer reply None cached
Workaround ✓ Mentioned in thread ↓
Activity 14 comments · opened Mar 15, 2026 · closed Jun 6, 2026
Problem
With the recent upgrade of Opus 4.6 to 1M context, my API quota burns ~5x faster than before. I was working comfortably at 200K and have no need for 1M in most sessions. There's currently no way to limit the context window size Claude Code uses.
Proposed Solution
Add a --max-context <tokens> CLI flag (and/or a settings option) that caps the effective context window. For example:
claude --max-context 200000
This would:
- Trigger auto-compaction at the same relative thresholds (64-75%) but relative to the cap, not the model's max
- Prevent the context from growing beyond the specified limit
- Allow users to control their token spend per session
A settings-level default would also be useful:
{
"maxContextTokens": 200000
}
Use Case
- Quota management: Users on usage-based billing who don't need the full context window
- Consistent behavior: Researchers benchmarking across sessions want reproducible context sizes
- Cost control: Especially relevant as context windows keep growing (200K → 1M → ?)
Alternatives Considered
- Frequent /compact: Manual, error-prone, doesn't prevent the context from growing in between
- Shorter sessions: Loses continuity
- Hooks: PreToolUse hooks don't have access to current context token count, so can't build this as a workaround
Environment
- Claude Code on Windows (MSYS2/Git Bash)
- Opus 4.6 with 1M context
- Previously worked well with 200K limit
Showing cached comments. Read the full discussion on GitHub ↗
13 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
+1 on this. Running Opus 4.6 with 1M context on autonomous sessions, the cost difference is substantial.
Workaround I'm using now: A PostToolUse hook that monitors context usage percentage and forces compaction before it grows too large. The hook checks the conversation state after each tool call and warns (or blocks further tool calls) when context exceeds a threshold. It's not as clean as a native
--max-contextflag would be, but it does cap effective usage.The hook approach has a limitation though: it can only react after a tool call, so a single very large tool result can still push you past your target. A native flag that triggers compaction proactively at the API layer would be much more reliable.
A settings.json option like
"maxContextTokens": 200000would also be great for users who want to set it once rather than passing a flag every time.Thanks @yurukusa — interesting to see the same need independently!
I've implemented a similar workaround, but using the
UserPromptSubmithook instead ofPostToolUse. The approach:used_percentage(fromcontext_window) to a per-session JSON file (~/.claude/context_guard/<session_id>.json)additionalContext) when above a threshold (default 15% of model max = ~150K on 1M)"decision": "block") when above a higher threshold (default 20% = ~200K)/ctxguardskill lets you configure thresholds on the flyUserPromptSubmit has the advantage of blocking before the prompt is processed (cheaper — no wasted tokens), but PostToolUse catches growth mid-turn which is also valuable. Ideally both hooks would receive
context_windowdata directly.Code is at https://github.com/profff/isYourClaudeHappy (context_guard/ directory).
That said, this is clearly a workaround. A native
--max-contextflag or"maxContextTokens"in settings.json would be much cleaner and wouldn't require the statusline-to-file relay hack.Great approach with UserPromptSubmit — blocking before the prompt is processed is strictly cheaper than my PostToolUse path. The statusline relay is clever; I hadn't considered piping context_window data through a file to make it available to non-statusline hooks.
You're right that the two are complementary:
A defense-in-depth setup would use both: UserPromptSubmit as the primary gate, PostToolUse as the mid-turn safety net.
The core limitation for both is that neither hook receives
context_windowdirectly. If the team ever exposes that data in hook input (like they do in statusline), both approaches collapse to a few lines of bash with no file relay needed.Thanks for publishing the context_guard code — the session-scoped JSON file pattern is reusable for other stateful hooks too.
@yurukusa I added PostToolUse support to the hook (same script handles both events), but after testing I chose not to register it in settings.json.
The issue: a PostToolUse warning that says "stop and compact" mid-turn is disruptive — it can derail Claude's reasoning flow if it's in the middle of a multi-step operation. The UserPromptSubmit gate is cleaner: it blocks between turns, before any tokens are spent, and the user gets a clear "compact to continue" message.
PostToolUse is still useful as a concept if hooks ever gain the ability to gracefully interrupt a turn (like pausing before the next tool call), but today it can only inject additionalContext, which is too late to actually prevent the context from growing.
The code supports both events, just not wired up for PostToolUse. If someone wants the defense-in-depth setup they can add it to their settings.json.
Additional use case: cross-model session compatibility
On Claude Code Max subscription, Sonnet quota runs out faster than Opus quota. When Sonnet hits its weekly limit, switching to Opus 4.6 (1M context) mid-week is the natural fallback — but it creates a trap:
Sessions accumulate context under Opus 1M, then when trying to switch back to Sonnet (200K window), those sessions are too large for Sonnet to handle. The session is effectively locked to Opus for the rest of its life.
A per-session or global
maxContextTokens: 200000setting would let Opus behave like Sonnet context-wise, keeping sessions portable across model switches./compacthelps but is manual and doesn't prevent the session from growing large between compactions — it's a workaround, not a solution.@wanguardd Good point about cross-model portability — this is exactly why context_guard uses percentage of context window rather than absolute token counts. A threshold of 15% means ~150K on Opus 1M but ~30K on Sonnet 200K, so the same config works regardless of which model is active.
That said, we just added support for absolute token thresholds too (
/ctxguard set block 250K), which gets auto-converted to a percentage based on the active model'scontext_window_sizefrom the statusline data. Best of both worlds: set in tokens, stored as %, adapts on model switch.Still a workaround though. A native
--max-contextor"maxContextPercent"in settings.json would make all of this unnecessary.You can use the regular Opus 4.6 model with 200k context by typing:
/model opusI'm having the same issue. I use oh-my-pi (omp) and had it cook up an
extensions/context_guard.tsbased on your[context_guard.py](https://github.com/profff/isYourClaudeHappy/blob/master/context_guard/context_guard.py)to do the same thing. Thanks!Cozempic v1.6.11 already ships this. Set
COZEMPIC_CONTEXT_WINDOW=200000(or any size) to cap the effective context window. The guard daemon uses this for all threshold calculations. Also auto-detects 1M for current Opus/Sonnet models.pip install cozempic && cozempic init+1
An additional use case is when using local models (either for privacy/regulatory reasons, or because I'm either at the usage limit or trying to avoid hitting that limit). They default to 200K, but many local models support 256K or 1M.
One can "work around" this by choosing model names that "match" Opus--1m, but that's not nearly as clean or appropriate as just allowing one to explicitly specify what the total context window size is.
This smells like a money grab to inflate their value before they go public. Shameful. There is no other reason for this but to try to force people to buy more. Please support your userbase and add an option to rate limit. I tried to pick up where I left off last night on a project today. The rate limit kept telling me I could not continue. Ran a clear and my session had to essentially re-learn the project I have been working on for the last few days. Another waste of tokens.