CC v2.1.100+ inflates cache_creation by ~20K tokens vs v2.1.98 — same payload, server-side
Summary
Claude Code versions 2.1.100 and 2.1.101 consume ~20,000 more cache_creation_input_tokens per request than v2.1.98, despite sending fewer bytes in the request payload. The inflation is server-side and version-specific (likely User-Agent routing).
This is not a billing-only issue — these tokens enter the model's context window and may affect output quality.
Reproduction
# 1. Install proxy to capture full API request/response bodies
mkdir /tmp/cc-test && cd /tmp/cc-test
npx -y claude-code-logger@1.0.2 start --port 8000 --log-body --merge-sse
# 2. In another terminal — test with older version
export ANTHROPIC_BASE_URL="http://localhost:8000"
claude-2.1.98 --print "1+1"
# Note cache_creation_input_tokens in response
# 3. Same setup — test with newer version
claude-2.1.100 --print "1+1"
# Note cache_creation_input_tokens in response
Each test is a cold cache, single API call, no session state (--print mode). Same machine, same project, same account, minutes apart.
Evidence
| Version | Content-Length (bytes) | cache_creation_input_tokens | cache_read | Total |
|---------|----------------------|----------------------------|------------|-------|
| v2.1.98 | 169,514 | 49,726 | 0 | 49,726 |
| v2.1.100 | 168,536 (-978 B) | 69,922 | 0 | 69,922 |
| v2.1.101 | 171,903 (+2,389 B) | ~72,000 | 0 | ~72,000 |
v2.1.100 sends 978 fewer bytes than v2.1.98 but is billed 20,196 MORE tokens. This rules out any client-side payload difference — the inflation happens server-side after the request is received.
Cross-account test (same v2.1.98, two different Max accounts): delta < 500 tokens = noise. Not account-specific.
Interactive mode confirms
/tmp/claude-cache-*.json files across 40+ sessions show bimodal distribution:
- Group A: ~50K (
cache_read=0, cache_create=~50K) — matches v2.1.98--print - Group B: ~71K (
cache_read=0, cache_create=~71K) — matches v2.1.100+--print
Some sessions start cold at 71K with cache_read=0, confirming this is not accumulated cache — it's the baseline.
Quality concern
The 20K extra tokens are cache_creation_input_tokens — this means they enter the model's context window, not just the billing ledger. If the server injects additional content invisible to the user:
- Instruction dilution: Hidden system content may compete with user-provided CLAUDE.md rules, leading to inconsistent agent behavior
- Reduced effective context: 20K fewer tokens available for actual conversation history — in long sessions this compounds with every turn
- Unverifiable behavior: Users cannot audit what the model actually "sees" vs what they sent — makes debugging agent misbehavior significantly harder
We observed qualitative differences between v2.1.98 and v2.1.100+ sessions (instruction adherence, tool selection accuracy), but cannot isolate whether this is caused by the extra hidden tokens or other version changes. The lack of transparency makes it impossible to tell.
Additional findings
- After
/loginaccount switch, statusline can jump ±20K — this is cache invalidation (new account_uuid = new cache key), not a billing difference between accounts. - 56
count_tokensburst calls observed immediately after first interactive prompt — inflates the apparent "first visible" context number in statusline. - Current v2.1.104 is untested — the investigation was done on v2.1.98/100/101. We cannot confirm whether v2.1.104 carries the same inflation.
Impact
~20K extra tokens per session = ~40% overhead on a clean project. On Max plan with usage limits, this means hitting the 5-hour cap significantly faster on newer CC versions.
Combined with the quality concern: users are paying more for potentially degraded output, with no visibility into why.
Workaround
Downgrade to v2.1.98 or earlier. Check ~/.local/share/claude/versions/ for available binaries, or use npx claude-code@2.1.98.
Note: Auto-updates may overwrite older versions. v2.1.98 is no longer retained in the local versions directory after v2.1.104 installed.
Related
- #45515 — Original phantom token report (account-specific delta, now understood as cache invalidation artifact)
- Reddit investigation with full proxy data: https://www.reddit.com/r/ClaudeCode/comments/1sj10ou/
- Community reports of rapid limit exhaustion correlate with v2.1.100+ rollout timeline
Environment
- Claude Code: v2.1.98 / v2.1.100 / v2.1.101 (tested all three)
- OS: Linux (WSL2), Windows 11
- Plan: Max (5x)
- Install method: native
- Measurement: HTTP proxy capturing full request/response bodies
41 Comments
Following
Following. Urgent fix is required. Please remediate or explain the issue Anthropic.
Hi, if the issue is related only to the useragent, you can override it instead of downgrading claude.
Example:
export ANTHROPIC_CUSTOM_HEADERS='User-Agent: claude-cli/2.1.98 (external, sdk-cli)'settings.jsonenv:"ANTHROPIC_CUSTOM_HEADERS":"User-Agent: claude-cli/2.1.98 (external, sdk-cli)"is this true @Claude ?
up
Up
up
up
up
<p class="font-claude-response-body break-words whitespace-normal leading-[1.7]">Tested on <strong>v2.1.104</strong> using the same HTTP proxy approach — results show the overhead has continued growing beyond what was reported here.</p>
<p class="font-claude-response-body break-words whitespace-normal leading-[1.7]"><strong>Test conditions:</strong> empty directory, no <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">CLAUDE.md</code>, single <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">--print "responda apenas: ok"</code> call, cold cache, <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">ANTHROPIC_BASE_URL</code> proxied locally to capture raw SSE <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">message_start</code> events.</p>
<p class="font-claude-response-body break-words whitespace-normal leading-[1.7]"><strong>Results:</strong></p>
<div class="overflow-x-auto w-full px-2 mb-6">
Version | cache_creation (cold)
-- | --
v2.1.98 | ~49,726 (community)
v2.1.100 | ~69,922 (community)
v2.1.101 | ~72,000 (community)
v2.1.104 (mine) | ~96,539
</div>
<p class="font-claude-response-body break-words whitespace-normal leading-[1.7]">That's a <strong>94% increase</strong> over v2.1.98 in just 6 patch versions.</p>
<p class="font-claude-response-body break-words whitespace-normal leading-[1.7]"><strong>Request payload size:</strong> 349,684 bytes — comparable to values reported here, so the inflation is server-side.</p>
<p class="font-claude-response-body break-words whitespace-normal leading-[1.7]"><strong>Context:</strong> I run parallel subagent sessions (orchestrator + specialized agents). Each agent that starts a cold session pays this independently, so the real multiplier in my workflow is 3–5×.</p>
<p class="font-claude-response-body break-words whitespace-normal leading-[1.7]">Combined with the TTL regression reported in #46829 (5m instead of 1h), the effective cost per agent loop has roughly doubled compared to a few weeks ago.</p>
<p class="font-claude-response-body break-words whitespace-normal leading-[1.7]"><strong>Plan:</strong> Max | <strong>OS:</strong> macOS</p>
The 20K token inflation per request is brutal for quota. We open-sourced Cozempic which keeps sessions lean by pruning stale tool results, thinking blocks, and accumulated bloat before each API call — lossless, nothing meaningful is removed.
Sessions typically run 3-4x longer and cost 2-3x less. The guard daemon auto-prunes at configurable thresholds so the inflated cache_creation hits a smaller payload.
\
pip install cozempic && cozempic init\Feedback welcome — always improving based on what users report.
upp
up
Up
Quick way to check if you're affected without setting up a proxy:
Option 1 — Enter your version: Version Health Check — shows which issues affect your specific version and recommended fixes.
Option 2 — Check
/costoutput: Run/costand look atcache_creation_input_tokens:| Range | Status |
|-------|--------|
| 40-55K | Normal (v2.1.98 baseline) |
| 60-72K | Inflated (~v2.1.100-101 range) |
| 90K+ | Severely inflated (v2.1.104 range per @alanceloth's data above) |
If your
cache_creationexceedscache_readconsistently, you're paying full price for content that should be cached — compounding the inflation on every turn.For detailed breakdown, paste your
/costoutput into Cache Health Checker — flags inflation, TTL breakage (#46829), and read/creation ratio. No sign-up, runs client-side.Following
Up
Up
Independent Verification — v2.1.98 through v2.1.107 + User-Agent workaround confirmed
Ran a controlled test across 4 CC versions + a UA spoof test using a custom Node.js proxy that captures full SSE response bodies (including gzip-decoded
message_startusage data).Method:
--print "1+1"per version, same project directory, same machine, sequential runs within ~2 minutes. Proxy extractscache_creation_input_tokensandcache_read_input_tokensfrom raw SSEmessage_startevents.Results
| Version | Content-Length | cache_creation | cache_read | Total | Δ vs 2.1.98 |
|---------|---------------|----------------|------------|-------|-------------|
| v2.1.98 | 176,128 B | 40,950 | 9,558 | 50,511 | baseline |
| v2.1.100 | 174,943 B (-1,185 B) | 57,659 | 13,182 | 70,847 | +40.8% |
| v2.1.104 | 178,552 B (+2,424 B) | 57,763 | 14,410 | 72,179 | +42.9% |
| v2.1.107 | 180,028 B (+3,900 B) | 58,249 | 14,464 | 72,719 | +44.0% |
| v2.1.107 + UA spoof | 180,028 B (+3,900 B) | 41,095 | 10,520 | 51,618 | +2.2% |
Key findings
User-Agent: claude-cli/2.1.98sends the exact same payload (180,028 B) but the server returnscache_creationof 41,095 instead of 58,249. That's 17,154 fewer tokens — matching the v2.1.98 baseline within noise. The inflation is 100% server-side, routed by User-Agent string.cache_readpartially shared across tests. Because tests ran sequentially, some cache was shared between versions (common CLAUDE.md content). In a true cold-cache scenario (fresh account, no prior calls), the numbers would be higher across the board, but the delta between versions would remain the same.Workaround
Credit to @fabifont for the suggestion — independently confirmed with proxy evidence:
This reduces
cache_creationby ~17K tokens per session start without downgrading. The client sends the same payload — only the server-side injection is reduced.Environment
message_startextractionRemaining questions
---
Tested 2026-04-14 using SSE usage proxy. Original report: #46917.
Up!
up
20k tokens wasted every generation on tools you cant turn off nor does it use, dilutes the quality of the response and makes them take far longer for less quality, fix this anthropic, stop breaking something that worked so good 2 weeks ago
Confirmed independently on macOS with a different methodology (forged UA strings via
ANTHROPIC_CUSTOM_HEADERSon the same v2.1.105 binary,--print --output-format json --no-session-persistence, empty project directory).| UA forged | cache_creation_input_tokens | Total injected |
|---|---|---|
|
claude-cli/2.1.91| 17,505 | 17,505 ||
claude-cli/2.1.98| 17,505 | 17,505 ||
claude-cli/2.1.99| 17,505 | 17,505 ||
claude-cli/2.1.100| 24,215 | 24,215 ||
claude-cli/2.1.101| 27,525 | 27,525 ||
claude-cli/2.1.104| 27,525 | 27,525 ||
claude-cli/2.1.105| 27,525 | 27,525 |Same binary, same prompt, same account — only the UA header changes. Pre-2.1.100 UAs share a cache entry (proving identical server-side content), post-2.1.100 UAs share a different one.
v2.1.108 resolves this. Retested after upgrading — old and new UAs now produce the same token count (20,210 for both
claude-cli/2.1.98andclaude-cli/2.1.108). The UA-keyed injection delta is gone. Upgrade to v2.1.108+.Great findings. Unfortunately, I think the actual reasoning will be cloaked behind some excuse rather than "We screwed up, here's what happened". Part of me wonders how long it'll be until 2.1.108+ will have something like this happen again... hopefully not.
Follow
Noted.
If you're on Windows, switching back to npm v2.1.98, disabling auto-updates, and sticking with Opus 4.6 made a huge difference for me.
Both response quality and usage have improved significantly, and my usage no longer spikes as quickly on 5x.
Not sure why this works, but it’s been consistently effective on my setup. I know it's not a proper solution tho...
npm install -g @anthropic-ai/claude-code@2.1.98{"env": {
"DISABLE_AUTOUPDATER": "1"
}
}
I downgraded to 2.1.77 through the AUR or via the official link, it has gotten increasingly better ever since...
git checkout 821f57194c06a535e99345ad1dc1d05e1b99d01dfor 2.1.77git checkout 6425def20316a9b7078f262e3294b5508628e1c4for 2.1.89or without the AUR:
Same procedure for 2.1.77.
Up
up
up
up
up
Status Update: W16 Follow-up
Following up on my previous findings about the User-Agent workaround (spoofing v2.1.98 UA while running v2.1.107):
The workaround stopped working sometime between W15 and W16.
Current Test Results (2026-04-16)
| CC Version | cache_creation | cache_read | Total |
|------------|----------------|------------|-------|
| v2.1.98 | ~28,500 | ~9,500 | ~38,000 |
| v2.1.100 | ~28,500 | ~9,500 | ~38,000 |
| v2.1.104 | ~28,500 | ~10,500 | ~39,000 |
| v2.1.107 | ~28,600 | ~10,500 | ~39,000 |
| v2.1.110 | ~28,600 | ~10,400 | ~39,000 |
Observation: All CC versions now show similar token counts. However, the problem persists — the ~40-50% overhead compared to pre-inflation baseline is still present across ALL versions.
What We Tried (nothing works anymore)
Current Impact
Ask
Is there any server-side change that could explain this? The inflation pattern suggests something changed in how the API processes or caches requests for Claude Code specifically.
Any guidance appreciated.
---
Tested with claude-code-logger proxy capturing full SSE response bodies on same project directory.
Is it possible it was using the tokenizer for Opus 4.7 (and the new model as well)?
They have documented an increase in the number of used tokens for the same amount of text.
The 20K inflation likely comes from accumulated session content that gets re-sent on every turn. Cozempic pre-prunes the JSONL with 18 strategies — stale tool results, old images, metadata bloat — before the API call ever fires. Less payload = fewer cache_creation tokens regardless of what the server does.
pipx install cozempic && cozempic guard— https://github.com/Ruya-AI/cozempicAny update or plan to fix this?
Any update on this? Any comment from Anthropic at all???
This is the load-bearing piece of evidence in what looks like a 10-issue cluster on this repo — operator-runnable, version-correlated, server-side. I tried to organize the surrounding evidence and the operator-side measurement responses into one place:
The cluster. Ten open issues, ~2,200 cumulative reactions, ~3,000 comments, accumulated 2025-12 through 2026-04. Four of them name an independent runtime version or date boundary, which is the part that disambiguates this from perception drift:
| Issue | Reactions | Boundary named |
|-------|-----------|----------------|
| #16157 | 717 | — (oldest, structural) |
| #38335 | 525 | 2026-03-23 |
| #46917 (this one) | 218 | v2.1.100 |
| #45756 | 158 | — |
| #29579 | 92 | — |
| #41788 | 84 | v2.1.89 |
| #13585 | 82 | — (feature request: CLI quota access) |
| #23706 | 77 | Opus 4.6 vs 4.5 |
| #16856 | 76 | 2.1.1 |
| #19673 | 76 | — |
Four independent users naming four independent inflection points is a stronger evidentiary base than ten anecdotes about general dissatisfaction. Your reproduction is the one that lets any operator verify the pattern on their own machine in ~30 minutes.
Three-stage structural read.
Stages compose: stage 1 leaves the operator blind, stage 3 shifts the runtime, stage 2 means the surface won't tell you when it happens.
Operator-side measurement composition. Until the first-party CLI lands, the five paths I've found useful:
ryoppippi/ccusage(14.6K stars, third-party) — reads~/.claude/projects/JSONL and aggregates by day/session/model. Catches the Opus 4.6 vs 4.5 shift (#23706) directly viabunx ccusage models --since 7d.``
bash
`LAST=$(ls -t "$HOME/.claude/projects/$(pwd | sed 's|/|-|g')"/*.jsonl | head -1)
jq -s '[.[] | .message.usage // empty] |
{total_cache_creation: ([.[].cache_creation_input_tokens // 0] | add)}' "$LAST"
--print` invocation. Any delta > ~5% is worth investigating.Snapshot before / after a version bump on the same
claude-code-loggerproxy — your reproduction, the definitive server-side evidence path.cache_creation_input_tokensper PostToolUse event, appends to a rolling JSONL, and emits a one-line stderr warning when the current request exceeds the trailing-window mean by 25% (configurable). Advisory only — does not block. The alert message references this issue (#46917) so the operator can correlate the regression with your documented evidence.Pre-purchase routine for cost-conscious Max subscribers.
bunx ccusage dailyover the last 7 days; snapshot a representative--printinvocation with path 2; re-snapshot after each version bump. If the delta on a same-shape payload exceeds ~5%, you have a candidate worth instrumenting with path 3.I've written the comprehensive version (pattern-to-path mapping, recommended operator hygiene, what to file vs. measure-locally) at https://gist.github.com/yurukusa/158436e88d169406593d55bd84f0d7e9 (MIT, no signup, no telemetry, ~2,600 words). The Gist credits
ccusageandclaude-code-loggeras the third-party tools doing the heavy lifting; the cc-safe-setup hook is one component of the path-4 composition, not a replacement for either.Three concrete asks from the cluster's audience that would help maintainers prioritize:
modelfield switches (e.g., requested Opus, got Sonnet) coinciding with the quota spike, attaching anonymized excerpts to #23706 would tighten that thread's evidentiary baseThanks for the rigorous reproduction here. The operator side genuinely couldn't build path 3 without it.
Confirming this bug on v2.1.160 | Max 20X plan | June 2026
Still present on v2.1.160. Posting to add real-world billing impact data.
Token counts across 4 sessions (same account, same project):
| Session | Model | Cache Read | Cache Write | Total |
|---|---|---|---|---|
| 1 | Sonnet 4.6 | 286.3M | 7.2M | 295.4M |
| 2 | Sonnet 4.6 | 139.1M | 6.9M | 147.1M |
| 3 | Opus 4.8 | 576.3M | 27.1M | 605.4M |
| 4 | Sonnet 4.6 | 106.1M | 10.3M | 116.8M |
| Total | | 1.107B | 51.5M | 1.165B |
Plan gauge throughout: Weekly all models 6%, Sonnet only 4%, 5-hour limit 0%.
Financial impact: €43.08 charged to usage credits with zero warning or consent moment. Full session transcript search confirms no threshold alert was ever delivered by the system — only cryptic
overload/retry_errormessages with no billing language.Currently seeing "Usage limit reached" + Upgrade prompt on an active Max 20X plan renewed less than 48 hours ago.
The 1.1B cache token total on a plan showing 4-6% usage is a direct fingerprint of the cache inflation bug described in this issue. This is causing real financial harm to paying subscribers.
Anthopic support ticket: Conversation ID 215474548931290
/cc #45203
Confirming on v2.1.160 | Max 20X plan | June 2026
Still present on v2.1.160. Real-world billing impact:
| Session | Model | Cache Read | Cache Write | Total |
|---|---|---|---|---|
| 1 | Sonnet 4.6 | 286.3M | 7.2M | 295.4M |
| 2 | Sonnet 4.6 | 139.1M | 6.9M | 147.1M |
| 3 | Opus 4.8 | 576.3M | 27.1M | 605.4M |
| 4 | Sonnet 4.6 | 106.1M | 10.3M | 116.8M |
| Total | | 1.107B | 51.5M | 1.165B |
Plan gauge throughout: Weekly 6%, Sonnet 4%, 5-hour 0%. Result: €43.08 charged to usage credits, zero threshold alerts in transcripts, only cryptic overload/retry errors.
Currently getting "Usage limit reached" on Max 20X plan renewed <48 hours ago. The 1.1B cache total on 4-6% gauge usage is a direct fingerprint of this bug.
Anthopic support ref: Conversation ID 215474548931290. /cc #45203