Skip to content

fix(codex): date fallback review model pricing - #1303

Merged
ryoppippi merged 7 commits into
mainfrom
codex/date-aware-codex-review-pricing
Jun 12, 2026
Merged

fix(codex): date fallback review model pricing#1303
ryoppippi merged 7 commits into
mainfrom
codex/date-aware-codex-review-pricing

Conversation

@ryoppippi

@ryoppippi ryoppippi commented Jun 12, 2026

Copy link
Copy Markdown
Member

Summary:

  • Resolve Codex `codex-auto-review` log labels to the newest known Codex/OpenAI model available on each event date.
  • Move that behavior out of the undated pricing alias path so older review logs no longer price as `gpt-5.5` unconditionally.
  • Document the date-aware fallback behavior in the Codex guide.

Testing:

  • just fmt
  • cargo test --manifest-path rust/Cargo.toml -p ccusage resolves_codex_auto_review
  • cargo test --manifest-path rust/Cargo.toml -p ccusage embedded_pricing_
  • cargo test --manifest-path rust/Cargo.toml -p ccusage codex
  • pre-push hooks via nix develop --command git push

View with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is enabled.


Summary by cubic

Fix Codex review pricing by resolving codex-auto-review to the newest available model per log date during parsing, using an embedded models.dev snapshot. Invalid or missing dates fall back to gpt-5, and the embedded snapshot is now included in Nix builds.

  • Bug Fixes
    • Generate and embed the Codex review fallback table from pinned models.dev, with correct base vs -codex same-day handling; parse once at runtime (no extra I/O). just gen-models-dev-pricing now refreshes both snapshots.
    • Resolve from the raw log timestamp, trying created_at/createdAt and nested fields when the top-level value is malformed; validate YYYY-MM-DD, month lengths, and leap years; invalid/pre-table/missing dates map to gpt-5.
    • Remove the undated alias in pricing so codex-auto-review doesn’t resolve globally or set a context limit.
    • Update the Codex guide to note parser-side mapping from the pinned snapshot; add tests for per-date mapping, malformed timestamps with fallback fields, file mtime fallback, ordering, and turn_context.
    • Include the embedded fallback JSON in Nix cleanSource so native packages build correctly.
    • Make just gen-models-dev-pricing fail fast by chaining build and copy with &&.

Written for commit 01b690b. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Documentation

    • Clarified Codex guide: internal review aliases resolve to the newest known model as of an event's log date and explained alias mapping behavior.
  • Behavior

    • Undated codex-auto-review no longer maps to a fixed model and is treated as not found (no context limit); dated aliases resolve to the newest model for the event date.
  • Tests

    • Added unit tests for alias resolution across event dates, invalid dates, and contextual scenarios.
  • Chores

    • Vendored a dated fallback snapshot and updated generation tooling to produce and include it.

Codex can emit the internal codex-auto-review label for review runs, but pricing that label as gpt-5.5 for every historical row overstates older usage.

Resolve that label while parsing Codex logs, using a small release-date table from models.dev so each event falls back to the newest known Codex/OpenAI model available on the log date without extra I/O in the hot path.

Remove the undated pricing alias for codex-auto-review, keep the raw alias handling for gpt-5.3-spark, and document the date-aware fallback behavior in the Codex guide.
@ryoppippi

Copy link
Copy Markdown
Member Author

@coderabbitai review\n@cubic-dev-ai review

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Centralizes codex-auto-review resolution in the parser using a pinned, release-date-ordered fallback snapshot driven by a log-date timestamp; removes the undated pricing alias; adds loader tests for dated and invalid timestamps; and updates generation tooling and docs.

Changes

Codex Auto-Review Model Resolution

Layer / File(s) Summary
Parser timestamp-based resolution
rust/crates/ccusage/src/adapter/codex/parser.rs
Added CODEX_AUTO_REVIEW constants and embedded fallback snapshot loading, CodexExecTimestamps, raw/raw-or-normalized timestamp helpers, and resolve_codex_usage_model; refactored session and exec ingestion to use centralized dated fallback resolution and to mark fallback models.
Loader test coverage
rust/crates/ccusage/src/adapter/codex/loader.rs
Added three unit tests: multiple turn.completed events resolving per-event dated fallbacks, invalid-date handling defaulting to gpt-5, and turn_context-driven resolution for subsequent event_msg entries; all verify fallback flagging.
Pricing layer alias removal
rust/crates/ccusage/src/pricing.rs
Removed codex-auto-review from pricing_alias so the undated key no longer maps to a canonical pricing key; updated embedded pricing test to assert absence and no context limit.
User guide documentation
docs/guide/codex/index.md
Updated pricing and model-alias guidance to state the parser resolves codex-auto-review to the newest known Codex/OpenAI model available on the log date using a pinned models.dev snapshot prior to pricing.
models.dev generation and Nix/Just updates
nix/models-dev-gen.ts, nix/models-dev-pricing.nix, justfile, nix/packages.nix
Added generation of codex-auto-review-fallbacks.json, updated Nix wrapper to export both snapshots, and extended Just recipe to copy, chmod, and nix fmt both generated JSON files into the Rust crate.
Embedded fallback snapshot
rust/crates/ccusage/src/adapter/codex/codex-auto-review-fallbacks.json
Committed a release-date-ordered array of fallback entries mapping releasedOn dates to concrete gpt-* model identifiers used by the parser.
Packaging/source filter
package.nix
Updated lib.cleanSourceWith filter to retain codex-auto-review-fallbacks.json in the source tarball alongside models-dev-pricing.json.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • ccusage/ccusage#1301: Directly connected — both PRs touch codex-auto-review resolution vs pricing alias behavior.

Suggested reviewers

  • pullfrog

Poem

🐰 I hop through logs by date and time,
I map an alias to a concrete rhyme.
When dates are fuzzy, I choose the safe line,
Fallbacks ordered by release and sign.
🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 24.39% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: implementing date-aware fallback model resolution for codex-auto-review pricing, moving this logic from the undated pricing alias to the parser.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/date-aware-codex-review-pricing

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

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

@ryoppippi Sure, I'll review the changes!

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 12, 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 01b690b Commit Preview URL

Branch Preview URL
Jun 12 2026, 02:01 PM

@pkg-pr-new

pkg-pr-new Bot commented Jun 12, 2026

Copy link
Copy Markdown

Open in StackBlitz

ccusage

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

