Repository navigation
Description
Summary
Straude currently pins Codex usage collection to @ccusage/codex@18, and Codex usage can be severely overstated for users who heavily use forked/spawned sessions.
Relevant Straude code:
packages/cli/src/lib/codex.tsconst CODEX_PKG = "@ccusage/codex@18"
Upstream context:
- ccusage issue: @ccusage/codex: Forked sessions double count shared token usage across sessions ccusage/ccusage#897
- main fix PR: [codex] fix forked session double-counting and optimize loading ccusage/ccusage#910
- follow-up fix PR I opened after reviewing
#910: Fix Codex token delta accounting jackcpku/ccusage#1
Case study from my usage
Straude estimated my last 7 days at roughly $70k of API-equivalent usage, which seemed implausible.
I dug into the raw Codex session logs and found two problems:
- forked Codex sessions can replay ancestor cumulative
token_countstate, which inflates totals if counted naively - there is also a mixed
last_token_usage/total_token_usagedelta bug that still overcounts some sessions unless corrected
After patching the loader locally and re-running against my actual logs, my last-7-days numbers changed from roughly:
- raw Codex total: 20.58B tokens
- corrected deduped Codex total: 9.05B tokens
- corrected Claude Code total: 0.78B tokens
- corrected combined total: 9.83B tokens
Using Straude-style API list-price estimates, that moved me from about $70k/week down to about $4,267.58/week:
- Codex: $3,911.82
- Claude Code: $355.76
- Combined: $4,267.58
That is still huge, but it is nowhere near the current displayed estimate.
Why this matters
This is not just a small edge-case normalization bug. For heavy Codex users who rely on forking/spawned sessions, leaderboards and personal cost estimates can be off by an order of magnitude.
Suggested path
Short term:
- add a note/warning that Codex totals may be inflated until the upstream
@ccusage/codexfix lands
Practical rollout options:
- Best: bump Straude to a released
@ccusage/codexversion once upstream merges/releases#910plus the follow-up fix - Fast opt-in: let advanced users override the Codex package name/version via an env var like
STRAUDE_CODEX_PKG, so they can point Straude at a patched npm tag/fork without waiting for a full Straude release - If needed: temporarily point Straude at a patched published fork package until upstream releases
I’m happy to share more detail or help test a Straude-side fix once the ccusage package version story is decided.
Activity
MaxGhenis commentedon Apr 14, 2026
Opened a small PR for the short-term rollout path here: https://github.com/ohong/straude/pull/88\n\nThis keeps as the default, but lets advanced users point Straude at a patched package via until upstream releases the fork-dedup fixes.
MaxGhenis commentedon Apr 14, 2026
Opened a small PR for the short-term rollout path here: #88
This keeps
@ccusage/codex@18as the default, but lets advanced users point Straude at a patched package viaSTRAUDE_CODEX_PKGuntil upstream releases the fork-dedup fixes.MaxGhenis commentedon Apr 14, 2026
Agreed that this should not be opt-in as the steady state. For a leaderboard, everyone should be on the accurate Codex accounting by default.
I opened PR #88 only as a temporary escape hatch because Straude currently shells out to a published package name (
@ccusage/codex@18), and there is not yet a published fixed release/package to point the default at.So my recommendation is:
@ccusage/codexfixesIf a patched package gets published before upstream releases, then Straude should just switch the default to that package rather than asking leaderboard users to opt in manually.
MaxGhenis commentedon Apr 14, 2026
I tried the real end-to-end path locally instead of just comparing custom scripts:
@ccusage/codexbranch (#910+ follow-up fixes)STRAUDE_CODEX_PKG=file:/tmp/ccusage-pack/ccusage-codex-18.0.10.tgzpush --days 7 --dry-runResult: Straude still showed the inflated ~$70k/week numbers. So the current
@ccusage/codexfix path is still not enough to trust leaderboard uploads for my data.That means there is at least one more overcounting path beyond the fixes in
#910and my follow-up PR. I am not going to upload the corrected number through Straude yet, because the package path that Straude can actually execute is still wrong for my corpus.I think the next step is to trace the remaining mismatch between:
$4.27k/week)@ccusage/codex daily --jsonpath (which still yields the inflated leaderboard number)Until that is resolved, I would treat Codex-heavy leaderboard values as suspect.
ohong commentedon Apr 25, 2026
PR #92 is now merged and replaces Straude’s Codex collection path with a native collector instead of
@ccusage/codex. The native collector fixes the two overcount paths described here:last_token_usage/total_token_usagerecords being counted twiceIt also adds a repair path for already-uploaded inflated rows. Once the web deploy containing #92 is live and the fixed CLI is published to npm, please run this from the machine that has the original Codex logs and the same Straude CLI config/device that uploaded the inflated data:
Do not pass
--datefor the repair run. On the first upgraded run, the CLI should detect local Codex logs and automatically do a one-time 30-day Codex resync, printing a short “repairing Codex totals” message. That corrected native submission is allowed to lower previously inflated Straude rows, so the profile, activity cards, contribution graph, and leaderboards should update from the correcteddaily_usagetotals.A few important caveats:
~/.codex/sessions/**/*.jsonllogs. Server-only aggregates are not enough to safely reconstruct true Codex usage.~/.straude/config.jsonwas regenerated and the device ID changed after the inflated upload, the server may not be able to match and lower that old per-device row automatically. In that case, comment here or DM me and we can do an admin-assisted repair.After running the upgraded push, please check your profile again. If any April Codex-heavy rows still look inflated, share the dates and whether the local Codex logs are still present, and I’ll help trace the remaining mismatch.
MaxGhenis commentedon Apr 27, 2026
Follow-up update: #88 is closed as superseded now that #92 moved Codex accounting to Straude's native collector. I opened #94 for the remaining native-pricing gap called out here: adding GPT-5.5/GPT-5.5 Pro pricing so those model names do not fall through to baseline GPT-5 pricing.
ohong commentedon May 8, 2026
Closing this out as resolved.
Straude no longer uses
@ccusage/codexfor Codex collection. The earlier native collector work moved Codex accounting into Straude, and PR #119 fixed the remaining overcount path described in this issue:total_token_usageis now treated as a per-request context snapshot, not a monotonic session cumulative counter.last_token_usageis used as the billing source of truth when present.token_countemissions are skipped only when bothtotal_token_usageandlast_token_usageare repeated.ccusage.This is released in
[email protected].For historical inflated rows, the intended repair path is to re-push from the machine that has the original local Codex logs:
That run re-reads local
~/.codex/sessionsdata and submits corrected daily totals. We intentionally do not repair these rows through heuristic SQL rewrites, because the local session logs are the source of truth.If anyone still sees obviously inflated Codex-heavy rows after running
straude@latestfrom the original machine, please reopen or file a follow-up with the affected dates and whether the local Codex logs are still present.MaxGhenis commentedon Jul 11, 2026
Taking you up on the admin-assisted repair offer: my Codex-heavy rows from before the native-collector fix are outside the 30-day backfill window and still inflated, and they're large enough to distort the all-time board.
Current state:
maxghenis: $425,671 / 1.10B output tokens~/.claude+~/.codexincludingarchived_sessions/, with the fork-replay and snapshot-vs-cumulative fixes applied, plus Claude-side cross-file resume dedup by(message.id, requestId)): ~$266,626 / 1.00B output tokensSetup matches your repair caveats: same machine, original Codex logs still present (
sessions/+archived_sessions/), and the same Straude device config that made the inflated uploads. I've run the upgraded push, which repaired the recent window; the older rows are the remainder.Since the window is also enforced server-side (
apps/web/app/api/usage/submit/route.tsrejects entries outsideMAX_BACKFILL_DAYS), there's no client-side path for this. Two options, whichever you prefer:daily_usagedirectly, orMAX_BACKFILL_DAYSwhen the submission comes from the samedevice_idthat created the row, so it can't be used to game numbers upward.I'm about to write publicly about my usage and would rather the top of the all-time board be accurate before I point people at it.