Repository navigation
Description
What happened?
ccusage leaves out real usage from some forked Codex subagent rollouts. On my machine 36 rollouts written by the Codex VS Code extension (0.164.0-alpha.11.1) on 1 and 2 Nov are missing from ccusage codex daily and ccusage codex session altogether. That is about 2% of my October Codex tokens and 6% of 1 to 8 Nov.
All 36 have the same shape. The file opens with a compacted item, and every line, including every token_usage_record, carries the timestamp of the session_meta line. Codex seems to have rewritten the whole file with that one timestamp. My guess is that the same-second replay check (#1460) then treats all of it as replayed parent history.
The usage is not replayed. In one of these files the 60 response_ids appear in no other rollout, and no other rollout has the same per-response usage. Codex's own state_5.sqlite shows threads.tokens_used for that thread at 40,203,403, against 32,622,562 at the first token_count in the file. The difference, 7,580,841, is exactly the sum of the file's 60 token_usage_record usages. The thread's updated_at is seven hours after it was created.
Steps to reproduce
- Save the lines below as
sessions/2026/11/01/rollout-2026-11-01T09-42-09-01a1967c-0000-7000-8000-00000000000a.jsonlin an emptyCODEX_HOME. - Run
CODEX_HOME=<that dir> ccusage codex session --json --offline. - No session is reported.
{"timestamp":"2026-11-01T09:42:09.923Z","type":"session_meta","payload":{"id":"01a1967c-0000-7000-8000-00000000000a","forked_from_id":"01a1967b-0000-7000-8000-000000000001","timestamp":"2026-11-01T09:42:09.923Z","originator":"codex_vscode","cli_version":"0.164.0-alpha.11.1","source":{"subagent":{"thread_spawn":{"parent_thread_id":"01a1967b-0000-7000-8000-000000000001","depth":1}}},"model_provider":"openai"}}
{"timestamp":"2026-11-01T09:42:09.923Z","type":"compacted","payload":{"message":"","replacement_history":[]}}
{"timestamp":"2026-11-01T09:42:09.923Z","type":"turn_context","payload":{"model":"gpt-6-astra"}}
{"timestamp":"2026-11-01T09:42:09.923Z","type":"event_msg","payload":{"type":"token_count","info":{"total_token_usage":{"input_tokens":990000,"cached_input_tokens":0,"output_tokens":10000,"reasoning_output_tokens":0,"total_tokens":1000000},"last_token_usage":{"input_tokens":990000,"cached_input_tokens":0,"output_tokens":10000,"reasoning_output_tokens":0,"total_tokens":1000000}}}}
{"timestamp":"2026-11-01T09:42:09.923Z","type":"token_usage_record","payload":{"response_id":"resp_child_1","usage":{"input_tokens":10000,"cached_input_tokens":2000,"output_tokens":100,"reasoning_output_tokens":0,"total_tokens":10100}}}
{"timestamp":"2026-11-01T09:42:09.923Z","type":"event_msg","payload":{"type":"token_count","info":{"total_token_usage":{"input_tokens":1000000,"cached_input_tokens":2000,"output_tokens":10100,"reasoning_output_tokens":0,"total_tokens":1010100},"last_token_usage":{"input_tokens":10000,"cached_input_tokens":2000,"output_tokens":100,"reasoning_output_tokens":0,"total_tokens":10100}}}}
{"timestamp":"2026-11-01T09:42:09.923Z","type":"token_usage_record","payload":{"response_id":"resp_child_2","usage":{"input_tokens":10000,"cached_input_tokens":2000,"output_tokens":100,"reasoning_output_tokens":0,"total_tokens":10100}}}
{"timestamp":"2026-11-01T09:42:09.923Z","type":"event_msg","payload":{"type":"token_count","info":{"total_token_usage":{"input_tokens":1010000,"cached_input_tokens":4000,"output_tokens":10200,"reasoning_output_tokens":0,"total_tokens":1020200},"last_token_usage":{"input_tokens":10000,"cached_input_tokens":2000,"output_tokens":100,"reasoning_output_tokens":0,"total_tokens":10100}}}}Expected behavior
The two token_usage_record rows are counted: 16,000 input, 4,000 cached, 200 output. The first token_count is the inherited baseline and is rightly skipped. A rollout that opens with compacted and has one timestamp throughout can't be split by timestamp, so the records themselves look like the safer signal.
Version
ccusage 20.0.48 on Linux x64. Codex VS Code extension 0.164.0-alpha.11.1.
Activity
pullfrog commentedon Nov 9, 2026
fix(codex): keep identical requests from one rollout distinct
test(codex): cover the #2046 rollout in every Codex report mode
fix(codex): count spawned subagent requests stamped at the fork insta…
chore: credit issue reporters for #2050 and #2051