Skip to content

Session token usage grows unbounded via cache.read and causes unrecoverable context-window errors #30649

Description

@wang1970

Description

Long-running sessions can grow their recorded token usage without a practical upper bound, especially through tokens.cache.read, until most models/providers fail with a context-window error and the session becomes unrecoverable.

In my real session, OpenCode reported approximately 56,128,248 total tokens while the persisted conversation data was small:

session tokens:
  input:        14,774,671
  output:           77,881
  reasoning:        20,400
  cache.read:   41,255,296
  cache.write:           0
  total:        56,128,248

stored rows for that session:
  message: 224 rows, ~0.52 MB JSON data
  part:   1042 rows, ~2.33 MB JSON data

After this, continuing the same session fails with:

Your input exceeds the context window of this model. Please adjust your input and try again.

The issue is not that the saved message JSON itself is tens of millions of tokens. The large number appears to come from cumulative session usage accounting. In particular, tokens_cache_read can grow very large over repeated turns.

Relevant code path observed in source:

packages/core/src/session/projector.ts
  tokens_input:       SessionTable.tokens_input + value.tokens.input
  tokens_output:      SessionTable.tokens_output + value.tokens.output
  tokens_reasoning:   SessionTable.tokens_reasoning + value.tokens.reasoning
  tokens_cache_read:  SessionTable.tokens_cache_read + value.tokens.cache.read
  tokens_cache_write: SessionTable.tokens_cache_write + value.tokens.cache.write

This makes session-level usage an ever-growing lifetime counter. That is fine for statistics, but it becomes dangerous if any compaction / routing / provider request / context-window logic treats cumulative session usage, especially cache.read, as if it represented the current prompt/context size.

Impact:

  • Long sessions eventually hit provider context-window errors.
  • Auto compaction does not reliably save an already-overflowed session.
  • Once overflowed, the same session can repeatedly fail and effectively becomes unusable.
  • opencode stats can become slow/hang on large databases/sessions.
  • This affects providers/models with smaller context windows especially badly when using an auto model/router.

Expected behavior:

  • Current context-window checks should be based on the actual messages that will be sent to the provider, not lifetime cumulative usage counters.
  • cache.read should not be counted as current prompt/context tokens for overflow decisions.
  • Auto compaction should trigger before the provider rejects the request.
  • If a provider returns a known context-window error, OpenCode should attempt a safe compact/prune/retry or suggest/fork a new session instead of leaving the session dead.
  • There should be a hard cap / safety guard for long-running sessions, e.g. archive/fork/reset usage or force compaction before sending.

Plugins

Only a local/custom provider/router was used (providerID: 9090, modelID: auto). No plugin-specific behavior is required to reproduce the core issue: repeated turns can accumulate session usage far beyond any real model context window.

OpenCode version

1.15.13

Steps to reproduce

  1. Use OpenCode with a provider/model that reports token usage including cache read tokens.
  2. Keep a long-running session active for many turns, especially with repeated cache hits or provider-side prompt caching.
  3. Inspect the SQLite session row, for example:
select
  tokens_input,
  tokens_output,
  tokens_reasoning,
  tokens_cache_read,
  tokens_cache_write
from session
where id = '<session id>';
  1. Observe that cumulative tokens_cache_read and total session tokens can grow to tens of millions even when the stored message/part JSON is only a few MB.
  2. Continue the same session until the provider rejects the next request with a context-window error:
Your input exceeds the context window of this model. Please adjust your input and try again.
  1. Try enabling aggressive compaction settings such as:
{
  "compaction": {
    "auto": true,
    "prune": true,
    "tail_turns": 1,
    "preserve_recent_tokens": 4000,
    "reserved": 12000
  }
}

The already-overflowed session still remains difficult/impossible to continue.

Screenshot and/or share link

No public share link, because the affected session contains private project data. Sanitized measurements are included above.

Related existing issues that look adjacent but do not mention the cache.read/cumulative-session-usage aspect:

Operating System

Windows 11

Terminal

Windows Terminal / PowerShell

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions