Repository navigation
Description
Summary
When OpenAI Codex spawns subagent threads via thread_spawn, the subagent's rollout JSONL file contains a full replay of the parent thread's token usage history, re-timestamped to the subagent's creation time. @ccusage/codex treats all these replayed token_count events as real API calls, inflating reported usage by up to 91x.
Environment
@ccusage/codexversion: latest (as of 2026-04-18)- Codex CLI version: 0.120.0
- Platform: macOS
Reproduction
- Have a long-running Codex session (parent thread) that accumulates significant token usage over days
- The parent spawns multiple subagents via
thread_spawn(e.g., worker/explorer agents) - Run
npx @ccusage/codex dailyon the date the subagents were created - Observe astronomically high token counts
Root Cause (triple inflation)
Layer 1: Parent history replay in subagent rollout files
When a subagent is forked from a parent thread, its rollout file includes two session_meta entries:
{"type": "session_meta", "payload": {"id": "<subagent-id>", "source": {"subagent": {"thread_spawn": {"parent_thread_id": "<parent-id>"}}}}}
{"type": "session_meta", "payload": {"id": "<parent-id>"}}The subagent file then replays the parent's entire conversation history — all event_msg entries with token_count payloads — with timestamps all set to the subagent's creation time (within the same second). For example, a subagent created at T will have thousands of token_count entries all timestamped T.xxx.
The replay accounts for 99.8% of the token data in each subagent's rollout file. The subagent's own actual API calls are only ~0.2%.
Layer 2: Duplicate logging
Within each rollout file, roughly 47% of entries are exact duplicates — same timestamp (to the millisecond), same last_token_usage, same total_token_usage, same rate_limits. This causes ccusage to count each replayed call twice (since last_token_usage is non-null in both copies).
Layer 3: Multiple subagents replaying the same history
The parent spawned 12 subagents for the same task, and each independently replayed the parent's full history. So the parent's token usage was counted 12 times.
Impact
Metric | ccusage reported | Actual -- | -- | -- Input tokens | ~20.6B | ~226M Cost | ~$9,041 | ~$100 Inflation factor | | 91xSuggested Fix
ccusage could detect and skip replayed entries by:
- Detect subagent sessions: Check for
session_metaentries withsource.subagent.thread_spawn. If present, the session is a forked subagent. - Identify replay boundary: In subagent files, the replayed entries all share the same creation timestamp (first ~N thousand entries). Real entries have timestamps that differ by minutes. The replay can be detected by finding where timestamps diverge from the session creation time.
- Alternatively, skip parent history: The second
session_meta(with the parent's ID) marks the start of replayed history. Entries before the first "live" event (where timestamp meaningfully differs) should be treated as context, not new usage. - Deduplicate: Even for non-replay entries, entries with identical
(timestamp, last_token_usage.input_tokens, last_token_usage.output_tokens)should be deduplicated to prevent double-counting.
Minimal test case indicators
A subagent rollout file affected by this bug will have:
- Two
session_metaentries (self + parent) source.subagent.thread_spawnin the firstsession_meta- Thousands of
token_countentries all within 1 second of the file's creation time - The same
total_token_usageprogression as the parent's rollout file - ~47% exact-duplicate entries (identical timestamp + token values)
Activity
Tengs-Fan commentedon Jun 6, 2026
I meet the same problem, I was scared when ccusage shows that I spent $5500 on token in one day
ryoppippi commentedon Jun 6, 2026
@pullfrog could you work on it?
pullfrog commentedon Jun 6, 2026
Implemented fix for #950: detect thread_spawn subagent sessions and skip replayed parent token history to prevent 91x token overcounting.
PR: #1218
Approach:
thread_spawnbyte pattern to detect subagent sessionsAll 215 existing tests pass, plus 2 new fixture-based tests covering single-subagent and multi-subagent scenarios.
Task list (6/6 completed)
DeepSeek Pro(free via Pullfrog for OSS) | 𝕏fix(codex): skip replayed parent token history in thread_spawn subage…
fix(codex): skip replayed parent token history in thread_spawn subage…
Codex: skip the fork replay burst structurally
Codex: dedupe fork-replayed history by content, not position (#37)
fix(codex): dedupe replayed usage (#1435)
Usage panel: Codex accuracy, transcript attribution, and a self-verif…
weathon commentedon Aug 23, 2026
I still see this problem at ccusage 20.0.18, it shows 54,035,907 input and 6,638,218 output with 26 subagents. That is impossible in a day of single thread usage
retrievaaaa commentedon Sep 5, 2026
same. i resumed an old chat, and it created a bunch of new subagents and reused previous ones, and my days input cache tokens jumped up by 3.5 billion. looking at sessions it seems to come from subagents.
unless openai has gotten really generous i kinda doubt that i was able to rack up 1,7kUSD usage in 10% of my weekly limit lol