Skip to content

fix(codex): follow a rewritten replay burst past a second tick - #1501

Merged
ryoppippi merged 2 commits into
mainfrom
fix/codex-rewritten-burst-boundary
Jul 27, 2026
Merged

ryoppippi merged 2 commits into
mainfrom
fix/codex-rewritten-burst-boundary

Conversation

@ryoppippi

@ryoppippi ryoppippi commented Jul 27, 2026 •

Copy link
Copy Markdown
Member

Closes the gap left by #1457, which I closed as superseded — the one-second heuristic it rewrote no longer exists, but the residual bug it pointed at was real.

Problem

When a forked session's parent log is in the scanned set, CodexReplayPlan subtracts the exact replayed prefix and the accounting is correct. When it is not — the parent was deleted, archived elsewhere, or lives outside the scanned directory — the parser falls back to skipping the burst Codex rewrote to the fork instant.

That fallback bucketed events by their recorded second ([u8; 19] prefix compare). Codex writes the replayed history in a few milliseconds, so whenever a fork lands late in a second the burst straddles the tick — and everything after the tick was counted as the child's own usage.

One real subagent log in a local ~/.codex/sessions:

Scanned totalTokens
Child alone (parent absent, fallback) 47,175,282
Child + parent (exact prefix subtraction) 19,820,638

A 2.4x over-count, from 315 replayed records that landed in the second after the tick. Its burst is 458 records at 00:36:00 plus 315 at 00:36:01, all written between .985 and .000 — about 15ms of wall clock spread across two second strings.

Fix

Follow the run rather than the second: skip while successive usage events stay within a second of each other, carrying the last skipped timestamp instead of a fixed second.

The threshold is picked from measurement, not taste. Across the 229 fork sessions in that log directory, the 9 with a leading burst show:

Range
Burst span 10 – 40 ms
Pause before the child's own first turn 5,789 – 15,252 ms

One second sits two orders of magnitude above the burst and roughly 6x below the shortest real pause, so the two populations are cleanly separated.

I also checked #1457's own signal — task_started.started_at matching the record second — and did not adopt it. Across 1,833 real task_started records in fork sessions, 135 have started_at differing from their record second, including differences of exactly 1 second on native records that merely crossed a tick. Strict equality there misclassifies them.

Verification

  • 210 real fork sessions whose parent log could be located, each scanned twice, once alone and once beside its parent:

    Identical Mismatched Excess
    Before 209 / 210 1 27,354,644
    After 210 / 210 0 0

    The fallback now agrees with exact prefix subtraction on every one of them.

  • A full scan of the same directory is unchanged down to the cost figure: totalTokens 23,772,515,519, costUSD 12927.978162399995 before and after. The normal path is untouched.

  • just test green, just fmt 0 changed, cargo clippy --all-targets no warnings.

Test change to flag

skips_missing_parent_replay_when_duplicate_snapshot_is_suppressed placed the child's own turn 800ms after the burst. That only read as the child's own usage under second bucketing — by the measurements above an 800ms gap is inside a burst, not after one. The test's subject is snapshot suppression, so its fixture now uses a pause a real log would show and it keeps testing exactly that.

Known limits

A fork whose own first turn begins within a second of the replayed burst would still be skipped. The shortest real pause observed is 5.8 seconds, and the previous code carried the same class of exposure, so this narrows the window rather than closing it. The exact path via the parent log has no such limit; this is only the fallback.


View with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is enabled.


Summary by cubic

Fixes inflated token usage when a forked Codex session’s parent log is missing by following the rewritten replay burst across second boundaries and requiring monotonic timestamps. Aligns the fallback with exact-prefix subtraction and prevents counting replayed history as the child’s usage.

  • Bug Fixes
    • Skip the replayed burst by time continuity: continue skipping while successive events are monotonic and within 1,000ms.
    • Added CODEX_REWRITTEN_BURST_PAUSE_MS, detect_rewritten_burst, and a new state SkippingRewrittenBurst; use parse_ts_timestamp and real timestamps instead of [u8; 19] second prefixes.
    • Correctly handles bursts that straddle a tick and ignores duplicate snapshots; keeps the child’s own turns after the real pause.
    • Verification: 210/210 fork sessions now match exact subtraction; full scan totals unchanged; adjusted test fixture to use a realistic pause.

