[BUG] Token estimation vs API-reported tokens diverge significantly for cached context

Resolved 💬 3 comments Opened Apr 10, 2026 by Fearvox Closed May 24, 2026

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:

  1. AutoCompact fires at wrong threshold — local estimation shows e.g. "80% full" but API has already consumed much more of the context window
  2. Context bar misreads — user sees "X% used" but the real percentage is different
  3. Silent context overruns — session appears fine locally but hits API limits unexpectedly

Reproduction

  1. Start a long session with multiple rounds of tool use
  2. Note the local context bar percentage vs the API-reported input_tokens in responses
  3. 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 request
  • cache_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

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