Repository navigation
Auto-compaction request usage is never added to total_token_usage in rollouts (not recorded at all in 0.147) #47003
Description
What version of Codex CLI is running?
Codex Desktop 26.915.31945 (bundled codex-cli 0.155.0-alpha.9.2). Reproduced in rollouts written by 0.154.0-alpha.6.2 and 0.155.0-alpha.2.6; 0.147.0 behaves worse (see below).
What subscription do you have?
ChatGPT Pro
Which model were you using?
gpt-6-astra and gpt-5.6-sol. Model-independent: affects every model that auto-compacts.
What platform is your computer?
Darwin 25.6.0 arm64 arm
What terminal emulator and version are you using (if applicable)?
N/A (Codex Desktop app)
Codex doctor report
not available
What issue are you seeing?
The usage of the auto-compaction request is never added to the thread's cumulative total_token_usage in the rollout. Any token or cost figure derived from token_count events therefore undercounts every thread that compacts.
0.154 / 0.155: the compaction request is written as a token_usage_record, and its response_id matches the compacted item's compaction_response_id. However, the total_token_usage in the next token_count event does not change. The last token_count before the compaction and the first one after it report identical totals.
Example from a real rollout (0.154.0-alpha.6.2):
total_token_usage.input_tokens before compaction: 13,048,912
total_token_usage.input_tokens after compaction: 13,048,912
compaction token_usage_record usage: input 223,139 / output 6,057
I checked this across every compaction in my rollouts from 15–19 Sep: 68 of 68 compaction requests on 0.154.0-alpha.6.2 and 0.155.0-alpha.2.6 were excluded from the running total. None were included.
0.147.0: no token_usage_record is written at all, so the compaction request's usage is not recoverable from the rollout. The only trace is the compacted item and the wall-clock gap before it.
Magnitude, from one month of my own rollouts (848 real compactions, 1,640 sessions): a compaction request averages ~232K input tokens and ~5.8K output tokens on gpt-6-astra, and ~235K input / ~3.2K output on gpt-5.6-sol. It also costs one cache rebuild (~18–21K uncached input tokens) on the next request. A long thread compacts every ~40 minutes, so each one leaves roughly a whole context window of billed input out of the totals.
What steps can reproduce the bug?
- Run any thread long enough to trigger auto-compaction (context window 258,400).
- In the rollout JSONL, find the
compacteditem and readpayload.compaction_response_id. - Find the
token_usage_recordwith thatresponse_idand note itsusage. On 0.147.0 there is none. - Compare
info.total_token_usagein thetoken_countevent immediately before thecompacteditem with the first one after it. They are identical; the compaction request's usage was never added.
Minimal check:
import json, sys
rows = [json.loads(l) for l in open(sys.argv[1])]
usage = {r["payload"]["response_id"]: r["payload"]["usage"]
for r in rows if r["type"] == "token_usage_record"}
last = None
for i, r in enumerate(rows):
p = r.get("payload", {})
if r["type"] == "event_msg" and p.get("type") == "token_count" and (p.get("info") or {}).get("total_token_usage"):
last = p["info"]["total_token_usage"]
if r["type"] == "compacted":
u = usage.get(p.get("compaction_response_id"))
nxt = next(q["payload"]["info"]["total_token_usage"] for q in rows[i+1:]
if q["type"] == "event_msg" and q["payload"].get("type") == "token_count")
print("compaction usage:", u and u["input_tokens"],
"| running-total delta:", nxt["input_tokens"] - last["input_tokens"])Every line prints a running-total delta of 0.
What is the expected behavior?
- The compaction request's usage is added to
total_token_usage, the same as any other model request in the thread, so the rollout reflects everything the thread consumed. - Every version writes a usage record for the compaction request. Ideally it is also marked as a compaction request, so tools can separate compaction overhead from turn work.
Additional information
- Consequence: local token and cost reports built from rollout totals are systematically low for long-running threads, and the gap grows with the number of compactions. The error also isn't visible: the totals look complete and internally consistent.
- Subagent and guardian-review threads start with a
compacteditem copied from the parent, with no request behind it. That's fine, but tools countingcompacteditems will overcount compactions unless they exclude these. A marker distinguishing copied compaction items from real ones would help. - Possibly related: Clarify account/usage/read daily bucket timezone and token accounting semantics #43650. That report reconciles rollout-derived totals against
account/usage/readand leaves a ~5.2% residual after UTC re-bucketing. Excluded compaction requests would push rollout totals below the backend's, in the direction of that gap.
Activity
[docs][backlog] decision-17 usage 실측 채널 재조사 결과
SergiPantoja commentedon Sep 26, 2026
Same here, on 0.154.0-alpha.6.2 and 0.155.0-alpha.2.6. All compactions in my rollouts are missing from
total_token_usage.I'm building a small usage report. I switched from reading
total_token_usageout oftoken_countto summingpayload.usagefromtoken_usage_record, deduplicated byresponse_id, and that picks up the compaction requests. Tools that readtoken_count, such as ccusage, don't see them, so their totals come out low.