@ccusage/ccusage-darwin-arm64

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

@ccusage/ccusage-darwin-x64

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

@ccusage/ccusage-linux-arm64

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

@ccusage/ccusage-linux-x64

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

@ccusage/ccusage-win32-x64

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

commit: 3d80f23

@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 — resolves codex-auto-review log labels to the newest known Codex/OpenAI model per event date during parsing, removes the undated pricing alias so older logs no longer price as gpt-5.5.

  • Date-aware model resolution in parser — extracted duplicated model resolution into resolve_codex_usage_model with a codex_log_model_fallback that maps codex-auto-review per-event timestamp against a sorted table of (release_date, model_name) pairs.
  • Pricing alias removed"codex-auto-review" => Some("gpt-5.5") deleted from pricing_alias; the pricing module no longer resolves it globally.
  • New testsresolves_codex_auto_review_to_latest_model_for_event_date (direct turn.completed) and resolves_codex_auto_review_turn_context_for_each_event_date (context propagation); existing test renamed and inverted.
  • Docs update — Codex guide reflects the date-aware resolution path.

Pullfrog  | View workflow run | Using Big Pickle (free via Pullfrog for OSS) | 𝕏

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: 38fa2369bed4
Base SHA: e455f34601ac

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

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new e455f34601ac 584.0ms 725.3ms 56.1ms 3
PR pkg.pr.new 38fa236 828.9ms 771.5ms 53.7ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: e455f34601ac; PR package: 38fa236. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, 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
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 870.6ms 824.5ms 1.06x 731.00 MiB 728.25 MiB 1.00x 1.16 GiB/s 1.22 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 174.5ms 172.0ms 1.01x 93.00 MiB 89.75 MiB 0.97x 5.77 GiB/s 5.85 GiB/s

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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 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 717.6ms 1.40 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 850.7ms 1.18 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 152.5ms 6.60 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 121.5ms 8.28 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 rust/target/release/ccusage directly. 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 45.7ms 4.5ms 10.09x 44.00 MiB 3.00 MiB 0.07x 0.03 MiB/s 0.34 MiB/s
claude session --offline --json 0.00 MiB 37.8ms 4.6ms 8.19x 44.00 MiB 2.75 MiB 0.06x 0.04 MiB/s 0.34 MiB/s
codex daily --offline --json 0.00 MiB 37.8ms 4.4ms 8.60x 44.25 MiB 2.75 MiB 0.06x 0.02 MiB/s 0.20 MiB/s
codex session --offline --json 0.00 MiB 38.7ms 4.4ms 8.72x 44.25 MiB 2.75 MiB 0.06x 0.02 MiB/s 0.19 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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs rust/target/release/ccusage directly. 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 783.9ms 738.5ms 1.06x 747.75 MiB 744.00 MiB 0.99x 1.28 GiB/s 1.36 GiB/s
codex --offline --json 1.01 GiB 152.8ms 121.4ms 1.26x 92.00 MiB 87.50 MiB 0.95x 6.59 GiB/s 8.29 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 17.32 KiB 17.32 KiB -0.00 KiB 1.00x
installed native package binary 3325.09 KiB 3324.71 KiB -0.38 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: 38fa2369bed4
Base SHA: e455f34601ac

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

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new e455f34601ac 623.0ms 608.0ms 55.7ms 3
PR pkg.pr.new 38fa236 645.9ms 592.8ms 56.1ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: e455f34601ac; PR package: 38fa236. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, 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
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 744.7ms 848.0ms 0.88x 729.25 MiB 741.25 MiB 1.02x 1.35 GiB/s 1.19 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 196.2ms 202.3ms 0.97x 89.25 MiB 90.25 MiB 1.01x 5.13 GiB/s 4.98 GiB/s

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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 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 962.2ms 1.05 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 843.9ms 1.19 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 172.9ms 5.82 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 130.8ms 7.70 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 45.0ms 38.7ms 1.16x 44.00 MiB 44.25 MiB 1.01x 0.03 MiB/s 0.04 MiB/s
claude session --offline --json 0.00 MiB 37.9ms 36.3ms 1.05x 44.00 MiB 44.00 MiB 1.00x 0.04 MiB/s 0.04 MiB/s
codex daily --offline --json 0.00 MiB 36.9ms 38.8ms 0.95x 44.00 MiB 44.25 MiB 1.01x 0.02 MiB/s 0.02 MiB/s
codex session --offline --json 0.00 MiB 44.3ms 37.2ms 1.19x 44.25 MiB 44.00 MiB 0.99x 0.02 MiB/s 0.02 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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 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 845.1ms 854.4ms 0.99x 718.75 MiB 723.25 MiB 1.01x 1.19 GiB/s 1.18 GiB/s
codex --offline --json 1.01 GiB 171.2ms 166.4ms 1.03x 92.00 MiB 93.75 MiB 1.02x 5.88 GiB/s 6.05 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 17.32 KiB 17.32 KiB -0.00 KiB 1.00x
installed native package binary 3325.09 KiB 3324.71 KiB -0.38 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.

@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.

Actionable comments posted: 1

🧹 Nitpick comments (2)
rust/crates/ccusage/src/adapter/codex/parser.rs (2)

499-512: ⚡ Quick win

Inconsistent default fallback models for edge cases.

When the timestamp date cannot be parsed (line 504), the code defaults to "gpt-5.5" (the newest model). However, when the parsed date predates all known releases (line 510), it defaults to "gpt-5" (the oldest model). This inconsistency may confuse future maintainers and could cause old logs with malformed timestamps to be priced at the newest model rate. Consider defaulting both edge cases to the same conservative fallback (likely "gpt-5"), or document the rationale if the asymmetry is intentional.

♻️ Proposed consistent conservative fallback
     let Some(date) = codex_timestamp_date(timestamp) else {
-        return Some("gpt-5.5");
+        return Some("gpt-5");
     };

Alternatively, document the rationale:

+    // If timestamp is malformed, assume it's recent and use the newest model.
+    // Well-formed timestamps should always parse successfully after upstream normalization.
     let Some(date) = codex_timestamp_date(timestamp) else {
         return Some("gpt-5.5");
     };
