Possible context-accounting bug: automatic compaction at 388K displayed tokens uses a 623K internal count
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
What issue are you seeing?
Summary
A long-running Codex session automatically compacted while the UI showed roughly
388K tokens used out of a 570K usable context window (32% remaining).
The project configuration requests a 600K context window and a 550K automatic
compaction threshold.
The local logs show a substantial discrepancy between the latest model-reported
token usage and the internal count used to trigger compaction. Immediately after
a short mid-turn user message, the internal count jumped from 392,300 to
623,194, while the model-reported total changed from 386,918 to
387,738. The internal count crossed both the effective compaction threshold
and the usable context limit.
This is evidence of inconsistent accounting or presentation, not yet a confirmed
implementation bug. The extra count's source has not been established.
Environment and configuration
-
Observed on 11 September 2026; all timestamps below are UTC.
-
Linux, using a long-running Codex session with an active
/goalassignment. -
The session has been accessed through Codex CLI and remote/app-server control;
this has not been reproduced in an isolated CLI-only session. -
Locally installed version:
codex-cli 0.154.0. -
Active model:
gpt-6-astra; reasoning effort:max. -
Project
.codex/config.toml:model_context_window = 600000 model_auto_compact_token_limit = 550000 -
The CLI launch script also passes those same two values with
-c. -
The model catalog reports
effective_context_window_percent = 95.
Accordingly, 600,000 × 0.95 = 570,000, matching both session telemetry and the UI. -
Runtime logs report
auto_compact_scope_limit=Some(540000)and
auto_compact_limit_scope=Total.
The context-window override is demonstrably active. The effective 540K threshold
differs from the requested 550K. It equals 90% of the configured window, but a
clamping rule has not been verified from implementation source. That smaller
difference does not by itself explain compaction at a displayed 388K.
Observed sequence
- Continue a long, tool-heavy research assignment, with previous compactions and
mid-turn steering messages in the session history. - At
04:30:34.312Z, the latest model-reported total is 386,918 tokens.
The compaction decision logs an internal count of 392,300 and no limit reached. - A 288-character user message is recorded at
04:30:34.316Z, asking for a
stronger process-review instruction in the research prompt. - Codex acknowledges the request and runs another tool call.
- At
04:30:56.463Z, the latest model-reported total is 387,738 tokens.
The compaction decision instead uses 623,194 and reports both limits reached. - A completed
compactedrecord appears at04:51:34.917Z.
These are steps from the observed incident, not a minimal or reliably repeatable
reproduction. The user did not request manual compaction at this boundary.
Expected behavior
The displayed context usage and the count used for automatic compaction should
be reconcilable. If the internal decision includes additional estimated context,
pending input, or a safety allowance, that distinction should be visible or
diagnosable. A short steering message should not produce an unexplained increase
of more than 230K tokens in the decision counter.
Actual behavior and evidence
Model-reported usage from the session JSONL
| UTC time | Input tokens | Output tokens | Total tokens | Usable window |
|---|---|---|---|---|
| 04:30:34.312 | 376,847 | 10,071 | 386,918 | 570,000 |
| 04:30:56.463 | 387,086 | 652 | 387,738 | 570,000 |
These values are event_msg / token_count → info.last_token_usage, with the
window from info.model_context_window. They are not cumulative lifetime usage.
The final total closely matches the user's displayed 388K.
Compaction-decision logs
The following fields are copied from codex_core::session::turn log records.
Session/turn identifiers and tracing prefixes are omitted.
2026-09-11T04:30:34Z post sampling token usage
total_usage_tokens=392300
auto_compact_scope_tokens=392300
auto_compact_scope_limit=Some(540000)
auto_compact_limit_scope=Total
auto_compact_window_prefill_tokens=None
full_context_window_limit=Some(570000)
full_context_window_limit_reached=false
token_limit_reached=false
has_pending_input=true
2026-09-11T04:30:56Z post sampling token usage
total_usage_tokens=623194
auto_compact_scope_tokens=623194
auto_compact_scope_limit=Some(540000)
auto_compact_limit_scope=Total
auto_compact_window_prefill_tokens=None
full_context_window_limit=Some(570000)
full_context_window_limit_reached=true
token_limit_reached=true
has_pending_input=false
- Internal count increase: 230,894 tokens.
- Model-reported total increase: 820 tokens.
- Internal count minus model-reported total at the trigger: 235,456 tokens.
The source evidence is in the local ~/.codex/logs_2.sqlite database and this
session's rollout JSONL under ~/.codex/sessions/. Full logs are not included;
they contain the research conversation and unrelated runtime information.
What is established, and what remains uncertain
Established: the running session uses the configured context window, and the
recorded compaction decision is consistent with its 623,194-token internal
count, rather than the approximately 388K shown to the user.
Unresolved: why the internal count increased so sharply at this boundary.
Possible areas to investigate include switching between reported usage and a
local estimate, handling retained compaction history, or accounting changes when
pending input is consumed. These are hypotheses; no specific mechanism has been
demonstrated. The steering-message timing alone does not establish causation.
Also unresolved: why the effective threshold is 540K when 550K is configured.
The official configuration reference
describes the threshold and its counting scope, but does not explain this incident.
No settings were changed during this investigation, and increasing the threshold
has not been tested as a remedy. Useful follow-up would be to trace the source of
the decision counter across the two sampling iterations and compare it with the
usage notification sent to the client.
What steps can reproduce the bug?
Possibly (just a hypothesis): send a steering message during a long-running goal. That was when the jump in tokens, followed by compaction, was observed.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at codex_core::session::turn and trace the compaction-decision counter across the two sampling iterations. Compare those records with the token usage in ~/.codex/logs_2.sqlite and the session rollout JSONL; done means identifying why the internal count diverges from reported usage and whether the 540K effective threshold is explained.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100