Written for commit afca9d3. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of replayed and forked Codex sessions, including bursts that cross second boundaries.
    • Prevented duplicate replay snapshots from being counted as new usage.
    • Preserved usage recorded during subsequent fork-local session activity.
  • Tests

    • Added coverage for rewritten replay bursts and fork-local usage scenarios.

When a forked session's parent log is not in the scanned set, the parser cannot
subtract the exact replayed prefix and falls back to skipping the burst Codex
rewrote to the fork instant. That fallback bucketed events by their recorded
second, so any burst written across a second tick was truncated and its
remainder counted as the child's own usage.

One real subagent log on hand reports 47,175,282 tokens through the fallback
against 19,820,638 when the parent log is present, a 2.4x over-count from 315
replayed records that landed in the second after the tick.

Follow the run instead of the second: skip while successive events stay within a
second of each other. Measured across the fork logs on hand, a rewritten burst
spans 10 to 40ms and the child's own first turn follows a pause of 5.8 to 15.3
seconds, so a second sits two orders of magnitude above the burst and well below
the pause.

Verified against 210 real fork sessions whose parent log could be located: the
fallback now returns the same totals as exact prefix subtraction for every one of
them, and a full scan is unchanged down to the cost figure.

`skips_missing_parent_replay_when_duplicate_snapshot_is_suppressed` placed the
child's own turn 800ms after the burst, which only read as the child's own under
second bucketing. Its subject is snapshot suppression, so the fixture now uses a
pause a real log would show and keeps testing that.

Closes the gap left by #1457.
Copilot AI review requested due to automatic review settings July 27, 2026 14:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 27, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
ccusage-guide afca9d3 Commit Preview URL

Branch Preview URL
Jul 27 2026, 02:25 PM

@coderabbitai

coderabbitai Bot commented Jul 27, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Codex replay detection now uses millisecond timestamp bursts instead of same-second anchoring. Loader tests cover multi-second replay bursts, preserved fork-local usage, and duplicate snapshot suppression.

Changes

Codex replay detection

Layer / File(s) Summary
Rewritten-burst state machine
rust/adapters/codex/src/parser.rs
Replaces SkippingSecond with SkippingRewrittenBurst, adds timestamp-based burst detection, and updates replay transitions to use the configured pause window.
Replay regression coverage
rust/adapters/codex/src/loader.rs
Adds coverage for bursts crossing second boundaries and child-local usage, and adjusts duplicate-snapshot fixture timing.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related issues

  • ccusage/ccusage issue 1460 — Covers the same Codex replay-detection behavior and multi-second fork replay overcount.

Possibly related PRs

  • ccusage/ccusage#1369 — Modifies Codex replay detection and forked-session loader regression tests.
  • ccusage/ccusage#1457 — Refactors timestamp-based replay-boundary detection and related fixtures.

Suggested reviewers: copilot

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main fix: replay burst handling now follows rewritten bursts across a second boundary.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/codex-rewritten-burst-boundary

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — replaces second-bucketed replay detection with time-continuity, following the rewritten burst past tick boundaries instead of splitting it.

  • detect_rewritten_burst replaces detect_replay_second — checks the first two usage events are within CODEX_REWRITTEN_BURST_PAUSE_MS (1000ms) rather than sharing a second-prefix byte string.
  • SkippingRewrittenBurst(TimestampMs) replaces SkippingSecond([u8; 19]) — carries the last skipped timestamp so successive events are gated by gap rather than second match, consuming any burst that stays within the threshold.
  • Two new tests cover the straddle case and multi-turn fork-local usage; an existing test fixture was adjusted to use a realistic post-burst pause (8s instead of 800ms) since the old gap no longer registers as "past the burst."

