[BUG] Token estimation vs API-reported tokens diverge significantly for cached context
Preflight Checklist
- [x] I have searched existing issues and this has not been reported yet
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code
What's Wrong?
Claude Code's local token estimation (used for AutoCompact triggering, context bar display, and status line) diverges significantly from the API-reported token counts in the response usage field, particularly for sessions with high cache_read_input_tokens and cache_creation_input_tokens.
This causes:
- AutoCompact fires at wrong threshold — local estimation shows e.g. "80% full" but API has already consumed much more of the context window
- Context bar misreads — user sees "X% used" but the real percentage is different
- Silent context overruns — session appears fine locally but hits API limits unexpectedly
Reproduction
- Start a long session with multiple rounds of tool use
- Note the local context bar percentage vs the API-reported
input_tokensin responses - Compare: local estimation may show 60% while API shows 85%+ of effective window consumed
Technical Detail
The divergence appears in how Claude Code estimates tokens vs how the API counts them:
Local estimation (from tokenCountWithEstimation / context bar):
- Counts raw token content (messages + tools + system prompt)
- Does not always correctly account for cache hit savings
- Shows a number that may not reflect actual API context consumption
API-reported (from response usage field):
input_tokens: fresh tokens consumed this requestcache_read_input_tokens: tokens served from cache (5-minute ephemeral cache)cache_creation_input_tokens: tokens written to cache this request- Both cache fields are not subtracted from the effective context window in local estimation
Result: A session with 100K cache_read_input_tokens might show as "60% full" locally while actually having consumed far more of the API's context budget.
Root Cause Hypothesis
The gap is in how cache_read_input_tokens are treated in getEffectiveContextWindowSize(). The API counts cache reads against the context window differently than Claude Code's local estimation does.
Impact
- AutoCompact fires at wrong time — too late or too early depending on cache ratio
- Context bar misleading — users cannot trust the displayed percentage
- Budget surprises — sessions unexpectedly hit limits when local estimation said there was headroom
Suggested Labels
area:core, area:cost, bug
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