Skip to content

test(rust): use shared fixture macro#1161

Merged
ryoppippi merged 6 commits into
mainfrom
codex/use-fs-fixture-macro
May 25, 2026
Merged

test(rust): use shared fixture macro#1161
ryoppippi merged 6 commits into
mainfrom
codex/use-fs-fixture-macro

Conversation

@ryoppippi
Copy link
Copy Markdown
Owner

@ryoppippi ryoppippi commented May 25, 2026

Replaces handwritten Rust test fixture setup with the shared fs_fixture! macro across loader, parser, CLI, and command tests.

This removes manual temp directory creation and cleanup in tests while keeping runtime behavior unchanged. It also documents the missing create-pr merge step for explicit merge requests.

Testing:

  • pnpm run format
  • env -u CFLAGS -u CPPFLAGS -u LDFLAGS direnv exec . pnpm run test
  • env -u CFLAGS -u CPPFLAGS -u LDFLAGS direnv exec . cargo clippy --manifest-path rust/Cargo.toml --workspace --all-targets -- -D warnings

Summary by cubic

Standardized Rust tests on the shared fs_fixture! macro and added explicit merge guidance for the create-pr skill. Also fixed Claude dedupe index refresh when replacing sidechain replays to keep later duplicates deduping correctly.

  • Refactors

    • Migrated tests across adapters, CLI, commands, and main to ccusage_test_support::fs_fixture!.
    • Removed temp dir helpers and manual cleanup; added a panic-safe GeminiDataDirEnvGuard to restore GEMINI_DATA_DIR in tests.
    • Kept direct Fixture::write_file coverage while creating the root via the macro.
    • Preserved recent Claude sidechain dedupe tests during the conversion.
    • Added references/merge.md and updated SKILL.md to require explicit user-requested merges.
  • Bug Fixes

    • Refresh dedupe indexes when a parent usage entry replaces a sidechain replay with a different request id, ensuring subsequent exact duplicates still dedupe.

Written for commit c45ce85. Summary will update on new commits. Review in cubic

Summary by CodeRabbit

  • Documentation

    • Added PR merge guidance requiring an explicit merge request, checklist verification, and a new reference describing merge conditions and recommended squash-merge flow.
  • Tests

    • Standardized test fixtures to a shared fixture helper and simplified test env guards, streamlining setup/teardown across the codebase while preserving existing test behavior.

Review Change Stack

ryoppippi added 2 commits May 25, 2026 20:51
Replaces handwritten temporary directory setup across Rust tests with the shared fs_fixture! macro. This keeps fixture construction consistent, removes manual cleanup, and lets assert_fs own temporary directory lifetimes.

The change also narrows test-only imports and guard structs where directory cleanup is now handled by the fixture helper.
Adds the missing create-pr guidance for cases where the user explicitly asks for merge completion. The new reference keeps merge gated on CodeRabbit review, passing required CI, and normal GitHub mergeability instead of treating PR readiness as the final step.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: abbbd664-5c3b-4b8c-983d-a8b1c86b9dac

📥 Commits

Reviewing files that changed from the base of the PR and between 2bcb6b8 and c45ce85.

📒 Files selected for processing (4)
  • rust/crates/ccusage/src/adapter/claude/mod.rs
  • rust/crates/ccusage/src/adapter/gemini/loader.rs
  • rust/crates/ccusage/src/adapter/gemini/mod.rs
  • rust/crates/ccusage/src/adapter/gemini/paths.rs

📝 Walkthrough

Walkthrough

Replace many tests' manual temp-dir setup with ccusage_test_support::fs_fixture! and add a new SKILL step plus references/merge.md requiring explicit user merge requests and completion-condition checks.

Changes

PR workflow documentation

Layer / File(s) Summary
PR workflow merge gate and verification
.agents/skills/create-pr/SKILL.md, .agents/skills/create-pr/references/merge.md
Add a new "Merge only when explicitly requested" step to SKILL.md and create merge.md describing explicit merge intent, completion-condition checks (CodeRabbit review, CI), and default squash-merge behavior.

Test infrastructure migration to fs_fixture

Layer / File(s) Summary
Test fixture support infrastructure
rust/crates/ccusage-test-support/src/lib.rs
Update the test-support crate tests to construct fixtures using the exported fs_fixture! macro instead of manually instantiating Fixture objects.
Adapter, CLI, and integration tests
rust/crates/ccusage/src/..., rust/crates/ccusage-test-support/src/lib.rs
Refactor numerous adapter test modules and CLI/main/commands tests to use ccusage_test_support::fs_fixture! for JSON/JSONL/SQLite fixture files; remove local temp-dir helpers and manual fs write/remove logic; simplify environment-variable guard helpers to only set/unset env vars.

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly Related PRs

Suggested labels: enhancement

"🐰
I burrowed through temp dirs,
planted fixtures neat and spry—
fs_fixture blooms tests. 🥕"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 76.40% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'test(rust): use shared fixture macro' accurately summarizes the main change: replacing handwritten test fixture setup with the shared fs_fixture! macro across Rust tests.
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.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/use-fs-fixture-macro

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

❤️ Share

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

@ryoppippi
Copy link
Copy Markdown
Owner Author

@coderabbitai please review this PR. The latest push replaces handwritten Rust test fixture setup with the shared fs_fixture! macro and adds the missing merge guidance to the create-pr skill.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 25, 2026

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 c45ce85 Commit Preview URL

Branch Preview URL
May 25 2026, 08:28 PM

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

@ryoppippi: This is a clean, well-executed refactor. The migration is consistent across all 26 files, and the net reduction (~505 lines) reflects genuine simplification. Here are my observations:


Review of test(rust): use shared fixture macro

✅ Strengths

  • Consistent pattern: Every test now follows the same fs_fixture!({...}) → fixture.path(...) idiom — no more ad-hoc SystemTime::now().as_nanos() uniqueness tricks.
  • Correct cleanup delegation: The EnvDirGuard structs in codebuff, droid, kimi, and goose are correctly simplified — they no longer own the directory, since the Fixture's Drop impl handles cleanup.
  • openclaw/loader.rs: The change from Some(dir.to_str().unwrap()) to fixture.root().to_str() is correct — Path::to_str() already returns Option<&str>, matching the expected argument type.
  • balances_file_chunks_by_size: Correctly uses "x".repeat(100) / "x" as file content to preserve the size differential the test depends on.
  • merge.md / SKILL.md: Clear and well-structured. The guard conditions ("if not mergeable, keep open and continue the loop") are exactly the right behavior to encode.

🔍 One observation worth noting

rust/crates/ccusage-test-support/src/lib.rscreates_incremental_fixture_tree test

// Before
let fixture = Fixture::new();
let _ = fixture.write_file("projects/example/session/chat.jsonl", "{}\n");

// After
let fixture = fs_fixture!({
    "projects/example/session/chat.jsonl": "{}\n",
});

This test previously served as direct coverage for the Fixture::new() + write_file() API. After the change, that code path is only exercised indirectly (by the macro expansion). If write_file is still part of the public API of ccusage-test-support, it would be worth keeping at least one test that calls it directly — e.g. a test that writes a file incrementally after initial fixture creation. That said, if write_file is now considered an internal detail, this is a non-issue.


Minor cosmetic

A few test closings have a trailing blank line left after removing the fs::remove_dir_all call (e.g. codex/loader.rs, copilot/loader.rs). These are harmless but could be tidied.


Overall this is a straightforward improvement — less boilerplate, cleaner tests, no behaviour changes.

✅ Actions performed

Review triggered.

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.

Merges origin/main to resolve the PR merge conflict after upstream Claude sidechain dedupe changes landed. The conflict resolution keeps the new upstream sidechain tests while retaining the fs_fixture! conversion for Claude usage file discovery tests.
@ryoppippi
Copy link
Copy Markdown
Owner Author

