Skip to content

perf(ci): speed up the check job and make native build cache observable - #1260

Merged
ryoppippi merged 3 commits into
mainfrom
ci/print-nix-build-logs
Jun 11, 2026
Merged

perf(ci): speed up the check job and make native build cache observable#1260
ryoppippi merged 3 commits into
mainfrom
ci/print-nix-build-logs

Conversation

@ryoppippi

@ryoppippi ryoppippi commented Jun 11, 2026

Copy link
Copy Markdown
Member

What

Three small CI changes, motivated by investigating why the native release builds and the check job felt slow.

1. perf(ci): drop the duplicate ccusage package build from nix flake check

The check job re-realizes the full optimized native ccusage package on every cache-cold run (~70s), even though:

  • ccusage-clippy already compiles the entire workspace with --all-targets (so any build break is still caught), and
  • the build-native-packages job already produces and verifies the actual release binary.

Removing the redundant checks.ccusage entry trims that duplicate release compile from nix flake check.

2. ci: print nix build logs in native package builds

Pass --print-build-logs to the Nix builds (ccusage-static, ccusage) so CI shows whether each build compiled the derivation or restored it from the sticky-disk store — making cache hits/misses observable.

3. docs(nix): explain why ccusage-static is separate from ccusage

Document the dev/native (ccusage) vs distribution (ccusage-static) split at the top of the static package definition.

Why / findings

While investigating, with --print-build-logs added:

  • Linux native build = a clean sticky-disk store hit (no compile, ~12s nix).
  • check job swings between ~2m (warm) and ~7–8m (cold): on cold runs its large (~7.7 GiB) per-job sticky disk gets evicted, so it re-vendors crates from crates.io + recompiles ccusage-deps + the package. Nix's caching itself is fine — the CI persistent store just doesn't retain the big closure reliably.

Follow-up (not in this PR)

The proper "Nix-way" fix for cold-cache check runs is a shared binary cache (attic / cachix) so any runner can fetch the deps/package outputs instead of recompiling them, independent of sticky-disk retention. Happy to do that separately if we want to provision a cache.


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


Summary by cubic

Speeds up the check job by removing a redundant native package build and makes Nix build cache behavior visible in CI. Also documents why ccusage-static is separate from ccusage.

  • Performance

    • Remove checks.ccusage from nix flake check to avoid a duplicate ~70s release compile on cold runners; rely on ccusage-clippy and the release job instead.
  • CI and Docs

    • Pass --print-build-logs to nix build .#ccusage and nix build .#ccusage-static to show compile vs store-restore.
    • Document the ccusage (native/dev) vs ccusage-static (musl, fully static, release) split in nix/static-package.nix.

Written for commit 68e78e9. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Chores
    • Updated build process to print detailed logs during Linux and macOS native package builds
    • Streamlined build verification configuration by removing a redundant check
    • Enhanced documentation for static package builds to clarify release pipeline behavior

Pass --print-build-logs to the Nix builds so CI shows whether each
native package build compiles the derivation or restores it from the
Blacksmith sticky-disk Nix store, making cache hits/misses observable.
The check job re-realizes the full optimized native ccusage package on
every cache-cold run (~70s), even though ccusage-clippy already compiles
the whole workspace with --all-targets and the build-native-packages job
produces and verifies the actual release binary. Removing the redundant
checks.ccusage entry trims that duplicate release compile from flake check.
Document the dev/native (ccusage) vs distribution (ccusage-static) split
at the top of the static package definition so the release matrix's use
of .#ccusage-static for Linux is self-explanatory.
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

GitHub Actions for Linux and macOS builds now emit detailed build logs via --print-build-logs. The flake's check suite removes a redundant full native build of ccusage, retaining only language and schema checks. Documentation clarifies why the release pipeline uses a static musl variant on Linux rather than the default glibc build.

Changes

Build infrastructure for logging and check optimization

Layer / File(s) Summary
CI build log printing
.github/actions/build-linux-native-package/action.yaml, .github/actions/build-macos-nix-native-package/action.yaml
Both Linux and macOS nix build commands now include --print-build-logs to emit build logs consistently across CI platforms.
Nix check configuration and architecture documentation
nix/checks.nix, nix/static-package.nix
Flake checks remove the full ccusage package build to avoid redundant compilation on cache-cold runners; header comments in static-package.nix explain the separation between the default glibc-dynamic build and the static musl variant used in releases.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Possibly related PRs

  • ccusage/ccusage#1249: Updates the Blacksmith CI migration with related nix build invocation changes in the Linux composite action.

Poem

🐰 Nix builds now speak their minds so clear,
With logs that echo far and near,
Checks grow lean, the waste cuts deep,
While static binaries our secrets keep. 🏗️

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the main changes: performance improvement to the CI check job and making native build cache behavior observable through added logging.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ 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 ci/print-nix-build-logs

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