🤖 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/crates/ccusage/src/adapter/codex/parser.rs` around lines 499 - 512, The
function codex_log_model_fallback has inconsistent edge-case defaults: when
codex_timestamp_date(timestamp) fails it returns "gpt-5.5" but when the parsed
date predates known releases it falls back to "gpt-5"; change the parse-failure
branch to return the same conservative fallback ("gpt-5") as the unwrap_or
branch so both edge cases are consistent. Locate codex_log_model_fallback and
replace the return Some("gpt-5.5") in the codex_timestamp_date None branch with
Some("gpt-5"), or alternatively add a short comment explaining and intentionally
preserving the asymmetry if that is required. Ensure references:
CODEX_AUTO_REVIEW_MODEL, codex_timestamp_date, and
CODEX_AUTO_REVIEW_FALLBACK_MODELS remain unchanged.

37-46: 💤 Low value

Document the fallback table ordering requirement.

The fallback table must remain ordered newest-to-oldest for the find_map logic at lines 507-510 to work correctly (it picks the first entry where date >= released_on). Consider adding a comment above the constant to make this constraint explicit for future maintainers.

📝 Suggested documentation comment
+// Release date → model fallback table for codex-auto-review.
+// IMPORTANT: Entries must be ordered newest-to-oldest by release date so that
+// find_map picks the newest model available on a given log date.
 const CODEX_AUTO_REVIEW_FALLBACK_MODELS: [(&str, &str); 7] = [
     ("2026-04-23", "gpt-5.5"),
🤖 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/crates/ccusage/src/adapter/codex/parser.rs` around lines 37 - 46, Add a
clear comment above the CODEX_AUTO_REVIEW_FALLBACK_MODELS constant documenting
that the array must be ordered newest-to-oldest (descending by date) because the
parser logic (the find_map that compares date >= released_on) relies on the
first matching entry; mention that changing the order will break the selection
of fallback models and that maintainers must insert new entries at the front to
preserve behavior.
🤖 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.

Inline comments:
In `@docs/guide/codex/index.md`:
- Line 63: The doc incorrectly states that the CLI resolves the
`codex-auto-review` alias via LiteLLM pricing data; update the text to reflect
the new flow: explain that the parser maps `codex-auto-review` to a dated
fallback (i.e., the parser’s alias mapping step) before any pricing runs, and
that `pricing.rs` no longer resolves that label — make the wording explicitly
say the parser performs the alias-to-dated-fallback mapping and pricing only
uses the already-resolved model name.

---

Nitpick comments:
In `@rust/crates/ccusage/src/adapter/codex/parser.rs`:
- Around line 499-512: The function codex_log_model_fallback has inconsistent
edge-case defaults: when codex_timestamp_date(timestamp) fails it returns
"gpt-5.5" but when the parsed date predates known releases it falls back to
"gpt-5"; change the parse-failure branch to return the same conservative
fallback ("gpt-5") as the unwrap_or branch so both edge cases are consistent.
Locate codex_log_model_fallback and replace the return Some("gpt-5.5") in the
codex_timestamp_date None branch with Some("gpt-5"), or alternatively add a
short comment explaining and intentionally preserving the asymmetry if that is
required. Ensure references: CODEX_AUTO_REVIEW_MODEL, codex_timestamp_date, and
CODEX_AUTO_REVIEW_FALLBACK_MODELS remain unchanged.
- Around line 37-46: Add a clear comment above the
CODEX_AUTO_REVIEW_FALLBACK_MODELS constant documenting that the array must be
ordered newest-to-oldest (descending by date) because the parser logic (the
find_map that compares date >= released_on) relies on the first matching entry;
mention that changing the order will break the selection of fallback models and
that maintainers must insert new entries at the front to preserve behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4ff84d5f-7469-456e-bc32-c626db819176

📥 Commits

Reviewing files that changed from the base of the PR and between e455f34 and 38fa236.

📒 Files selected for processing (4)
  • docs/guide/codex/index.md
  • rust/crates/ccusage/src/adapter/codex/loader.rs
  • rust/crates/ccusage/src/adapter/codex/parser.rs
  • rust/crates/ccusage/src/pricing.rs

Comment thread docs/guide/codex/index.md Outdated

@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.

No issues found across 4 files

Re-trigger cubic

Address review feedback on the date-aware codex-auto-review fallback.

Malformed timestamps now use the same conservative gpt-5 fallback as dates before the known release table, avoiding accidental newest-model pricing for bad data.

The Codex guide now states that the parser maps codex-auto-review before pricing, and the fallback table documents its descending date-order invariant.
@ryoppippi

Copy link
Copy Markdown
Member Author

@coderabbitai review\n\nAddressed the review feedback in 0b0d653: clarified that the Codex parser maps `codex-auto-review` before pricing, made malformed timestamps use the conservative `gpt-5` fallback, and documented the fallback table order invariant.\n\nValidation: `nix develop --command cargo test --manifest-path rust/Cargo.toml -p ccusage codex` and pre-push hooks passed.

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

@ryoppippi Sure! I'll review the latest changes in commit 0b0d6537 that address the previous feedback. Starting the review now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
rust/crates/ccusage/src/adapter/codex/parser.rs (1)

500-512: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Malformed timestamp validation is still too permissive, so newest-model pricing can leak through.

At Line 515-524, codex_timestamp_date accepts any YYYY-MM-DD-shaped prefix (e.g. 2026-99-99), and at Line 510-511 that value can still resolve to the newest fallback model. This breaks the conservative malformed-timestamp behavior (expected gpt-5) and can misprice bad data.

Proposed fix
 fn codex_log_model_fallback(model: &str, timestamp: &str) -> Option<&'static str> {
     if model != CODEX_AUTO_REVIEW_MODEL {
         return None;
     }
-    let Some(date) = codex_timestamp_date(timestamp) else {
+    let Some(date) = codex_timestamp_date(timestamp) else {
         return Some("gpt-5");
     };
     Some(
         CODEX_AUTO_REVIEW_FALLBACK_MODELS
             .iter()
             .find_map(|(released_on, fallback)| (date >= *released_on).then_some(*fallback))
             .unwrap_or("gpt-5"),
     )
 }

 fn codex_timestamp_date(timestamp: &str) -> Option<&str> {
     let date = timestamp.get(..10)?;
     let bytes = date.as_bytes();
-    (bytes.len() == 10
+    let is_basic_shape = bytes.len() == 10
         && bytes[0..4].iter().all(u8::is_ascii_digit)
         && bytes[4] == b'-'
         && bytes[5..7].iter().all(u8::is_ascii_digit)
         && bytes[7] == b'-'
-        && bytes[8..10].iter().all(u8::is_ascii_digit))
-    .then_some(date)
+        && bytes[8..10].iter().all(u8::is_ascii_digit);
+    if !is_basic_shape {
+        return None;
+    }
+    let month = (bytes[5] - b'0') * 10 + (bytes[6] - b'0');
+    let day = (bytes[8] - b'0') * 10 + (bytes[9] - b'0');
+    ((1..=12).contains(&month) && (1..=31).contains(&day)).then_some(date)
 }