@coderabbitai please review the latest push. I merged origin/main to resolve the PR conflict, kept the new upstream Claude sidechain tests, retained the fs_fixture! conversion, and reran format, full tests, and clippy.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

@ryoppippi: On it — I'll review the latest push including the merge from origin/main, the new Claude sidechain tests, and the retained fs_fixture! conversions.

✅ Actions performed

Review triggered.

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.

Copy link
Copy Markdown

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

Choose a reason for hiding this comment

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

No issues found across 26 files

Re-trigger cubic

Updates the test-support fixture test to create the root through fs_fixture! while still calling Fixture::write_file directly. This addresses CodeRabbit feedback without reintroducing handwritten temporary directory setup.
@ryoppippi
Copy link
Copy Markdown
Owner Author

@coderabbitai I addressed your fixture-support observation in the latest push: the incremental fixture test now creates the root with fs_fixture!({}) and still calls Fixture::write_file directly, preserving direct API coverage without handwritten temp setup. I reran format, full tests, and clippy.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

Tip

For best results, initiate chat on the files or code changes.

@ryoppippi: That's a great solution — using fs_fixture!({}) for the empty root lets the macro handle lifecycle management while the explicit fixture.write_file(...) call directly exercises the public API as before. The best of both worlds. Thanks for the thorough follow-up and the rerun of all checks!