Pullfrog  | ⚠️ this action is pinned to a commit SHA, which freezes the cleanup step — switch to @v0 or keep the SHA fresh with Dependabot | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) | 𝕏

@pkg-pr-new

pkg-pr-new Bot commented Jul 27, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

ccusage

npx https://pkg.pr.new/ccusage@1501

@ccusage/ccusage-darwin-arm64

npx https://pkg.pr.new/@ccusage/ccusage-darwin-arm64@1501

@ccusage/ccusage-darwin-x64

npx https://pkg.pr.new/@ccusage/ccusage-darwin-x64@1501

@ccusage/ccusage-linux-arm64

npx https://pkg.pr.new/@ccusage/ccusage-linux-arm64@1501

@ccusage/ccusage-linux-x64

npx https://pkg.pr.new/@ccusage/ccusage-linux-x64@1501

@ccusage/ccusage-win32-x64

npx https://pkg.pr.new/@ccusage/ccusage-win32-x64@1501

commit: afca9d3

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
rust/adapters/codex/src/loader.rs (1)

1725-1749: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider a regression test for the documented residual limitation.

The PR notes the fallback can still skip a real child turn that begins within one second of the replay burst. None of the added tests pin this documented edge case down, so a future change to the pause threshold or state machine could silently alter that behavior without a failing test.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rust/adapters/codex/src/loader.rs` around lines 1725 - 1749, Add a regression
test alongside skips_a_rewritten_burst_that_straddles_a_second_boundary covering
a genuine child turn that begins within one second of the replay burst. Assert
the documented fallback behavior still skips that turn, so future changes to the
pause threshold or state machine cannot alter this residual limitation
unnoticed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@rust/adapters/codex/src/loader.rs`:
- Around line 1725-1749: Add a regression test alongside
skips_a_rewritten_burst_that_straddles_a_second_boundary covering a genuine
child turn that begins within one second of the replay burst. Assert the
documented fallback behavior still skips that turn, so future changes to the
pause threshold or state machine cannot alter this residual limitation
unnoticed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a87cd26d-8d68-4871-b105-7a487c94eb53

📥 Commits

Reviewing files that changed from the base of the PR and between 292e720 and facce31.

📒 Files selected for processing (2)
  • rust/adapters/codex/src/loader.rs
  • rust/adapters/codex/src/parser.rs

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: facce31d0c34
Base SHA: 292e7203b4a1

This compares the PR package against the configured base package on the same CI runner.

Package runtime diagnostics

Compares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 files)
All rows run --offline --json, measured by hyperfine with 0 warmups and 1 runs. This isolates wrapper overhead from the installed native optional dependency and the workspace release binary built on the runner.

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 358.1ms 2.81 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 300.1ms 3.35 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 117.5ms 8.57 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 93.0ms 10.83 GiB/s 1

Committed fixture performance

Committed small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage.

Fixtures: Claude apps/ccusage/test/fixtures/claude (0.00 MiB, 2 files), Codex apps/ccusage/test/fixtures/codex (0.00 MiB, 1 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 2 warmups and 7 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude daily --offline --json 0.00 MiB 25.8ms 25.4ms 1.02x 55.00 MiB 55.00 MiB 1.00x 0.06 MiB/s 0.06 MiB/s
claude session --offline --json 0.00 MiB 25.8ms 25.1ms 1.03x 55.25 MiB 55.25 MiB 1.00x 0.06 MiB/s 0.06 MiB/s
codex daily --offline --json 0.00 MiB 23.0ms 22.6ms 1.02x 55.00 MiB 55.00 MiB 1.00x 0.04 MiB/s 0.04 MiB/s
codex session --offline --json 0.00 MiB 23.1ms 23.2ms 1.00x 55.00 MiB 55.00 MiB 1.00x 0.04 MiB/s 0.04 MiB/s

Large real-world-shaped fixture performance

Generated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude --offline --json 1.01 GiB 370.8ms 343.0ms 1.08x 956.58 MiB 970.58 MiB 1.01x 2.71 GiB/s 2.94 GiB/s
codex --offline --json 1.01 GiB 136.6ms 126.5ms 1.08x 416.65 MiB 418.64 MiB 1.00x 7.37 GiB/s 7.96 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 18.78 KiB 18.78 KiB -0.00 KiB 1.00x
installed native package binary 4156.97 KiB 4156.78 KiB -0.19 KiB 1.00x

Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees.

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: facce31d0c34
Base SHA: 292e7203b4a1

This compares the Rust PR release binary against the configured base package on the same CI runner.

Package runtime diagnostics

Compares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 files)
All rows run --offline --json, measured by hyperfine with 0 warmups and 1 runs. This isolates wrapper overhead from the installed native optional dependency and the workspace release binary built on the runner.

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 351.2ms 2.87 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 310.9ms 3.24 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 138.2ms 7.28 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 108.6ms 9.27 GiB/s 1

