Skip to content

perf: speed up CI and local builds - #1984

Merged
ryoppippi merged 12 commits into
mainfrom
perf-faster-builds
Oct 28, 2026
Merged

ryoppippi merged 12 commits into
mainfrom
perf-faster-builds

Conversation

@ryoppippi

@ryoppippi ryoppippi commented Oct 27, 2026 •

Copy link
Copy Markdown
Member

Summary

Speeds up CI and local Rust builds. Baseline CI critical path: preflight (~45s) → build-windows-x64 (~200–250s: rustup install 44s, cache extraction 36s, cargo 90s) → publish → e2e.

CI

  • Fetch only the LiteLLM pricing file. The litellm flake input was the whole 2.7 GB repository, unpacked on every Nix job (7–25s each). It is now a single-file URL pinned to a commit; update-litellm-lock.nu rewrites the commit and re-locks, and non-Nix cargo builds read locked.url.
  • Dev-profile dependency layer for tests, clippy and hawk. ccusage-tests ran in the release profile and recompiled dev-dependencies and test-snapshots variants every run (~50s); hawk compiled the workspace uncached (~25s). New nix/test-artifacts.nix; main's test job roots both layers on the sticky disk.
  • Skip crane's cargo check pass in the static Linux and darwin-x64 deps layers (~30s whenever deps change).
  • Build/test no longer wait on preflight (~45s off the critical path). ci-gate still requires it, and the pkg.pr.new publish now depends on it so a leaked secret is never published.
  • Perf comment: benchmark against the nearest base commit with a preview package. Pricing snapshot commits are pushed with GITHUB_TOKEN, trigger no CI and never get a pkg.pr.new package, so a PR based on one made both perf jobs wait out the full 5-minute timeout (seen on this PR's first green run: 332s vs ~45s). The job now walks back over pricing-only commits to the nearest packaged one.

Local (dev shell)

  • lld on macOS (like mold on Linux): ~7–10% faster leaf/mid-depth incremental test rebuilds.
  • sccache shares dependencies, C build scripts included, across worktrees: fresh-worktree cargo test --workspace --no-run ~60s → ~45s wall (CPU 315s → 200s). No change for incremental rebuilds. Set RUSTC_WRAPPER (even empty) to opt out.
  • Fix: the copilot CLI snapshot test read host opencode data from XDG_DATA_HOME.

Risks / to verify on this PR's CI

  • A Windows Dev Drive was tried and dropped: Blacksmith's Windows image has neither Hyper-V (New-VHD) nor Defender, so neither a Dev Drive nor Defender exclusions apply there.
  • Native artifact uploads no longer wait for gitleaks (only the pkg.pr.new publish does); they are run-scoped Actions artifacts built from the PR's own public source.
  • First runs are cold (new Windows cache paths, new Nix layers), so timings should be judged on a re-run and after main warms the sticky disk.
  • Tests now run in the dev profile (overflow checks on). Nothing in the workspace uses debug_assertions.

Test plan

  • nix fmt, nix flake check --no-build
  • nix build .#ccusage-tests plus clippy and hawk checks, nix build .#ccusage on aarch64-darwin
  • cargo test --workspace in the dev shell (1081 passed, with lld + sccache)
  • fetch-litellm-pricing cargo build downloads from the locked URL
  • Test deps layer is reused: the ccusage-tests build compiles only the 28 workspace crates
  • Reviewed by Codex (gpt-6-astra): no critical findings; follow-ups applied
  • CI timings compared against recent runs

The unified report also scans opencode under XDG_DATA_HOME, so a developer's real opencode database leaked into the snapshot. Point it at an empty fixture directory like the other home directories.
Every Nix CI job unpacked the whole 2.7 GB BerriAI/litellm repository (7-25s per job), and pricing bumps re-lock it every few commits. The input is now a single-file URL pinned to a commit; update-litellm-lock.nu rewrites the commit in that URL before re-locking, and non-Nix cargo builds read the locked URL directly.
…y layer

The test derivation ran cargo test in the release profile on top of the release layers, which hold neither dev-dependencies nor the test-snapshots feature variants, so ~50s of dependencies recompiled on every run; hawk compiled the whole workspace uncached (~25s). A dev-profile deps-only layer now serves tests and clippy, hawk gets its own layer, and main's test job roots both on the sticky disk.
buildDepsOnly runs cargo check before cargo build, but only the host layer's check artifacts are used (by clippy and hawk). The static Linux and darwin-x64 layers only need the build output, which saves ~30s whenever dependencies change.
preflight (~45s) sat ahead of the slowest build on the critical path. ci-gate still requires it, and the pkg.pr.new publish now waits for it so a leaked secret is never published.
The rustup install (44s) and Cargo cache extraction (36s) were dominated by Defender and NTFS small-file costs. CARGO_HOME, RUSTUP_HOME and the target directory now live on a ReFS Dev Drive. The cache paths change, so the first run after merge starts cold.
lld links the test binaries an edit relinks faster than the Nix cctools ld64 (about 7-10% on leaf and mid-depth rebuilds). sccache shares compiled dependencies, C build scripts included, across worktrees: a fresh worktree's cargo test --no-run went from ~60s to ~45s wall (CPU 315s to 200s) with a warm cache. Set RUSTC_WRAPPER, even empty, to opt out.
The build command already compiles the test binaries; crane's check phase only added another cargo test --no-run for the ccusage bin.
setup-dev-drive needs the Hyper-V VHD cmdlets, which the release workflow's windows-11-arm runner is not known to provide, so arm64 falls back to the default Cargo and target locations.
@coderabbitai

coderabbitai Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Caution

Review failed

The pull request is closed.

Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@cloudflare-workers-and-pages

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

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

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

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

Branch Preview URL
Oct 27 2026, 07:46 PM

…Drive

Blacksmith's Windows image lacks the Hyper-V cmdlets setup-dev-drive needs (New-VHD), so the Dev Drive step failed. Defender path exclusions for the Cargo home, rustup home and workspace target the same small-file scan cost without Hyper-V, and the step is a no-op where Defender is absent.
@pkg-pr-new

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

Copy link
Copy Markdown

Open in StackBlitz

ccusage

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

@ccusage/ccusage-darwin-arm64

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

@ccusage/ccusage-darwin-x64

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

@ccusage/ccusage-linux-arm64

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

@ccusage/ccusage-linux-x64

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

@ccusage/ccusage-win32-x64

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

commit: 23c2fc2

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: 0868ffa4f178
Base SHA: 0c76c3e72b3a

Performance comparison skipped.

Base package URL was not ready before 300.000s. Fixture performance comparison requires a base package when --base-dir is not provided.

Base package: 0c76c3e72b3a

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: 0868ffa4f178
Base SHA: 0c76c3e72b3a

Performance comparison skipped.

Base package URL was not ready before 300.000s. Fixture performance comparison requires a base package when --base-dir is not provided.

Base package: 0c76c3e72b3a

Pricing snapshot commits are pushed to main with GITHUB_TOKEN, so they trigger no CI and never get a pkg.pr.new package. A PR based on one made both perf comment jobs wait out the full 5-minute package timeout and then skip the base comparison. Walk back over pricing-only commits to the nearest one with a package; any other commit without one keeps the old wait.
Blacksmith's Windows image has no Defender (Add-MpPreference fails with 'Invalid class'), so the step only cost ~7s; the slow cache extraction is not a Defender scan cost there.
@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: 23c2fc28066d
Base SHA: f1b50e642fd2

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

Package runtime diagnostics

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

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

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 452.0ms 2.23 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 432.4ms 2.33 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 171.2ms 5.88 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 143.4ms 7.02 GiB/s 1

Committed fixture performance

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

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

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude daily --offline --json 0.00 MiB 53.0ms 15.6ms 3.41x 56.00 MiB 23.22 MiB 0.41x 0.03 MiB/s 0.10 MiB/s
claude session --offline --json 0.00 MiB 49.7ms 15.2ms 3.27x 56.00 MiB 23.22 MiB 0.41x 0.03 MiB/s 0.10 MiB/s
codex daily --offline --json 0.00 MiB 43.4ms 15.7ms 2.77x 56.00 MiB 25.22 MiB 0.45x 0.02 MiB/s 0.05 MiB/s
codex session --offline --json 0.00 MiB 44.6ms 15.5ms 2.88x 56.00 MiB 25.21 MiB 0.45x 0.02 MiB/s 0.06 MiB/s

Large real-world-shaped fixture performance

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

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

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude --offline --json 1.01 GiB 435.0ms 436.3ms 1.00x 925.36 MiB 951.35 MiB 1.03x 2.31 GiB/s 2.31 GiB/s
codex --offline --json 1.01 GiB 174.7ms 146.2ms 1.19x 487.43 MiB 523.43 MiB 1.07x 5.76 GiB/s 6.88 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 24.02 KiB 24.05 KiB +0.02 KiB 1.00x
installed native package binary 4886.47 KiB 4886.47 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
Contributor

ccusage performance comparison

PR SHA: 262596707ad0
Base SHA: f1b50e642fd2

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

Package runtime diagnostics

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

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

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 426.6ms 2.36 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 406.6ms 2.48 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 174.7ms 5.76 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 140.8ms 7.15 GiB/s 1

Committed fixture performance

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

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

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude daily --offline --json 0.00 MiB 60.1ms 21.0ms 2.86x 56.00 MiB 23.22 MiB 0.41x 0.03 MiB/s 0.07 MiB/s
claude session --offline --json 0.00 MiB 48.4ms 15.9ms 3.04x 56.00 MiB 23.22 MiB 0.41x 0.03 MiB/s 0.10 MiB/s
codex daily --offline --json 0.00 MiB 48.9ms 18.2ms 2.69x 56.00 MiB 25.21 MiB 0.45x 0.02 MiB/s 0.05 MiB/s
codex session --offline --json 0.00 MiB 47.2ms 16.3ms 2.89x 56.00 MiB 25.21 MiB 0.45x 0.02 MiB/s 0.05 MiB/s

Large real-world-shaped fixture performance

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

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

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude --offline --json 1.01 GiB 428.5ms 414.0ms 1.03x 949.35 MiB 943.35 MiB 0.99x 2.35 GiB/s 2.43 GiB/s
codex --offline --json 1.01 GiB 185.3ms 145.9ms 1.27x 493.43 MiB 511.45 MiB 1.04x 5.43 GiB/s 6.90 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 24.02 KiB 24.05 KiB +0.02 KiB 1.00x
installed native package binary 4886.47 KiB 4886.47 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
Contributor

ccusage performance comparison

PR SHA: 262596707ad0
Base SHA: f1b50e642fd2

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

Package runtime diagnostics

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

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

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 589.2ms 1.71 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 476.7ms 2.11 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 194.5ms 5.18 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 160.4ms 6.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 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 66.2ms 62.5ms 1.06x 55.75 MiB 55.50 MiB 1.00x 0.02 MiB/s 0.02 MiB/s
claude session --offline --json 0.00 MiB 57.6ms 65.6ms 0.88x 56.00 MiB 56.25 MiB 1.00x 0.03 MiB/s 0.02 MiB/s
codex daily --offline --json 0.00 MiB 54.8ms 52.9ms 1.04x 56.00 MiB 56.00 MiB 1.00x 0.02 MiB/s 0.02 MiB/s
codex session --offline --json 0.00 MiB 55.5ms 51.9ms 1.07x 56.00 MiB 55.50 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, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude --offline --json 1.01 GiB 543.6ms 528.7ms 1.03x 931.34 MiB 935.34 MiB 1.00x 1.85 GiB/s 1.90 GiB/s
codex --offline --json 1.01 GiB 241.1ms 247.4ms 0.97x 505.43 MiB 469.43 MiB 0.93x 4.18 GiB/s 4.07 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 24.02 KiB 24.05 KiB +0.02 KiB 1.00x
installed native package binary 4886.47 KiB 4886.47 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
Contributor

ccusage performance comparison

PR SHA: 23c2fc28066d
Base SHA: f1b50e642fd2

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

Package runtime diagnostics

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

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

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 501.1ms 2.01 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 467.6ms 2.15 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 213.4ms 4.72 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 161.6ms 6.23 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 61.6ms 53.3ms 1.15x 56.00 MiB 56.00 MiB 1.00x 0.03 MiB/s 0.03 MiB/s
claude session --offline --json 0.00 MiB 47.6ms 53.9ms 0.88x 56.00 MiB 56.00 MiB 1.00x 0.03 MiB/s 0.03 MiB/s
codex daily --offline --json 0.00 MiB 49.8ms 50.2ms 0.99x 55.75 MiB 55.75 MiB 1.00x 0.02 MiB/s 0.02 MiB/s
codex session --offline --json 0.00 MiB 45.9ms 47.5ms 0.97x 55.75 MiB 56.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, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude --offline --json 1.01 GiB 468.2ms 474.4ms 0.99x 919.34 MiB 913.34 MiB 0.99x 2.15 GiB/s 2.12 GiB/s
codex --offline --json 1.01 GiB 215.1ms 206.0ms 1.04x 485.43 MiB 491.43 MiB 1.01x 4.68 GiB/s 4.89 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 24.02 KiB 24.05 KiB +0.02 KiB 1.00x
installed native package binary 4886.47 KiB 4886.47 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 marked this pull request as ready for review October 28, 2026 01:39
@ryoppippi
ryoppippi merged commit 4f1f470 into main Oct 28, 2026
47 checks passed
@ryoppippi
ryoppippi deleted the perf-faster-builds branch October 28, 2026 01:39

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

Important

The perf baseline walk-back misses one pricing-owned path, so half the pricing commits still hit the 5-minute wait this PR sets out to fix.

Reviewed changes

  • Slimmed the litellm flake input to a single-file URL and updated build.rs, dev-shell, packaging, docs, and the lock-update script to match.
  • Added a dev-profile nix/test-artifacts.nix dependency layer shared by tests, clippy, and hawk, and skipped crane's redundant check pass in cross/static dep layers.
  • Unblocked test and build-native-packages from preflight while keeping preflight required in ci-gate and the pkg.pr.new publish job.
  • Added a perf-comment step that walks back over pricing-only commits to the nearest packaged base SHA.
  • Enabled lld on macOS and sccache sharing in the dev shell, and isolated the copilot CLI snapshot from host XDG_DATA_HOME.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using muse-spark-1.3-contributor (free via Pullfrog for OSS) | 𝕏

Comment thread .github/workflows/ci.yaml
break
fi
if git diff --name-only "$sha^" "$sha" \
| grep -qvE '^(flake\.(lock|nix)|rust/crates/ccusage-pricing-snapshots/src/[^/]+\.json)$'; then

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.

The pricing-only allowlist omits rust/adapters/codex/src/codex-auto-review-fallbacks.json, which the models.dev leg also commits. A base commit touching only that file plus the allowlisted paths stops the walk and keeps an unpackaged base.

Suggested change
| grep -qvE '^(flake\.(lock|nix)|rust/crates/ccusage-pricing-snapshots/src/[^/]+\.json)$'; then
| grep -qvE '^(flake\.(lock|nix)|rust/crates/ccusage-pricing-snapshots/src/[^/]+\.json|rust/adapters/codex/src/codex-auto-review-fallbacks\.json)$'; then

| first
)
open --raw flake.nix
| str replace --regex 'BerriAI/litellm/[0-9a-f]{40}/' $"BerriAI/litellm/($rev)/"

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.