🐇 ✨

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@rust/crates/ccusage/src/adapter/gemini/loader.rs`:
- Around line 48-54: The test sets GEMINI_DATA_DIR_ENV then removes it manually,
which leaks the env var if the test panics; wrap the env change in a panic-safe
guard: capture the previous value with std::env::var_os(GEMINI_DATA_DIR_ENV),
set the env var, then create a small RAII drop guard (or use a scoped restore
pattern) that on Drop restores the previous value (or removes the var if None).
Apply this around the SharedArgs creation / call to load_entries and
PricingMap::load_embedded so GEMINI_DATA_DIR_ENV is always restored even if
load_entries or the test panics.
🪄 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

Run ID: 8ab5e42c-cf75-48a2-869e-f51ac5c7c4e8

📥 Commits

Reviewing files that changed from the base of the PR and between c86bc77 and 2b5fcc1.

📒 Files selected for processing (26)
  • .agents/skills/create-pr/SKILL.md
  • .agents/skills/create-pr/references/merge.md
  • rust/crates/ccusage-test-support/src/lib.rs
  • rust/crates/ccusage/src/adapter/amp/parser.rs
  • rust/crates/ccusage/src/adapter/claude/mod.rs
  • rust/crates/ccusage/src/adapter/codebuff/loader.rs
  • rust/crates/ccusage/src/adapter/codex/loader.rs
  • rust/crates/ccusage/src/adapter/codex/mod.rs
  • rust/crates/ccusage/src/adapter/copilot/loader.rs
  • rust/crates/ccusage/src/adapter/droid/loader.rs
  • rust/crates/ccusage/src/adapter/gemini/loader.rs
  • rust/crates/ccusage/src/adapter/gemini/paths.rs
  • rust/crates/ccusage/src/adapter/goose/loader.rs
  • rust/crates/ccusage/src/adapter/goose/paths.rs
  • rust/crates/ccusage/src/adapter/hermes/loader.rs
  • rust/crates/ccusage/src/adapter/kilo/loader.rs
  • rust/crates/ccusage/src/adapter/kimi/loader.rs
  • rust/crates/ccusage/src/adapter/kimi/parser.rs
  • rust/crates/ccusage/src/adapter/kimi/paths.rs
  • rust/crates/ccusage/src/adapter/openclaw/loader.rs
  • rust/crates/ccusage/src/adapter/opencode/loader.rs
  • rust/crates/ccusage/src/adapter/pi/parser.rs
  • rust/crates/ccusage/src/adapter/qwen/mod.rs
  • rust/crates/ccusage/src/cli.rs
  • rust/crates/ccusage/src/commands/mod.rs
  • rust/crates/ccusage/src/main.rs

Comment thread rust/crates/ccusage/src/adapter/gemini/loader.rs Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

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/claude/mod.rs (1)

241-279: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Refresh dedupe indexes after cross-key replacement

On Line 266, replacements can now occur after sidechain fallback matching, but only new insertions (Line 275+) update deduped_indexes. When replacement happens with a different exact (message_id, request_id) hash, later duplicates for that exact key can bypass dedupe and be appended.

💡 Proposed fix
-    if let Some((_, Some(index))) = dedupe_lookup {
+    if let Some((hash, Some(index))) = dedupe_lookup {
         if should_replace_deduped_entry(&entry.data, &deduped[index].data) {
             deduped[index] = entry;
+            push_deduped_index(deduped_indexes, hash, index);
+            if let Some(message_id) = deduped[index].data.message.id.as_deref() {
+                push_deduped_index(deduped_indexes, usage_dedupe_hash(message_id, None), index);
+            }
         }
         return;
     }
🤖 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/claude/mod.rs` around lines 241 - 279, When
replacing an existing deduped entry (the block handling Some((_, Some(index)))
where you call should_replace_deduped_entry and then set deduped[index] = entry)
you must also refresh deduped_indexes for the new entry keys so future lookups
for the exact (message_id, request_id) or message-only hash don't miss
duplicates; after assigning deduped[index] = entry, compute the new exact hash
via usage_dedupe_hash using the new entry's message.id and request_id and call
push_deduped_index(deduped_indexes, new_hash, index), and likewise if the new
entry has a message.id call push_deduped_index with
usage_dedupe_hash(message_id, None); use the existing symbols deduped_indexes,
deduped, entry, index, usage_dedupe_hash, push_deduped_index and
message.id.as_deref() to locate and update the code.
🤖 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/claude/mod.rs`:
- Around line 241-279: When replacing an existing deduped entry (the block
handling Some((_, Some(index))) where you call should_replace_deduped_entry and
then set deduped[index] = entry) you must also refresh deduped_indexes for the
new entry keys so future lookups for the exact (message_id, request_id) or
message-only hash don't miss duplicates; after assigning deduped[index] = entry,
compute the new exact hash via usage_dedupe_hash using the new entry's
message.id and request_id and call push_deduped_index(deduped_indexes, new_hash,
index), and likewise if the new entry has a message.id call push_deduped_index
with usage_dedupe_hash(message_id, None); use the existing symbols
deduped_indexes, deduped, entry, index, usage_dedupe_hash, push_deduped_index
and message.id.as_deref() to locate and update the code.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 02fa7b98-97b9-4359-a486-36154f09987b

📥 Commits

Reviewing files that changed from the base of the PR and between 2b5fcc1 and eb845e3.

📒 Files selected for processing (9)
  • rust/crates/ccusage-test-support/src/lib.rs
  • rust/crates/ccusage/src/adapter/amp/parser.rs
  • rust/crates/ccusage/src/adapter/claude/mod.rs
  • rust/crates/ccusage/src/adapter/codebuff/loader.rs
  • rust/crates/ccusage/src/adapter/copilot/loader.rs
  • rust/crates/ccusage/src/adapter/droid/loader.rs
  • rust/crates/ccusage/src/adapter/kimi/parser.rs
  • rust/crates/ccusage/src/adapter/pi/parser.rs
  • rust/crates/ccusage/src/main.rs

Apply cargo fmt to the Rust tests changed in the fixture macro refactor.

The CI lint-check runs nix flake check, which includes ccusage-rust-fmt. The previous local format pass did not cover the Rust workspace formatting shape used by that check, so this commit keeps the follow-up limited to rustfmt output.
@ryoppippi
Copy link
Copy Markdown
Owner Author

@coderabbitai I pushed a rustfmt-only follow-up after CI reported ccusage-rust-fmt differences. Please review the latest commit as well.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

@ryoppippi: On it — I'll review the rustfmt formatting follow-up commit now.

✅ Actions performed

Review triggered.

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.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 25, 2026

Open in StackBlitz

ccusage

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

@ccusage/ccusage-darwin-arm64

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

@ccusage/ccusage-darwin-x64

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

@ccusage/ccusage-linux-arm64

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

@ccusage/ccusage-linux-x64

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

@ccusage/ccusage-win32-arm64

npx https://pkg.pr.new/@ccusage/ccusage-win32-arm64@1161

@ccusage/ccusage-win32-x64

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

commit: c45ce85

@github-actions
Copy link
Copy Markdown

ccusage performance comparison

PR SHA: 6ec6d3faa9cd
Base SHA: c86bc7707764

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 c86bc7707764 896.5ms 409.8ms 35.8ms 3
PR pkg.pr.new 6ec6d3f 441.2ms 535.2ms 35.3ms 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: c86bc7707764; PR package: 6ec6d3f. 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 567.8ms 575.4ms 0.99x 290.83 MiB 294.95 MiB 1.01x 1.77 GiB/s 1.75 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 370.4ms 366.8ms 1.01x 66.95 MiB 65.08 MiB 0.97x 2.72 GiB/s 2.74 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 553.5ms 1.82 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 533.1ms 1.89 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 360.9ms 2.79 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 338.1ms 2.98 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 32.0ms 32.2ms 0.99x 43.48 MiB 43.61 MiB 1.00x 0.05 MiB/s 0.05 MiB/s
claude session --offline --json 0.00 MiB 32.3ms 32.1ms 1.01x 43.48 MiB 43.61 MiB 1.00x 0.05 MiB/s 0.05 MiB/s
codex daily --offline --json 0.00 MiB 31.7ms 31.4ms 1.01x 43.61 MiB 43.73 MiB 1.00x 0.03 MiB/s 0.03 MiB/s
codex session --offline --json 0.00 MiB 31.1ms 32.0ms 0.97x - 43.61 MiB - 0.03 MiB/s 0.03 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 564.4ms 542.6ms 1.04x 297.95 MiB - - 1.78 GiB/s 1.86 GiB/s
codex --offline --json 1.01 GiB 364.2ms 355.1ms 1.03x 51.45 MiB 59.95 MiB 1.17x 2.76 GiB/s 2.84 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 14.22 KiB 14.21 KiB -0.00 KiB 1.00x
installed native package binary 3289.49 KiB 3289.49 KiB +0.00 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

ccusage performance comparison

PR SHA: 6ec6d3faa9cd
Base SHA: c86bc7707764

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 c86bc7707764 571.5ms 541.4ms 34.7ms 3
PR pkg.pr.new 6ec6d3f 863.4ms 668.3ms 35.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: c86bc7707764; PR package: 6ec6d3f. 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 567.8ms 568.0ms 1.00x 313.83 MiB 302.95 MiB 0.97x 1.77 GiB/s 1.77 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 369.4ms 372.3ms 0.99x 57.20 MiB 51.45 MiB 0.90x 2.73 GiB/s 2.70 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 561.8ms 1.79 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 522.9ms 1.93 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 357.6ms 2.82 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 334.5ms 3.01 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 35.3ms 4.9ms 7.25x 43.61 MiB 2.83 MiB 0.06x 0.04 MiB/s 0.32 MiB/s
claude session --offline --json 0.00 MiB 34.9ms 4.8ms 7.26x 43.61 MiB 2.83 MiB 0.06x 0.04 MiB/s 0.32 MiB/s
codex daily --offline --json 0.00 MiB 31.1ms 3.9ms 7.91x 43.61 MiB 2.83 MiB 0.06x 0.03 MiB/s 0.22 MiB/s
codex session --offline --json 0.00 MiB 31.2ms 4.1ms 7.62x 43.48 MiB 2.83 MiB 0.07x 0.03 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 561.6ms 524.5ms 1.07x 275.45 MiB 311.45 MiB 1.13x 1.79 GiB/s 1.92 GiB/s
codex --offline --json 1.01 GiB 361.9ms 337.9ms 1.07x 57.45 MiB 65.33 MiB 1.14x 2.78 GiB/s 2.98 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 14.22 KiB 14.21 KiB -0.00 KiB 1.00x
installed native package binary 3289.49 KiB 3289.49 KiB +0.00 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

ccusage performance comparison

PR SHA: eb845e3a281c
Base SHA: c86bc7707764

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 c86bc7707764 648.4ms 597.5ms 34.5ms 3
PR pkg.pr.new eb845e3 1.184s 685.0ms 35.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: c86bc7707764; PR package: eb845e3. 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 560.2ms 557.8ms 1.00x 287.45 MiB 300.08 MiB 1.04x 1.80 GiB/s 1.80 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 365.7ms 366.3ms 1.00x 59.33 MiB 58.20 MiB 0.98x 2.75 GiB/s 2.75 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 557.5ms 1.81 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 525.9ms 1.91 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 364.5ms 2.76 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 334.3ms 3.01 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 32.0ms 32.1ms 1.00x - 43.48 MiB - 0.05 MiB/s 0.05 MiB/s
claude session --offline --json 0.00 MiB 31.7ms 32.0ms 0.99x 43.48 MiB 43.61 MiB 1.00x 0.05 MiB/s 0.05 MiB/s
codex daily --offline --json 0.00 MiB 31.3ms 31.3ms 1.00x 43.61 MiB 43.48 MiB 1.00x 0.03 MiB/s 0.03 MiB/s
codex session --offline --json 0.00 MiB 31.5ms 31.4ms 1.00x - 43.61 MiB - 0.03 MiB/s 0.03 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 568.2ms 572.0ms 0.99x 299.83 MiB 324.95 MiB 1.08x 1.77 GiB/s 1.76 GiB/s
codex --offline --json 1.01 GiB 366.0ms 363.2ms 1.01x 63.08 MiB 57.83 MiB 0.92x 2.75 GiB/s 2.77 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 14.22 KiB 14.21 KiB -0.00 KiB 1.00x
installed native package binary 3289.49 KiB 3289.49 KiB +0.00 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

ccusage performance comparison

PR SHA: eb845e3a281c
Base SHA: c86bc7707764

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 c86bc7707764 759.8ms 529.5ms 33.3ms 3
PR pkg.pr.new eb845e3 1.049s 569.7ms 34.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: c86bc7707764; PR package: eb845e3. 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 577.5ms 551.4ms 1.05x 324.45 MiB 286.95 MiB 0.88x 1.74 GiB/s 1.83 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 371.4ms 375.0ms 0.99x 58.83 MiB 51.08 MiB 0.87x 2.71 GiB/s 2.68 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 558.2ms 1.80 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 530.0ms 1.90 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 368.0ms 2.74 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 340.7ms 2.96 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 31.7ms 4.1ms 7.70x 43.61 MiB 2.83 MiB 0.06x 0.05 MiB/s 0.38 MiB/s
claude session --offline --json 0.00 MiB 32.0ms 4.2ms 7.60x 43.48 MiB 2.83 MiB 0.07x 0.05 MiB/s 0.37 MiB/s
codex daily --offline --json 0.00 MiB 31.1ms 3.9ms 8.05x 43.61 MiB 2.83 MiB 0.06x 0.03 MiB/s 0.22 MiB/s
codex session --offline --json 0.00 MiB 31.0ms 4.0ms 7.75x 43.61 MiB 2.83 MiB 0.06x 0.03 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 545.7ms 507.5ms 1.08x 290.70 MiB 278.70 MiB 0.96x 1.85 GiB/s 1.98 GiB/s
codex --offline --json 1.01 GiB 362.0ms 331.8ms 1.09x 51.45 MiB 58.20 MiB 1.13x 2.78 GiB/s 3.03 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 14.22 KiB 14.21 KiB -0.00 KiB 1.00x
installed native package binary 3289.49 KiB 3289.49 KiB +0.00 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

ccusage performance comparison

PR SHA: 2bcb6b8f5648
Base SHA: c86bc7707764

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 c86bc7707764 367.6ms 423.1ms 34.3ms 3
PR pkg.pr.new 2bcb6b8 415.5ms 578.0ms 34.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: c86bc7707764; PR package: 2bcb6b8. 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 561.6ms 581.1ms 0.97x 291.20 MiB 285.58 MiB 0.98x 1.79 GiB/s 1.73 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 372.1ms 373.9ms 1.00x 59.58 MiB 50.95 MiB 0.86x 2.71 GiB/s 2.69 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 570.9ms 1.76 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 537.4ms 1.87 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 370.1ms 2.72 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 344.3ms 2.92 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 32.0ms 32.1ms 1.00x 43.48 MiB 43.61 MiB 1.00x 0.05 MiB/s 0.05 MiB/s
claude session --offline --json 0.00 MiB 32.1ms 31.2ms 1.03x 43.48 MiB - - 0.05 MiB/s 0.05 MiB/s
codex daily --offline --json 0.00 MiB 31.8ms 31.4ms 1.01x 43.48 MiB - - 0.03 MiB/s 0.03 MiB/s
codex session --offline --json 0.00 MiB 31.0ms 31.5ms 0.98x 43.48 MiB - - 0.03 MiB/s 0.03 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 562.5ms 561.0ms 1.00x - 287.08 MiB - 1.79 GiB/s 1.79 GiB/s
codex --offline --json 1.01 GiB 367.3ms 361.8ms 1.02x 59.45 MiB 61.83 MiB 1.04x 2.74 GiB/s 2.78 GiB/s

Artifact size

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

ccusage performance comparison

PR SHA: 2bcb6b8f5648
Base SHA: c86bc7707764

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 c86bc7707764 631.8ms 754.2ms 34.6ms 3
PR pkg.pr.new 2bcb6b8 668.8ms 657.0ms 35.3ms 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: c86bc7707764; PR package: 2bcb6b8. 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 574.1ms 576.6ms 1.00x 302.58 MiB 304.08 MiB 1.00x 1.75 GiB/s 1.75 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 369.5ms 374.5ms 0.99x 59.45 MiB 52.20 MiB 0.88x 2.72 GiB/s 2.69 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 563.1ms 1.79 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 527.9ms 1.91 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 370.6ms 2.72 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 340.0ms 2.96 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 31.3ms 4.2ms 7.50x 43.61 MiB 2.83 MiB 0.06x 0.05 MiB/s 0.37 MiB/s
claude session --offline --json 0.00 MiB 32.1ms 4.1ms 7.80x 43.61 MiB 2.83 MiB 0.06x 0.05 MiB/s 0.38 MiB/s
codex daily --offline --json 0.00 MiB 31.5ms 3.9ms 8.06x 43.48 MiB 2.83 MiB 0.07x 0.03 MiB/s 0.22 MiB/s
codex session --offline --json 0.00 MiB 31.4ms 4.0ms 7.89x 43.48 MiB 2.83 MiB 0.07x 0.03 MiB/s 0.22 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 560.8ms 522.5ms 1.07x 303.70 MiB 289.95 MiB 0.95x 1.80 GiB/s 1.93 GiB/s
codex --offline --json 1.01 GiB 365.2ms 333.1ms 1.10x 51.20 MiB 51.20 MiB 1.00x 2.76 GiB/s 3.02 GiB/s

Artifact size

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

Restore GEMINI_DATA_DIR with a panic-safe guard in Gemini tests so the environment is not leaked when a test panics.

Refresh Claude dedupe indexes when a parent usage entry replaces a sidechain replay with a different request id, and cover the replacement path so later exact duplicates continue to dedupe.
@ryoppippi
Copy link
Copy Markdown
Owner Author

@coderabbitai I addressed the remaining actionable findings: Gemini tests now restore GEMINI_DATA_DIR with a panic-safe guard, and Claude dedupe replacement refreshes indexes with a regression test. Please review the latest push.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

@ryoppippi: On it — I'll review the latest push covering the panic-safe GEMINI_DATA_DIR restore guard and the Claude dedupe index-refresh regression test now.

✅ Actions performed

Review triggered.

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.

@github-actions
Copy link
Copy Markdown

ccusage performance comparison

PR SHA: c45ce85eb469
Base SHA: c86bc7707764

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 c86bc7707764 373.1ms 422.4ms 34.7ms 3
PR pkg.pr.new c45ce85 485.5ms 602.1ms 34.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: c86bc7707764; PR package: c45ce85. 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 586.2ms 558.6ms 1.05x 273.95 MiB 296.83 MiB 1.08x 1.72 GiB/s 1.80 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 373.4ms 372.4ms 1.00x 58.95 MiB 68.58 MiB 1.16x 2.70 GiB/s 2.70 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 564.2ms 1.78 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 533.0ms 1.89 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 362.8ms 2.77 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 340.4ms 2.96 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 31.8ms 31.6ms 1.01x 43.73 MiB 43.48 MiB 0.99x 0.05 MiB/s 0.05 MiB/s
claude session --offline --json 0.00 MiB 31.7ms 31.5ms 1.01x 43.61 MiB 43.61 MiB 1.00x 0.05 MiB/s 0.05 MiB/s
codex daily --offline --json 0.00 MiB 31.0ms 31.7ms 0.98x 43.61 MiB 43.61 MiB 1.00x 0.03 MiB/s 0.03 MiB/s
codex session --offline --json 0.00 MiB 31.4ms 31.0ms 1.01x 43.73 MiB 43.73 MiB 1.00x 0.03 MiB/s 0.03 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 554.6ms 557.7ms 0.99x 294.08 MiB 297.83 MiB 1.01x 1.82 GiB/s 1.81 GiB/s
codex --offline --json 1.01 GiB 361.6ms 358.6ms 1.01x 51.33 MiB 63.08 MiB 1.23x 2.78 GiB/s 2.81 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 14.22 KiB 14.21 KiB -0.00 KiB 1.00x
installed native package binary 3289.49 KiB 3289.49 KiB +0.00 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

ccusage performance comparison

PR SHA: c45ce85eb469
Base SHA: c86bc7707764

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 c86bc7707764 514.4ms 540.8ms 36.0ms 3
PR pkg.pr.new c45ce85 897.7ms 721.2ms 36.0ms 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: c86bc7707764; PR package: c45ce85. 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 565.3ms 583.6ms 0.97x 306.08 MiB 289.70 MiB 0.95x 1.78 GiB/s 1.73 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 375.9ms 377.3ms 1.00x 65.70 MiB 57.33 MiB 0.87x 2.68 GiB/s 2.67 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 554.7ms 1.81 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 534.9ms 1.88 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 372.7ms 2.70 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 350.3ms 2.87 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 33.2ms 4.5ms 7.34x 43.61 MiB 2.95 MiB 0.07x 0.05 MiB/s 0.34 MiB/s
claude session --offline --json 0.00 MiB 33.3ms 4.6ms 7.23x - 2.83 MiB - 0.05 MiB/s 0.34 MiB/s
codex daily --offline --json 0.00 MiB 33.6ms 4.2ms 8.06x - 2.83 MiB - 0.03 MiB/s 0.21 MiB/s
codex session --offline --json 0.00 MiB 33.0ms 4.3ms 7.71x 43.73 MiB 2.83 MiB 0.06x 0.03 MiB/s 0.20 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 565.3ms 538.0ms 1.05x 322.08 MiB 289.95 MiB 0.90x 1.78 GiB/s 1.87 GiB/s
codex --offline --json 1.01 GiB 365.3ms 339.0ms 1.08x 61.20 MiB 51.33 MiB 0.84x 2.76 GiB/s 2.97 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 14.22 KiB 14.21 KiB -0.00 KiB 1.00x
installed native package binary 3289.49 KiB 3289.49 KiB +0.00 KiB 1.00x

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

@ryoppippi ryoppippi merged commit 737092e into main May 25, 2026
40 checks passed
@ryoppippi ryoppippi deleted the codex/use-fs-fixture-macro branch May 25, 2026 20:47
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