Also applies to: 515-524

🤖 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/crates/ccusage/src/adapter/codex/parser.rs` around lines 500 - 512,
codex_timestamp_date is too permissive and allows invalid YYYY-MM-DD-like
prefixes, letting codex_log_model_fallback pick newer models; fix by making
codex_timestamp_date perform strict date parsing (e.g. use
chrono::NaiveDate::parse_from_str("%Y-%m-%d") or equivalent) and return None on
parse failure so codex_log_model_fallback will return the conservative
Some("gpt-5"). Update codex_timestamp_date implementation and add/adjust tests
for invalid dates; keep codex_log_model_fallback, CODEX_AUTO_REVIEW_MODEL and
CODEX_AUTO_REVIEW_FALLBACK_MODELS usage unchanged.
🤖 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.

Outside diff comments:
In `@rust/crates/ccusage/src/adapter/codex/parser.rs`:
- Around line 500-512: codex_timestamp_date is too permissive and allows invalid
YYYY-MM-DD-like prefixes, letting codex_log_model_fallback pick newer models;
fix by making codex_timestamp_date perform strict date parsing (e.g. use
chrono::NaiveDate::parse_from_str("%Y-%m-%d") or equivalent) and return None on
parse failure so codex_log_model_fallback will return the conservative
Some("gpt-5"). Update codex_timestamp_date implementation and add/adjust tests
for invalid dates; keep codex_log_model_fallback, CODEX_AUTO_REVIEW_MODEL and
CODEX_AUTO_REVIEW_FALLBACK_MODELS usage unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fc70e891-0549-44af-ae16-358246236417

📥 Commits

Reviewing files that changed from the base of the PR and between 38fa236 and 0b0d653.

📒 Files selected for processing (2)
  • docs/guide/codex/index.md
  • rust/crates/ccusage/src/adapter/codex/parser.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/guide/codex/index.md

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: 0b0d65374d65
Base SHA: e455f34601ac

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

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new e455f34601ac 602.7ms 635.6ms 53.9ms 3
PR pkg.pr.new 0b0d653 658.2ms 687.1ms 54.9ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: e455f34601ac; PR package: 0b0d653. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, 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
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 837.5ms 893.3ms 0.94x 734.00 MiB 733.00 MiB 1.00x 1.20 GiB/s 1.13 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 176.3ms 183.1ms 0.96x 91.50 MiB 93.00 MiB 1.02x 5.71 GiB/s 5.50 GiB/s

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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 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 942.9ms 1.07 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 986.7ms 1.02 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 168.0ms 5.99 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 124.7ms 8.07 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 38.6ms 43.6ms 0.88x 44.00 MiB 44.25 MiB 1.01x 0.04 MiB/s 0.04 MiB/s
claude session --offline --json 0.00 MiB 39.5ms 37.4ms 1.06x 44.25 MiB 44.00 MiB 0.99x 0.04 MiB/s 0.04 MiB/s
codex daily --offline --json 0.00 MiB 37.3ms 38.9ms 0.96x 44.00 MiB 44.00 MiB 1.00x 0.02 MiB/s 0.02 MiB/s
codex session --offline --json 0.00 MiB 36.7ms 39.5ms 0.93x 44.00 MiB 44.00 MiB 1.00x 0.02 MiB/s 0.02 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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 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 757.5ms 867.5ms 0.87x 738.00 MiB 735.50 MiB 1.00x 1.33 GiB/s 1.16 GiB/s
codex --offline --json 1.01 GiB 152.7ms 154.4ms 0.99x 90.50 MiB 86.25 MiB 0.95x 6.59 GiB/s 6.52 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 17.32 KiB 17.32 KiB -0.00 KiB 1.00x
installed native package binary 3325.09 KiB 3324.71 KiB -0.38 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: 0b0d65374d65
Base SHA: e455f34601ac

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

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new e455f34601ac 756.5ms 642.9ms 58.6ms 3
PR pkg.pr.new 0b0d653 579.2ms 634.3ms 57.6ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: e455f34601ac; PR package: 0b0d653. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, 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
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 949.4ms 909.9ms 1.04x 742.50 MiB 728.75 MiB 0.98x 1.06 GiB/s 1.11 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 196.2ms 194.0ms 1.01x 88.00 MiB 91.00 MiB 1.03x 5.13 GiB/s 5.19 GiB/s

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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 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 880.7ms 1.14 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 871.3ms 1.16 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 173.4ms 5.81 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 139.4ms 7.22 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 rust/target/release/ccusage directly. 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 38.6ms 6.1ms 6.28x 44.00 MiB 2.75 MiB 0.06x 0.04 MiB/s 0.25 MiB/s
claude session --offline --json 0.00 MiB 38.6ms 6.0ms 6.38x 44.00 MiB 2.75 MiB 0.06x 0.04 MiB/s 0.26 MiB/s
codex daily --offline --json 0.00 MiB 38.3ms 5.7ms 6.78x 44.00 MiB 2.75 MiB 0.06x 0.02 MiB/s 0.15 MiB/s
codex session --offline --json 0.00 MiB 39.7ms 5.5ms 7.23x 44.25 MiB 2.75 MiB 0.06x 0.02 MiB/s 0.16 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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs rust/target/release/ccusage directly. 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 874.3ms 858.7ms 1.02x 748.50 MiB 725.25 MiB 0.97x 1.15 GiB/s 1.17 GiB/s
codex --offline --json 1.01 GiB 180.4ms 145.4ms 1.24x 87.25 MiB 91.25 MiB 1.05x 5.58 GiB/s 6.92 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 17.32 KiB 17.32 KiB -0.00 KiB 1.00x
installed native package binary 3325.09 KiB 3324.71 KiB -0.38 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.

Resolve codex-auto-review model fallback dates from the raw log timestamp used for model selection instead of only the normalized event timestamp. This prevents malformed timestamp strings from being discarded and replaced by file mtime before the fallback decision.

Validate YYYY-MM-DD components before comparing release dates, including month ranges, month lengths, and leap years. Invalid or missing dates now conservatively resolve to gpt-5.

Add regression coverage for invalid month and non-leap-day Codex review logs.
@ryoppippi

Copy link
Copy Markdown
Member Author

Addressed the malformed-date review fallback issue in 8f0937e.

Changes:

  • validate the YYYY-MM-DD date components before release-date comparison, including month length and leap years
  • use the raw log timestamp for codex-auto-review model fallback decisions so malformed timestamps do not get replaced by file mtime before choosing a fallback
  • added regression coverage for invalid month and non-leap-day timestamps resolving conservatively to gpt-5

Validation:

  • nix develop --command cargo test --manifest-path rust/Cargo.toml -p ccusage resolves_codex_auto_review_with_invalid_event_date_to_conservative_model
  • nix develop --command cargo test --manifest-path rust/Cargo.toml -p ccusage codex
  • nix develop --command just fmt
  • pre-push hooks: clippy, treefmt, gitleaks, cargo test

@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 — calendar-level date validation, conservative malformed-timestamp fallback, and per-exec-event timestamp separation for model resolution.

  • Calendar-level date validationcodex_timestamp_date now validates month range and day-of-month bounds including leap years, rejecting 2026-99-99 and 2026-02-29 as invalid.
  • Conservative fallback — malformed-timestamp fallback changed from "gpt-5.5" to "gpt-5", consistent with the pre-table-date fallback (addresses prior CodeRabbit feedback).
  • Timestamp separation for exec eventsCodexExecTimestamps struct and raw_or_normalized_* helpers isolate the model-resolution timestamp from the event timestamp, so resolve_codex_usage_model uses the raw log timestamp for date-aware fallback.
  • New testresolves_codex_auto_review_with_invalid_event_date_to_conservative_model validates the conservative fallback for impossible dates.

Pullfrog  | View workflow run | Using Big Pickle (free via Pullfrog for OSS) | 𝕏

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: 8f0937e7c314
Base SHA: e455f34601ac

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

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new e455f34601ac 662.6ms 671.2ms 65.8ms 3
PR pkg.pr.new 8f0937e 808.1ms 725.6ms 73.1ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: e455f34601ac; PR package: 8f0937e. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, 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
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 953.0ms 999.8ms 0.95x 735.00 MiB 727.00 MiB 0.99x 1.06 GiB/s 1.01 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 223.1ms 203.6ms 1.10x 92.75 MiB 93.25 MiB 1.01x 4.51 GiB/s 4.94 GiB/s

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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 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 924.5ms 1.09 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 823.2ms 1.22 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 168.3ms 5.98 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 132.1ms 7.62 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 rust/target/release/ccusage directly. 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 44.5ms 5.9ms 7.60x 44.00 MiB 3.00 MiB 0.07x 0.03 MiB/s 0.26 MiB/s
claude session --offline --json 0.00 MiB 42.6ms 6.2ms 6.84x 44.00 MiB 2.75 MiB 0.06x 0.04 MiB/s 0.25 MiB/s
codex daily --offline --json 0.00 MiB 39.5ms 5.8ms 6.82x 44.25 MiB 2.75 MiB 0.06x 0.02 MiB/s 0.15 MiB/s
codex session --offline --json 0.00 MiB 40.5ms 5.9ms 6.85x 44.00 MiB 2.75 MiB 0.06x 0.02 MiB/s 0.14 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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs rust/target/release/ccusage directly. 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 810.5ms 888.6ms 0.91x 741.00 MiB 723.25 MiB 0.98x 1.24 GiB/s 1.13 GiB/s
codex --offline --json 1.01 GiB 186.7ms 137.2ms 1.36x 94.00 MiB 91.25 MiB 0.97x 5.39 GiB/s 7.34 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 17.32 KiB 17.32 KiB +0.00 KiB 1.00x
installed native package binary 3325.09 KiB 3326.40 KiB +1.31 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: 8f0937e7c314
Base SHA: e455f34601ac

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

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new e455f34601ac 561.5ms 877.0ms 91.6ms 3
PR pkg.pr.new 8f0937e 838.1ms 830.4ms 64.9ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: e455f34601ac; PR package: 8f0937e. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, 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
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 888.0ms 925.9ms 0.96x 727.25 MiB 724.25 MiB 1.00x 1.13 GiB/s 1.09 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 234.2ms 263.1ms 0.89x 95.25 MiB 94.00 MiB 0.99x 4.30 GiB/s 3.83 GiB/s

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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 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 967.9ms 1.04 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 818.7ms 1.23 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 220.6ms 4.56 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 198.3ms 5.08 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 52.0ms 55.4ms 0.94x 44.25 MiB 44.00 MiB 0.99x 0.03 MiB/s 0.03 MiB/s
claude session --offline --json 0.00 MiB 61.4ms 62.6ms 0.98x 44.25 MiB 44.25 MiB 1.00x 0.03 MiB/s 0.02 MiB/s
codex daily --offline --json 0.00 MiB 56.1ms 53.9ms 1.04x 44.00 MiB 44.25 MiB 1.01x 0.02 MiB/s 0.02 MiB/s
codex session --offline --json 0.00 MiB 49.3ms 55.4ms 0.89x 44.25 MiB 44.25 MiB 1.00x 0.02 MiB/s 0.02 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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 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 847.5ms 796.4ms 1.06x 718.25 MiB 727.00 MiB 1.01x 1.19 GiB/s 1.26 GiB/s
codex --offline --json 1.01 GiB 205.4ms 258.8ms 0.79x 95.00 MiB 94.50 MiB 0.99x 4.90 GiB/s 3.89 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 17.32 KiB 17.32 KiB +0.00 KiB 1.00x
installed native package binary 3325.09 KiB 3326.40 KiB +1.31 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.

@pullfrog

pullfrog Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Diagnosis

The check suite (73751687517) on PR #1303 reported conclusion: failure, but pullfrog_get_check_suite_logs returned no failed workflow runs — the workflow logs have expired. This matches the known pattern in the learnings (line 40): expired workflow runs on a previous commit.

Local verification

I ran the full suite of checks that CI would execute and all pass cleanly:

  • Rust tests: 258/258 passed (including the 3 new resolves_codex_auto_review_* tests)
  • Vitest tests: 41/41 passed
  • cargo clippy: clean (no warnings or errors)
  • cargo fmt --check: clean (no formatting changes)
  • Git working tree: clean

No code changes were needed — the PR's code is correct and all checks pass locally.

Action taken

Pushed the current tip to origin/codex/date-aware-codex-review-pricing to retrigger CI on the latest commit.

Task list (5/5 completed)

Pullfrog  | View workflow run | via Pullfrog | Using Big Pickle (free via Pullfrog for OSS) | 𝕏

Replace the hand-written codex-auto-review release table in the parser with an embedded snapshot generated from the pinned models.dev input.

Extend the models.dev snapshot generator to emit Codex auto-review fallback metadata alongside the existing pricing snapshot, and wire the just recipe to refresh both generated files.

Keep runtime lookup fast by parsing the tiny embedded snapshot once through LazyLock, while preserving the existing date-aware fallback behavior and malformed-date conservative fallback.
@ryoppippi

Copy link
Copy Markdown
Member Author

Good catch. The previous implementation had the fallback release table hand-written in parser.rs.

Updated in 5331af1:

  • removed the hand-written parser fallback table
  • generate codex-auto-review fallback metadata from the pinned models.dev input alongside the existing models.dev pricing snapshot
  • embed the generated codex-auto-review-fallbacks.json and parse it once with LazyLock, so runtime lookup stays local and cheap
  • documented that codex-auto-review fallback uses the pinned models.dev snapshot

Validation:

  • nix develop --command cargo test --manifest-path rust/Cargo.toml -p ccusage codex
  • nix develop --command just fmt
  • pre-push hooks: clippy, oxlint, treefmt, gitleaks, cargo test, vitest related

@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 — Extracted the codex-auto-review fallback table from a hardcoded Rust array to a committed JSON file, auto-generated from the pinned models.dev catalog via a new TS generator.

  • Extract fallback data to JSON — The hardcoded CODEX_AUTO_REVIEW_FALLBACK_MODELS array replaced with include_str! + zero-copy serde deserialization from codex-auto-review-fallbacks.json, keeping the same 7 entries.
  • New TS generatornix/models-dev-gen.ts updated to produce the fallback JSON alongside the existing pricing snapshot, filtering to GPT-5 family models and deduplicating codex/non-codex variants per decimal version.
  • Updated build pipelinenix/models-dev-pricing.nix outputs both snapshots; justfile recipe copies both files and formats them.
  • New testloads_codex_auto_review_fallbacks_from_models_dev_snapshot validates length, content, and descending date order of the embedded data.

Pullfrog  | View workflow run | Using Big Pickle (free via Pullfrog for OSS) | 𝕏

The Nix cleanSource filter only whitelists specific JSON files alongside
Cargo sources. The newly added codex-auto-review-fallbacks.json embedded
via include_str! by the codex parser was being filtered out, causing the
Linux/macOS/Windows native package builds to fail with 'No such file or
directory' at compile time.

Co-authored-by: Codesmith <[email protected]>

@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/crates/ccusage/src/adapter/codex/parser.rs (1)

968-979: ⚡ Quick win

Relax the snapshot-size assertions in this unit test.

just gen-models-dev-pricing now regenerates codex-auto-review-fallbacks.json, but this test still hardcodes the current snapshot length and edge entries. The next pinned models.dev bump will fail just check until parser.rs is manually edited too, even if the generated snapshot and parser logic are correct. Prefer asserting non-empty data plus ordering/shape, or compare directly against the committed JSON artifact instead.

♻️ Possible simplification
     let fallbacks = codex_auto_review_fallback_models();

-    assert_eq!(fallbacks.len(), 7);
-    assert_eq!(fallbacks[0].released_on, "2026-04-23");
-    assert_eq!(fallbacks[0].model, "gpt-5.5");
-    assert_eq!(fallbacks[6].released_on, "2025-08-07");
-    assert_eq!(fallbacks[6].model, "gpt-5");
+    assert!(!fallbacks.is_empty());
+    assert!(fallbacks
+        .iter()
+        .all(|fallback| !fallback.released_on.is_empty() && !fallback.model.is_empty()));
     assert!(fallbacks
         .windows(2)
         .all(|window| window[0].released_on > window[1].released_on));
🤖 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/crates/ccusage/src/adapter/codex/parser.rs` around lines 968 - 979, The
test loads_codex_auto_review_fallbacks_from_models_dev_snapshot is brittle
because it hardcodes snapshot length and exact edge entries; update it to
validate shape and ordering instead: call codex_auto_review_fallback_models(),
assert the returned Vec is non-empty, verify each entry has expected fields
populated (e.g., model and released_on not empty) and that the list is strictly
sorted by released_on using the existing windows check; optionally replace exact
value checks with a comparison to the committed codex-auto-review-fallbacks.json
artifact if you prefer exact match.
🤖 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/crates/ccusage/src/adapter/codex/parser.rs`:
- Around line 968-979: The test
loads_codex_auto_review_fallbacks_from_models_dev_snapshot is brittle because it
hardcodes snapshot length and exact edge entries; update it to validate shape
and ordering instead: call codex_auto_review_fallback_models(), assert the
returned Vec is non-empty, verify each entry has expected fields populated
(e.g., model and released_on not empty) and that the list is strictly sorted by
released_on using the existing windows check; optionally replace exact value
checks with a comparison to the committed codex-auto-review-fallbacks.json
artifact if you prefer exact match.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1a088920-2eaa-47ac-b7fa-afc576171bd8

📥 Commits

Reviewing files that changed from the base of the PR and between 8f0937e and 5331af1.

📒 Files selected for processing (7)
  • docs/guide/codex/index.md
  • justfile
  • nix/models-dev-gen.ts
  • nix/models-dev-pricing.nix
  • nix/packages.nix
  • rust/crates/ccusage/src/adapter/codex/codex-auto-review-fallbacks.json
  • rust/crates/ccusage/src/adapter/codex/parser.rs
✅ Files skipped from review due to trivial changes (2)
  • nix/packages.nix
  • docs/guide/codex/index.md

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: 833abbba9abd
Base SHA: e455f34601ac

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

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new e455f34601ac 636.5ms 671.9ms 56.2ms 3
PR pkg.pr.new 833abbb 668.1ms 686.9ms 64.7ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: e455f34601ac; PR package: 833abbb. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, 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
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 878.4ms 918.4ms 0.96x 730.50 MiB 723.75 MiB 0.99x 1.15 GiB/s 1.10 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 204.6ms 193.6ms 1.06x 91.25 MiB 89.50 MiB 0.98x 4.92 GiB/s 5.20 GiB/s

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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 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 948.2ms 1.06 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 938.1ms 1.07 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 171.6ms 5.87 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 133.4ms 7.54 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 48.0ms 41.0ms 1.17x 44.00 MiB 44.25 MiB 1.01x 0.03 MiB/s 0.04 MiB/s
claude session --offline --json 0.00 MiB 43.3ms 45.9ms 0.94x 44.00 MiB 44.00 MiB 1.00x 0.04 MiB/s 0.03 MiB/s
codex daily --offline --json 0.00 MiB 44.6ms 39.4ms 1.13x 44.00 MiB 44.00 MiB 1.00x 0.02 MiB/s 0.02 MiB/s
codex session --offline --json 0.00 MiB 37.6ms 39.1ms 0.96x 44.00 MiB 44.25 MiB 1.01x 0.02 MiB/s 0.02 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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 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 878.1ms 872.1ms 1.01x 725.50 MiB 740.50 MiB 1.02x 1.15 GiB/s 1.15 GiB/s
codex --offline --json 1.01 GiB 165.8ms 177.6ms 0.93x 92.75 MiB 90.75 MiB 0.98x 6.07 GiB/s 5.67 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 17.32 KiB 17.32 KiB -0.00 KiB 1.00x
installed native package binary 3325.09 KiB 3328.40 KiB +3.31 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: 833abbba9abd
Base SHA: e455f34601ac

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

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new e455f34601ac 714.6ms 711.2ms 55.4ms 3
PR pkg.pr.new 833abbb 879.2ms 709.0ms 53.6ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: e455f34601ac; PR package: 833abbb. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, 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
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 838.6ms 777.6ms 1.08x 744.50 MiB 730.00 MiB 0.98x 1.20 GiB/s 1.29 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 176.2ms 174.0ms 1.01x 88.50 MiB 90.25 MiB 1.02x 5.72 GiB/s 5.79 GiB/s

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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 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 847.4ms 1.19 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 741.2ms 1.36 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 164.2ms 6.13 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 122.1ms 8.25 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 rust/target/release/ccusage directly. 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 45.8ms 4.4ms 10.30x 44.00 MiB 2.75 MiB 0.06x 0.03 MiB/s 0.35 MiB/s
claude session --offline --json 0.00 MiB 45.0ms 4.5ms 9.94x 44.25 MiB 2.75 MiB 0.06x 0.03 MiB/s 0.34 MiB/s
codex daily --offline --json 0.00 MiB 36.9ms 4.1ms 9.00x 44.00 MiB 2.75 MiB 0.06x 0.02 MiB/s 0.21 MiB/s
codex session --offline --json 0.00 MiB 37.2ms 4.1ms 9.00x 44.25 MiB 2.75 MiB 0.06x 0.02 MiB/s 0.21 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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs rust/target/release/ccusage directly. 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 818.1ms 815.7ms 1.00x 729.75 MiB 732.50 MiB 1.00x 1.23 GiB/s 1.23 GiB/s
codex --offline --json 1.01 GiB 151.8ms 119.6ms 1.27x 91.25 MiB 89.25 MiB 0.98x 6.63 GiB/s 8.42 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 17.32 KiB 17.32 KiB -0.00 KiB 1.00x
installed native package binary 3325.09 KiB 3328.40 KiB +3.31 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.

3 issues found across 9 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

Comment thread justfile Outdated
Comment thread rust/crates/ccusage/src/adapter/codex/parser.rs
Comment thread nix/models-dev-gen.ts Outdated
Replace ';' with '&&' between the nix build and two cp commands in the
gen-models-dev-pricing recipe so that a failed earlier step doesn't get
silently masked by a later successful cp.

Co-authored-by: Codesmith <[email protected]>
@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: 3d80f2301d43
Base SHA: e455f34601ac

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

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new e455f34601ac 1.785s 2.430s 54.8ms 3
PR pkg.pr.new 3d80f23 985.6ms 1.516s 55.6ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: e455f34601ac; PR package: 3d80f23. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, 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
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 902.5ms 926.9ms 0.97x 727.25 MiB 731.00 MiB 1.01x 1.12 GiB/s 1.09 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 191.1ms 193.2ms 0.99x 90.50 MiB 88.00 MiB 0.97x 5.27 GiB/s 5.21 GiB/s

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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 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 882.7ms 1.14 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 859.0ms 1.17 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 167.9ms 6.00 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 130.9ms 7.69 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 rust/target/release/ccusage directly. 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 38.9ms 5.6ms 6.92x 44.00 MiB 3.00 MiB 0.07x 0.04 MiB/s 0.27 MiB/s
claude session --offline --json 0.00 MiB 38.3ms 6.0ms 6.42x 44.00 MiB 2.75 MiB 0.06x 0.04 MiB/s 0.26 MiB/s
codex daily --offline --json 0.00 MiB 43.3ms 5.2ms 8.28x 44.00 MiB 2.75 MiB 0.06x 0.02 MiB/s 0.16 MiB/s
codex session --offline --json 0.00 MiB 35.2ms 5.3ms 6.67x 44.00 MiB 2.75 MiB 0.06x 0.02 MiB/s 0.16 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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs rust/target/release/ccusage directly. 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 895.2ms 878.3ms 1.02x 730.00 MiB 728.50 MiB 1.00x 1.12 GiB/s 1.15 GiB/s
codex --offline --json 1.01 GiB 164.0ms 133.5ms 1.23x 88.00 MiB 88.25 MiB 1.00x 6.14 GiB/s 7.54 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 17.32 KiB 17.32 KiB -0.00 KiB 1.00x
installed native package binary 3325.09 KiB 3328.40 KiB +3.31 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: 3d80f2301d43
Base SHA: e455f34601ac

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

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new e455f34601ac 2.092s 1.060s 57.7ms 3
PR pkg.pr.new 3d80f23 2.571s 1.597s 56.1ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: e455f34601ac; PR package: 3d80f23. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, 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
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 900.0ms 937.3ms 0.96x 725.75 MiB 732.00 MiB 1.01x 1.12 GiB/s 1.07 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 194.3ms 191.6ms 1.01x 91.50 MiB 95.25 MiB 1.04x 5.18 GiB/s 5.25 GiB/s

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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 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 997.2ms 1.01 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 872.8ms 1.15 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 167.0ms 6.03 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 128.9ms 7.81 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 41.4ms 42.3ms 0.98x 44.00 MiB 44.00 MiB 1.00x 0.04 MiB/s 0.04 MiB/s
claude session --offline --json 0.00 MiB 39.8ms 39.4ms 1.01x 44.25 MiB 44.00 MiB 0.99x 0.04 MiB/s 0.04 MiB/s
codex daily --offline --json 0.00 MiB 39.7ms 36.6ms 1.08x 44.00 MiB 44.25 MiB 1.01x 0.02 MiB/s 0.02 MiB/s
codex session --offline --json 0.00 MiB 35.1ms 35.7ms 0.98x 44.00 MiB 44.00 MiB 1.00x 0.02 MiB/s 0.02 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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 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 850.6ms 863.1ms 0.99x 738.25 MiB 722.00 MiB 0.98x 1.18 GiB/s 1.17 GiB/s
codex --offline --json 1.01 GiB 164.4ms 167.4ms 0.98x 92.25 MiB 90.00 MiB 0.98x 6.12 GiB/s 6.01 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 17.32 KiB 17.32 KiB -0.00 KiB 1.00x
installed native package binary 3325.09 KiB 3328.40 KiB +3.31 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.

…s malformed

The model-date resolution chain in codex_model_timestamp_from_result used
raw_or_normalized_codex_timestamp, which returned any non-empty string as-is
regardless of whether it parsed as a date. That short-circuited the or_else
chain, so a malformed top-level `timestamp` would prevent the parser from
looking at `created_at`, `created_at_camel`, nested result-field
timestamps, or the file mtime fallback, and forced events through the
conservative gpt-5 mapping.

Validate the raw string against codex_timestamp_date before short-circuiting;
fall through to normalize_codex_timestamp / normalize_value_timestamp and
finally None so the rest of the chain can supply a valid date. Mirror the
same change for the serde_json::Value path.

Also fix the models.dev fallback generator so a gpt-5.x decimal base model is
only dropped when a gpt-5.x-codex variant exists on the SAME release date.
When the codex variant ships later, keeping the base entry lets events in the
gap still resolve to the most recent model actually available then.

Co-authored-by: Codesmith <[email protected]>
@ryoppippi
ryoppippi merged commit bfd28e0 into main Jun 12, 2026
13 of 15 checks passed
@ryoppippi
ryoppippi deleted the codex/date-aware-codex-review-pricing branch June 12, 2026 13:59
@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: 01b690bfe767
Base SHA: e455f34601ac

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

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new e455f34601ac 792.2ms 704.8ms 52.8ms 3
PR pkg.pr.new 01b690b 1.457s 923.3ms 54.5ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: e455f34601ac; PR package: 01b690b. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, 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
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 836.2ms 822.2ms 1.02x 736.00 MiB 744.00 MiB 1.01x 1.20 GiB/s 1.22 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 178.2ms 173.4ms 1.03x 90.50 MiB 88.00 MiB 0.97x 5.65 GiB/s 5.80 GiB/s

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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 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 799.2ms 1.26 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 709.6ms 1.42 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 151.4ms 6.65 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 118.6ms 8.49 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 44.5ms 36.8ms 1.21x 44.00 MiB 44.00 MiB 1.00x 0.03 MiB/s 0.04 MiB/s
claude session --offline --json 0.00 MiB 37.8ms 37.3ms 1.01x 44.25 MiB 44.00 MiB 0.99x 0.04 MiB/s 0.04 MiB/s
codex daily --offline --json 0.00 MiB 38.0ms 36.1ms 1.05x 44.00 MiB 44.00 MiB 1.00x 0.02 MiB/s 0.02 MiB/s
codex session --offline --json 0.00 MiB 37.7ms 37.5ms 1.00x 44.25 MiB 44.25 MiB 1.00x 0.02 MiB/s 0.02 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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 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 858.5ms 745.3ms 1.15x 744.50 MiB 740.50 MiB 0.99x 1.17 GiB/s 1.35 GiB/s
codex --offline --json 1.01 GiB 153.2ms 152.9ms 1.00x 90.25 MiB 92.75 MiB 1.03x 6.57 GiB/s 6.59 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 17.32 KiB 17.32 KiB -0.00 KiB 1.00x
installed native package binary 3325.09 KiB 3328.59 KiB +3.50 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: 01b690bfe767
Base SHA: e455f34601ac

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

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new e455f34601ac 919.8ms 1.220s 55.2ms 3
PR pkg.pr.new 01b690b 797.4ms 1.387s 53.9ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: e455f34601ac; PR package: 01b690b. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, 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
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 851.2ms 862.3ms 0.99x 749.50 MiB 745.00 MiB 0.99x 1.18 GiB/s 1.17 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 172.4ms 172.9ms 1.00x 91.00 MiB 89.50 MiB 0.98x 5.84 GiB/s 5.82 GiB/s

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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 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 742.5ms 1.36 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 760.1ms 1.32 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 153.4ms 6.56 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 119.1ms 8.45 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 rust/target/release/ccusage directly. 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 46.0ms 4.4ms 10.41x 44.25 MiB 3.00 MiB 0.07x 0.03 MiB/s 0.35 MiB/s
claude session --offline --json 0.00 MiB 48.2ms 4.4ms 10.89x 44.00 MiB 2.75 MiB 0.06x 0.03 MiB/s 0.35 MiB/s
codex daily --offline --json 0.00 MiB 37.2ms 4.2ms 8.83x 44.00 MiB 2.75 MiB 0.06x 0.02 MiB/s 0.20 MiB/s
codex session --offline --json 0.00 MiB 37.2ms 4.1ms 9.12x 44.00 MiB 2.75 MiB 0.06x 0.02 MiB/s 0.21 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, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs rust/target/release/ccusage directly. 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 747.0ms 740.5ms 1.01x 743.00 MiB 737.25 MiB 0.99x 1.35 GiB/s 1.36 GiB/s
codex --offline --json 1.01 GiB 152.5ms 119.5ms 1.28x 91.75 MiB 91.25 MiB 0.99x 6.60 GiB/s 8.43 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 17.32 KiB 17.32 KiB -0.00 KiB 1.00x
installed native package binary 3325.09 KiB 3328.59 KiB +3.50 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.

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.

1 participant