Committed fixture performance

Committed small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage.

Fixtures: Claude apps/ccusage/test/fixtures/claude (0.00 MiB, 2 files), Codex apps/ccusage/test/fixtures/codex (0.00 MiB, 1 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published native ccusage binary from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 2 warmups and 7 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude daily --offline --json 0.00 MiB 31.8ms 5.5ms 5.80x 55.00 MiB 12.44 MiB 0.23x 0.05 MiB/s 0.28 MiB/s
claude session --offline --json 0.00 MiB 25.0ms 2.6ms 9.68x 55.00 MiB 12.45 MiB 0.23x 0.06 MiB/s 0.60 MiB/s
codex daily --offline --json 0.00 MiB 23.0ms 2.4ms 9.65x 54.75 MiB 10.45 MiB 0.19x 0.04 MiB/s 0.36 MiB/s
codex session --offline --json 0.00 MiB 22.8ms 2.3ms 9.90x 55.00 MiB 10.45 MiB 0.19x 0.04 MiB/s 0.37 MiB/s

Large real-world-shaped fixture performance

Generated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published native ccusage binary from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude --offline --json 1.01 GiB 374.9ms 336.7ms 1.11x 956.59 MiB 962.57 MiB 1.01x 2.69 GiB/s 2.99 GiB/s
codex --offline --json 1.01 GiB 114.7ms 91.2ms 1.26x 406.64 MiB 420.64 MiB 1.03x 8.78 GiB/s 11.03 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 18.78 KiB 18.78 KiB -0.00 KiB 1.00x
installed native package binary 4156.97 KiB 4156.78 KiB -0.19 KiB 1.00x

Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 2 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread rust/adapters/codex/src/parser.rs Outdated
Copilot AI review requested due to automatic review settings July 27, 2026 14:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed changes — tightens the burst gap check from <= 1000 to a 0..=1000 range, requiring monotonic timestamps so wrapping subtraction of a non-monotonic pair cannot slip through.

  • CODEX_REWRITTEN_BURST_PAUSE_MS gap check in detect_rewritten_burst and SkippingRewrittenBurst — gap <= 1000 → (0..=1000).contains(&gap). Since as_millis() returns i64, non-monotonic timestamps wrap to a negative value that the old <= check accepted but the range check correctly rejects.

Pullfrog  | ⚠️ this action is pinned to a commit SHA, which freezes the cleanup step — switch to @v0 or keep the SHA fresh with Dependabot | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) | 𝕏

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: afca9d380274
Base SHA: 292e7203b4a1

This compares the Rust PR release binary against the configured base package on the same CI runner.

Package runtime diagnostics

Compares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 files)
All rows run --offline --json, measured by hyperfine with 0 warmups and 1 runs. This isolates wrapper overhead from the installed native optional dependency and the workspace release binary built on the runner.

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 379.5ms 2.65 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 317.3ms 3.17 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 125.6ms 8.02 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 102.6ms 9.82 GiB/s 1