@cloudflare-workers-and-pages

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 68e78e9 Commit Preview URL

Branch Preview URL
Jun 11 2026, 12:13 AM

@github-code-quality

Copy link
Copy Markdown

Code Coverage Overview

Languages: Rust

Rust / code-coverage/cargo-llvm-cov

The overall coverage remains at 77%, unchanged from the main branch.


Code Coverage is in Public Preview. Learn more and provide us with your feedback.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 4 files

Re-trigger cubic

@pkg-pr-new

pkg-pr-new Bot commented Jun 11, 2026

Copy link
Copy Markdown

Open in StackBlitz

ccusage

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

@ccusage/ccusage-darwin-arm64

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

@ccusage/ccusage-linux-arm64

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

@ccusage/ccusage-linux-x64

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

@ccusage/ccusage-win32-x64

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

commit: 68e78e9

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: 68e78e96fd83
Base SHA: da04f8b6e9d8

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 da04f8b6e9d8 716.6ms 734.4ms 48.0ms 3
PR pkg.pr.new 68e78e9 1.031s 1.198s 45.5ms 3

Cached bunx execution performance

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

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: da04f8b6e9d8; PR package: 68e78e9. 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 921.9ms 864.0ms 1.07x 726.75 MiB 726.00 MiB 1.00x 1.09 GiB/s 1.17 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 187.0ms 183.0ms 1.02x 87.50 MiB 87.50 MiB 1.00x 5.38 GiB/s 5.50 GiB/s

Package runtime diagnostics

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

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

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 902.6ms 1.12 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 886.9ms 1.14 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 169.9ms 5.93 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 129.4ms 7.78 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 40.1ms 37.8ms 1.06x 43.00 MiB 43.25 MiB 1.01x 0.04 MiB/s 0.04 MiB/s
claude session --offline --json 0.00 MiB 39.1ms 37.6ms 1.04x 43.00 MiB 43.00 MiB 1.00x 0.04 MiB/s 0.04 MiB/s
codex daily --offline --json 0.00 MiB 39.6ms 38.2ms 1.04x 43.00 MiB 43.00 MiB 1.00x 0.02 MiB/s 0.02 MiB/s
codex session --offline --json 0.00 MiB 37.8ms 38.3ms 0.99x 43.00 MiB 43.25 MiB 1.01x 0.02 MiB/s 0.02 MiB/s

Large real-world-shaped fixture performance

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

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

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude --offline --json 1.01 GiB 899.5ms 851.9ms 1.06x 726.75 MiB 725.50 MiB 1.00x 1.12 GiB/s 1.18 GiB/s
codex --offline --json 1.01 GiB 168.9ms 170.2ms 0.99x 89.75 MiB - - 5.96 GiB/s 5.91 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 17.32 KiB 17.33 KiB +0.00 KiB 1.00x
installed native package binary 3353.74 KiB 3353.74 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: 68e78e96fd83
Base SHA: da04f8b6e9d8

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 da04f8b6e9d8 778.2ms 728.8ms 56.0ms 3
PR pkg.pr.new 68e78e9 799.4ms 803.9ms 52.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: da04f8b6e9d8; PR package: 68e78e9. 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 898.5ms 931.4ms 0.96x 682.25 MiB 730.25 MiB 1.07x 1.12 GiB/s 1.08 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 201.2ms 208.1ms 0.97x 90.25 MiB 87.50 MiB 0.97x 5.00 GiB/s 4.84 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 939.7ms 1.07 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 995.0ms 1.01 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 179.4ms 5.61 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 139.8ms 7.20 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 47.1ms 6.5ms 7.25x 43.25 MiB 2.75 MiB 0.06x 0.03 MiB/s 0.24 MiB/s
claude session --offline --json 0.00 MiB 43.6ms 6.3ms 6.90x 43.25 MiB 2.50 MiB 0.06x 0.04 MiB/s 0.24 MiB/s
codex daily --offline --json 0.00 MiB 48.1ms 6.0ms 8.03x 43.25 MiB 2.50 MiB 0.06x 0.02 MiB/s 0.14 MiB/s
codex session --offline --json 0.00 MiB 48.5ms 6.4ms 7.62x 43.00 MiB 2.50 MiB 0.06x 0.02 MiB/s 0.13 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 947.1ms 877.6ms 1.08x 739.00 MiB 741.25 MiB 1.00x 1.06 GiB/s 1.15 GiB/s
codex --offline --json 1.01 GiB 170.8ms 137.3ms 1.24x 89.75 MiB 90.75 MiB 1.01x 5.89 GiB/s 7.33 GiB/s

Artifact size

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

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