If git ls-remote fails or prints nothing, $rev is empty and the rewrite corrupts flake.nix before nix flake update runs. Validate a 40-hex rev first.

Buster210 added a commit to Buster210/ccusage that referenced this pull request Nov 6, 2026
Upstream tip: 30b653f (2026-11-06,
chore(pricing): update models.dev snapshot)
Previous fork base: c76874e (the upstream commit this fork was synced to)

Synced 128 upstream commits on top of c76874e: 70 automated pricing
snapshot refreshes and the following meaningful ones:

  b24e7a7 docs: remove LINE MAN sponsor logo (ccusage#1910)
  a93d2fe chore: release v20.0.38 (ccusage#1938)
  d91f296 docs: add ccx to community projects (ccusage#1943)
  aa7c675 chore: release v20.0.39 (ccusage#1944)
  39fefa2 fix(cli): accept --start-of-week on top-level weekly (ccusage#1945)
  600b3c9 chore: release v20.0.40 (ccusage#1946)
  baeb991 fix(antigravity): map model ID 1402 to claude-opus-5-5 (ccusage#1948)
  06347d3 chore: release v20.0.41 (ccusage#1949)
  5649632 test(hermes): derive DeepSeek provider pricing from embedded snapshot (ccusage#1951)
  d0847af chore(deps): update node.js to >=24.22.1 (ccusage#1950)
  91dfe85 chore(deps): update pullfrog/pullfrog action to v0.1.100 (ccusage#1953)
  f335280 chore: release v20.0.42 (ccusage#1952)
  b86527d chore(deps): update rust crate rustls-webpki to 0.103.16 (ccusage#1954)
  5c85ca2 chore(deps): update pullfrog/pullfrog action to v0.1.101 (ccusage#1958)
  f268798 fix(cli): apply source-specific config in unified reports (ccusage#1959)
  37a51da chore: release v20.0.43 (ccusage#1955)
  e302366 chore(deps): update github/codeql-action action to v4.39.1 (ccusage#1960)
  7af0db6 chore(deps): update pnpm to v12.15.0 (ccusage#1961)
  730c336 chore(deps): update rust crate ureq to 3.5.0 (ccusage#1964)
  bd1a21a fix(release): publish platform packages before the wrapper (ccusage#1965)
  ca33842 chore: release v20.0.44 (ccusage#1962)
  b2c8f8b chore: remove unused npm registry gate test (ccusage#1966)
  19e71d0 chore(deps): update songmu/tagpr action to v1.21.4 (ccusage#1969)
  2a84385 fix(codex): count repeated first-response snapshots once (ccusage#1971)
  60227f2 chore(deps): update rust crate smallvec to 1.16.4 (ccusage#1973)
  3e31edd chore(deps): update hustcer/setup-nu action to v3.29 (ccusage#1974)
  d93c260 feat(pricing): add gpt-6.1-terra fast/flex multipliers (ccusage#1975)
  154e13b chore: release v20.0.45 (ccusage#1967)
  f1b50e6 chore(deps): update pullfrog/pullfrog action to v0.1.102 (ccusage#1980)
  4f1f470 perf: speed up CI and local builds (ccusage#1984)
  0bd3d19 refactor(rust): move binary-only report helpers out of ccusage-core (ccusage#1985)
  65c5837 fix(antigravity): skip unreadable conversation databases (ccusage#1992)
  6372cac chore(deps): update dependency vitepress to v2.0.0-alpha.21 (ccusage#1994)
  9a42066 chore(deps): update node.js to >=24.22.2 (ccusage#1995)
  87fa788 chore(deps): update pnpm to v12.16.0 (ccusage#1996)
  8cb2532 fix(codex): price recorded Ultrafast requests at Ultrafast rates (ccusage#1989)
  128d6a0 chore(deps): update pnpm to v12.16.1 (ccusage#1997)
  5aa9d3f chore: release v20.0.46 (ccusage#1982)
  4712880 chore(deps): update rust crate unicode-width to 0.2.3 (ccusage#1998)
  3d59863 chore(deps): update node.js to v26 (ccusage#1999)
  96e98c6 chore(deps): update dependency @types/node to v26.6.6 (ccusage#2002)
  60fac54 chore(deps): update pullfrog/pullfrog action to v0.1.103 (ccusage#2003)
  de83d19 fix(config): let space-form command sections override generic report sections (ccusage#2006)
  72b8ad4 fix(all): count OpenCode Claude Agent turns once in unified reports (ccusage#2007)
  7db7a30 test(pricing): stop the alias-precedence test depending on the LiteLLM snapshot (ccusage#2009)
  e7a7ee4 fix(all): keep sessions last active on the --until day (ccusage#2008)
  4a3da73 chore: release v20.0.47 (ccusage#2001)
  8e56c11 chore(deps): update pullfrog/pullfrog action to v0.1.104 (ccusage#2010)
  e2eddf7 chore(deps): update pullfrog/pullfrog action to v0.1.107 (ccusage#2012)
  e3d2dcb chore(deps): update pullfrog/pullfrog action to v0.1.108 (ccusage#2014)
  8995f3b chore: release v20.0.48 (ccusage#2011)
  3977fd0 chore(deps): update pullfrog/pullfrog action to v0.1.110 (ccusage#2017)
  546ae51 fix(nix): make `nix flake show` work again on nixpkgs 26.11 (ccusage#2019)
  1b5e8cc chore(deps): update kesin11/actions-timeline action to v3.2.1 (ccusage#1983)
  23c5d62 chore(deps): update rust crate jiff to 0.2.39 (ccusage#2024)
  7b7cec0 chore(deps): update rust crate ureq to 3.5.1 (ccusage#2025)
  a1e4a03 chore(deps): update pullfrog/pullfrog action to v0.1.111 (ccusage#2028)
  e84d142 chore(deps): update pnpm to v12.17.0 (ccusage#2029)

Fork wins kept: the SQLite on-disk cache with its per-namespace ledger,
--live-only and clear-cache, the pi adapter with replay suppression and
per-path namespaces, the OpenCode V2 loader (now wrapped as LinkedEntry),
the FxHash/Cow hot paths, parallel per-file loads with their single_thread
seam, the table renderer, the fork CI and tag-only release workflow, and the
pricing freshness, refresh and offline precompute paths.

Hand-resolved conflicts:

  rust/adapters/claude/src/lib.rs: upstream's DedupedEntries/pruned dedupe
    lands beside the fork's collapse_replays and requestless replay rules;
    load_daily_summaries routes through load_daily_summaries_with_detection.
  rust/adapters/opencode/{parser,loader}.rs: upstream's V2 session_message
    parsing is wrapped as the fork's LinkedEntry, and the native Claude
    session link is read from the payload so it survives a cache hit.
  rust/adapters/antigravity/src/loader.rs: upstream's rewrite is taken,
    keeping the fork's per-database outcome reporting and file order.
  rust/crates/ccusage-core/src/pricing.rs: the fork's OnceLock embedded
    loader sits beside upstream's models.dev fallback and alias resolution.
  rust/crates/ccusage/src/main.rs: upstream dispatch plus the fork's
    ClearCache command.
  rust/crates/ccusage-core/src/cache.rs: the ledger is now generic over a
    LedgerPayload trait, so it covers plain entries and OpenCode's
    entry-plus-link pairs alike.
  rust/Cargo.toml: the fork's exact `=` pins stay; jiff 0.2.39,
    smallvec 1.16.4, ureq 3.5.1, unicode-width 0.2.3, rustls-webpki
    0.103.16.
  .github/workflows/{ci,release}.yaml: the fork's design is kept.
  packages/ccusage-*/package.json (6 files) and
  rust/adapters/claude/src/daily.rs: stay deleted.
  rust/crates/ccusage-core/src/{home,last_window}.rs: upstream's crate
    split moved them to ccusage-cli and ccusage-report, with their snapshots.
  apps/ccusage/config-schema.json: regenerated from the merged Rust source
    (32 numeric minimums `0.0` -> `0`, new pi description), plus three
    snapshots regenerated in the fork layout for the codex and qwen tests.

Fixes made while landing this sync, folded in so the merge stands green:

  fix(rust): decode cache blobs written before `data_session_id`. postcard
    encodes struct fields positionally, so a field added mid-struct made
    every blob the released 20.0.36 binary wrote undecodable. A failed
    decode is not merely slow: it drops the ledger rows of deleted source
    files, which no later run can rebuild. In an isolated fixture the
    released binary still reported 101,570,002 pi tokens after the source
    files were deleted; a warm build without the decoders reported 0.
    LegacyCachedEntry and LegacyLedgerEntry decode the old layout and
    reconstruct `data_session_id` as None; decode_exact requires the whole
    buffer, so a newer blob can no longer "decode" into an older struct as
    garbage. Four regression tests cover both layouts and the tail rule.
  fix(rust): warn once per table when a cached blob decodes as no known
    layout. The files table is rebuildable; the ledger table is not, so the
    warning says to save a copy before clear-cache.
  test(opencode): isolate the Claude-agent pairing test from the developer's
    real cache; it had been writing 'agent'/'plain' ledger rows into the
    opencode-db namespace.

Version: take upstream's 20.0.48 in package.json, apps/ccusage/package.json
and docs/package.json; the Rust workspace keeps version 0.0.0.

DO NOT push a v20.0.48 tag from this fork: release.yaml would publish fork
bytes under upstream identity.
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