Committed fixture performance

Committed small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage.

Fixtures: Claude apps/ccusage/test/fixtures/claude (0.00 MiB, 2 files), Codex apps/ccusage/test/fixtures/codex (0.00 MiB, 1 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published native ccusage binary from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 2 warmups and 7 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude daily --offline --json 0.00 MiB 27.1ms 5.1ms 5.28x 55.00 MiB 12.44 MiB 0.23x 0.06 MiB/s 0.30 MiB/s
claude session --offline --json 0.00 MiB 24.8ms 3.2ms 7.66x 55.00 MiB 12.45 MiB 0.23x 0.06 MiB/s 0.48 MiB/s
codex daily --offline --json 0.00 MiB 25.0ms 2.5ms 10.07x 55.00 MiB 10.44 MiB 0.19x 0.03 MiB/s 0.35 MiB/s
codex session --offline --json 0.00 MiB 25.6ms 2.3ms 10.92x 55.00 MiB 10.44 MiB 0.19x 0.03 MiB/s 0.37 MiB/s

Large real-world-shaped fixture performance

Generated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published native ccusage binary from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude --offline --json 1.01 GiB 368.9ms 322.6ms 1.14x 956.58 MiB 960.57 MiB 1.00x 2.73 GiB/s 3.12 GiB/s
codex --offline --json 1.01 GiB 138.7ms 102.9ms 1.35x 428.90 MiB 414.65 MiB 0.97x 7.26 GiB/s 9.78 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 18.78 KiB 18.78 KiB -0.00 KiB 1.00x
installed native package binary 4156.97 KiB 4156.78 KiB -0.19 KiB 1.00x

Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees.

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: afca9d380274
Base SHA: 292e7203b4a1

This compares the PR package against the configured base package on the same CI runner.

Package runtime diagnostics

Compares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 files)
All rows run --offline --json, measured by hyperfine with 0 warmups and 1 runs. This isolates wrapper overhead from the installed native optional dependency and the workspace release binary built on the runner.

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 347.1ms 2.90 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 312.6ms 3.22 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 115.6ms 8.71 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 94.3ms 10.68 GiB/s 1

Committed fixture performance

Committed small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage.

Fixtures: Claude apps/ccusage/test/fixtures/claude (0.00 MiB, 2 files), Codex apps/ccusage/test/fixtures/codex (0.00 MiB, 1 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 2 warmups and 7 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude daily --offline --json 0.00 MiB 30.8ms 29.9ms 1.03x 55.00 MiB 55.00 MiB 1.00x 0.05 MiB/s 0.05 MiB/s
claude session --offline --json 0.00 MiB 23.6ms 27.4ms 0.86x 54.75 MiB 55.00 MiB 1.00x 0.07 MiB/s 0.06 MiB/s
codex daily --offline --json 0.00 MiB 25.8ms 24.7ms 1.04x 55.00 MiB 55.00 MiB 1.00x 0.03 MiB/s 0.03 MiB/s
codex session --offline --json 0.00 MiB 23.5ms 23.4ms 1.00x 55.00 MiB 55.00 MiB 1.00x 0.04 MiB/s 0.04 MiB/s

Large real-world-shaped fixture performance

Generated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude --offline --json 1.01 GiB 363.0ms 347.9ms 1.04x 958.59 MiB 954.57 MiB 1.00x 2.77 GiB/s 2.89 GiB/s
codex --offline --json 1.01 GiB 113.9ms 134.3ms 0.85x 422.65 MiB 422.66 MiB 1.00x 8.84 GiB/s 7.49 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 18.78 KiB 18.78 KiB -0.00 KiB 1.00x
installed native package binary 4156.97 KiB 4156.78 KiB -0.19 KiB 1.00x

Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees.

@ryoppippi
ryoppippi merged commit c462cb5 into main Jul 27, 2026
36 checks passed
@ryoppippi
ryoppippi deleted the fix/codex-rewritten-burst-boundary branch July 27, 2026 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants