fix(pricing): add Claude Opus 4.8 rates by ryoppippi · Pull Request #1182 · ccusage/ccusage · GitHub
Skip to content

fix(pricing): add Claude Opus 4.8 rates#1182

Merged
ryoppippi merged 3 commits into
mainfrom
codex/fix-opus-48-pricing
May 29, 2026
Merged

fix(pricing): add Claude Opus 4.8 rates#1182
ryoppippi merged 3 commits into
mainfrom
codex/fix-opus-48-pricing

Conversation

@ryoppippi

@ryoppippi ryoppippi commented May 29, 2026

Copy link
Copy Markdown
Member

Adds embedded Claude Opus 4.8 pricing so offline reports and pricing refresh failures use the current Opus 4.8 rates instead of falling back to deprecated Opus 4 pricing.

Also updates Claude fast-mode multipliers so Opus 4.8 uses the current 2x rate, while Opus 4.6 and 4.7 remain at 6x. Pricing-key fuzzy matching now allows date-suffixed aliases but avoids falling back across unknown numeric model versions.

Testing:

  • nix develop --command cargo test --manifest-path rust/Cargo.toml -p ccusage pricing::tests
  • nix develop --command pnpm run format
  • pre-push hook via nix develop --command git push -u origin codex/fix-opus-48-pricing

Summary by cubic

Embed Claude Opus 4.8 pricing and set the correct fast-mode rate so offline reports use current costs instead of falling back to deprecated Opus 4. Also tighten model-name matching with a named YYYYMMDD date-suffix rule to allow date aliases without crossing numeric versions.

  • New Features

    • Added embedded rates for claude-opus-4-8 (input 5e-6, output 25e-6; cache create 6.25e-6; cache read 0.5e-6) and a 1,000,000 token context limit.
    • Updated fast multiplier: claude-opus-4-8 = 2x; claude-opus-4-6 and claude-opus-4-7 remain 6x.
  • Bug Fixes

    • Offline and pricing-refresh failures no longer fall back from 4.8 to claude-opus-4.
    • Fuzzy matching accepts date-suffixed IDs (e.g., claude-opus-4.8-20260528) via a documented 8-digit YYYYMMDD rule, and blocks cross-version fallbacks (e.g., 4.8 or 4.70 do not match 4).

Written for commit 2688af0. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Added support for claude-opus-4-8 with configured fast multiplier and matching context limit.
  • Bug Fixes

    • Improved model-version matching to prevent incorrect pricing or configuration fallbacks between similar variants.
  • Tests

    • Extended unit tests and fixtures to validate new model handling and fuzzy-match regressions.

Review Change Stack

Embed Claude Opus 4.8 pricing for offline reports so usage does not fall back to the deprecated Claude Opus 4 rate when the runtime LiteLLM refresh is unavailable.

Use the current Anthropic fast mode rate for Opus 4.8, which is  input and  output per MTok, so the fast multiplier is 2x instead of the 6x multiplier used by Opus 4.6 and 4.7.

Tighten pricing-key fuzzy matching so date-suffixed model IDs can still resolve through their base key while unknown numeric model revisions such as claude-opus-4.8 or claude-opus-4.70 no longer match claude-opus-4.
@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown

@ryoppippi

Copy link
Copy Markdown
Member Author

@coderabbitai review

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented May 29, 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 Updated (UTC)
⚠️ Deployment skipped
View logs
ccusage-guide 2688af0 May 29 2026, 08:45 AM

@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown
✅ 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.

@ryoppippi

ryoppippi commented May 29, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai Please focus the review on the pricing resolution behavior: (1) Claude Opus 4.8 should use embedded offline pricing at $5/$25 per MTok with cache rates $6.25/$0.50 matching Anthropic pricing, (2) fast mode for Opus 4.8 should use $10/$50 per MTok, so a 2x multiplier, while Opus 4.6/4.7 stay at $30/$150 and 6x, and (3) fuzzy model matching should still resolve date-suffixed aliases like claude-opus-4-20250514 but must not fall back across unknown numeric model versions such as claude-opus-4.8 or claude-opus-4.70 to claude-opus-4.

@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find pricing-related Rust files
fd -e rs . rust/ | xargs grep -l "opus.4" 2>/dev/null

echo "=== Find pricing/model data files ==="
fd -e rs . rust/ | head -40

Length of output: 2296


🏁 Script executed:

#!/bin/bash
echo "=== Search for claude-opus-4-8 pricing entries ==="
rg -n "opus.4.8\|opus_4_8\|opus-4-8" --type rust -C3

echo ""
echo "=== Search for fast mode multiplier logic ==="
rg -n "fast.*mult\|mult.*fast\|fast_mode\|FastMode\|6x\|2x\|multiplier" --type rust -C3 | head -100

echo ""
echo "=== Search for fuzzy matching logic ==="
rg -n "fuzzy\|fallback\|date.suffix\|date_suffix\|match.*model\|model.*match" --type rust -C5 | head -100

Length of output: 630


🏁 Script executed:

#!/bin/bash
echo "=== Full pricing.rs ==="
cat rust/crates/ccusage/src/pricing.rs

echo ""
echo "=== Check for embedded JSON/TOML pricing data ==="
fd -e json -e toml -e yaml . rust/ | xargs grep -l "opus" 2>/dev/null | head -10

echo ""
echo "=== Check for any data files with opus pricing ==="
rg -rn "opus-4-8\|opus_4_8\|4\.8" rust/ -C2 | head -80

Length of output: 39789


🏁 Script executed:

#!/bin/bash
cat rust/crates/ccusage/src/fast-multiplier-overrides.json

Length of output: 298



@ryoppippi Here's the focused review on all three pricing resolution behaviors:


1. Claude Opus 4.8 embedded offline pricing ✅

In put_builtin_pricing (pricing.rs):

"claude-opus-4-8" → input: 5e-6, output: 25e-6, cache_create: 6.25e-6, cache_read: 0.5e-6
  • Rates match Anthropic's published $5/$25 per MTok with the correct 1.25× cache-write and 0.1× cache-read ratios.
  • cache_read_explicit: true ensures the cache-read rate is treated as authoritative.
  • Context limit of 1_000_000 is registered in the same for model in [...] loop that covers 4-6, 4-7, and 4-8.
  • Since load_embedded calls put_builtin_pricing after load_json_with_overrides, these builtin entries will win over any stale LiteLLM build-time data for these models.

2. Fast-mode multipliers ✅

fast-multiplier-overrides.json:

"normalized_prefix": {
  "claude-opus-4-6": 6.0,
  "claude-opus-4-7": 6.0,
  "claude-opus-4-8": 2.0
}
  • matches_model_suffix requires the byte immediately after the matched base to be - or end-of-string, so claude-opus-4-80 or similar won't accidentally inherit the 2.0 multiplier.
  • The normalized_prefix path (via multiplier_for) normalises . and @ separators before matching, so provider-prefixed variants like anthropic.claude-opus-4-8 also get 2.0 — covered by the test embedded_pricing_includes_claude_fast_multiplier_for_provider_models.
  • The fills_claude_fast_multiplier_when_litellm_pricing_omits_it test verifies that claude-opus-4.8-20260528 from LiteLLM (without a provider_specific_entry.fast field) also receives 2.0, while claude-opus-4-70 gets 1.0.

3. Fuzzy model-key matching ✅

suffix_starts_with_numeric_model_version is the key guard:

  • A suffix like .8 or -8 after a digit-terminated key is treated as a new numeric version → blocks the match.
  • An 8-digit suffix (e.g. -20260528) is treated as a date → allows the match.

Concrete cases confirmed by tests:

Model queried Map contains Expected Result
claude-opus-4.8-20260528 claude-opus-4-8 resolve ✅ (normalization + 8-digit date exemption)
claude-opus-4.8-20260528 only claude-opus-4 None ✅ (fuzzy_match_does_not_fall_back_across_numeric_model_versions)
claude-opus-4.70 claude-opus-4 + claude-opus-4-7 None ✅ (fuzzy_match_requires_model_key_boundaries)
claude-opus-4-20250514 claude-opus-4 resolve ✅ (date suffix exemption)

Minor observation

claude-opus-4-5 in put_builtin_pricing has its fast_multiplier hardcoded to 1.0 rather than delegating to fast_multiplier_overrides.multiplier_for(...). This is consistent with the current overrides file (no entry for 4-5), but unlike 4-6/4-7/4-8, it would silently ignore a future override without a code change. Not a blocker, just worth noting for consistency.

Everything else looks correct. All three requirements are properly implemented and well-covered by tests.

@ryoppippi

ryoppippi commented May 29, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai Correction to my previous focus note: please specifically verify that standard Claude Opus 4.8 embedded/offline pricing is $5/$25 per MTok, cache write/read rates are $6.25/$0.50 per MTok, fast mode for Opus 4.8 is $10/$50 per MTok with a 2x multiplier, and Opus 4.6/4.7 fast mode remains $30/$150 per MTok with a 6x multiplier. Also verify that fuzzy matching allows date-suffixed aliases but does not fall back across unknown numeric model versions like claude-opus-4.8 or claude-opus-4.70 to claude-opus-4.

@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== Opus 4.8 and nearby entries in put_builtin_pricing ==="
rg -n "opus-4-[5678]|opus_4_[5678]|5e-6|25e-6|6\.25e-6|0\.5e-6|cache_read\|cache_create" --type rust -C4 rust/ | head -120

echo ""
echo "=== fast-multiplier-overrides.json ==="
cat rust/crates/ccusage/src/fast-multiplier-overrides.json

echo ""
echo "=== Relevant tests for pricing values ==="
rg -n "opus.4.8\|4\.8.*mult\|mult.*4\.8\|fast.*4\.[678]\|4\.[678].*fast\|10e-6\|50e-6\|30e-6\|150e-6" --type rust -C5 rust/ | head -120

echo ""
echo "=== Context limit entries for opus 4.8 ==="
rg -n "1_000_000\|context_limit\|opus-4-8" --type rust -C3 rust/ | head -60

echo ""
echo "=== Fuzzy match tests ==="
rg -n "fuzzy_match\|suffix_starts_with_numeric\|date.suffix\|20250514\|20260528\|4\.70\|4\.8.*opus" --type rust -C5 rust/ | head -100

Length of output: 13344


🏁 Script executed:

#!/bin/bash
echo "=== Lines 260-400 of pricing.rs ==="
sed -n '260,420p' rust/crates/ccusage/src/pricing.rs

echo ""
echo "=== Fuzzy match / suffix_starts_with_numeric function ==="
rg -n "suffix_starts_with_numeric\|fuzzy_key\|fuzzy_match\|find_key\|find_pricing" --type rust -C6 rust/ | head -150

echo ""
echo "=== Context window / token limit setup ==="
rg -n "context_window\|token_limit\|max_tokens\|1_000_000\|200_000" --type rust -C4 rust/ | head -80

echo ""
echo "=== Tests related to Opus 4.8 pricing or fuzzy ==="
rg -n "4[-_\.]8\|opus.*4.*8\|20260528\|20250514\|4\.70\|numeric_model" --type rust -C6 rust/ | head -150

Length of output: 6395


🏁 Script executed:

#!/bin/bash
echo "=== Full pricing.rs line count and last section ==="
wc -l rust/crates/ccusage/src/pricing.rs
sed -n '420,700p' rust/crates/ccusage/src/pricing.rs

echo ""
echo "=== context_limit / max_context entries ==="
grep -n "context\|limit\|1000000\|1_000_000" rust/crates/ccusage/src/pricing.rs | head -40

echo ""
echo "=== All test names in pricing.rs ==="
grep -n "fn \|#\[test\]" rust/crates/ccusage/src/pricing.rs | head -80

Length of output: 15213



@ryoppippi Here is the precise numerical verification against the source:


1. Claude Opus 4.8 embedded/offline pricing ✅

From pricing.rs (lines 262–278):

Rate Code value Per MTok
Input 5e-6 $5
Output 25e-6 $25
Cache write 6.25e-6 $6.25
Cache read 0.5e-6 $0.50

cache_read_explicit: true marks the cache-read rate as authoritative rather than derived.


2. Fast-mode multipliers ✅

From fast-multiplier-overrides.json:

"claude-opus-4-6": 6.0,
"claude-opus-4-7": 6.0,
"claude-opus-4-8": 2.0

And pricing.rs reads these via fast_multiplier_overrides.multiplier_for("claude-opus-4-8") (etc.) with .unwrap_or(1.0), so the values are correctly injected at build time.

Model Multiplier Fast input Fast output
Opus 4.8 $10/MTok $50/MTok
Opus 4.6 $30/MTok $150/MTok
Opus 4.7 $30/MTok $150/MTok

3. Context limit ✅

claude-opus-4-8 is included in the for model in ["claude-opus-4-8", "claude-opus-4-7", ...] loop that sets context_limits = 1_000_000. This is directly asserted by the test at line 899:

assert_eq!(pricing.context_limit("claude-opus-4.8"), Some(1_000_000));

4. Fuzzy model matching ✅

suffix_starts_with_numeric_model_version is the guard:

  • A suffix of -8 or .8 after a digit-terminated key → blocks the match (so claude-opus-4.8 does not fall back to claude-opus-4)
  • A suffix of .70blocks (so claude-opus-4.70 does not fall back to claude-opus-4)
  • An 8-digit suffix like -20260528 or -20250514allowed (date-suffix exemption)

Tests confirming this:

  • embedded_pricing_resolves_opus_48_dot_model_names (line 891)
  • fuzzy_match_requires_model_key_boundaries (line 927)
  • fuzzy_match_does_not_fall_back_across_numeric_model_versions (line 964)
  • fills_claude_fast_multiplier_when_litellm_pricing_omits_it (line 1022) — verifies claude-opus-4.8-20260528 gets 2× while claude-opus-4-70 gets 1×

All four requirements are correctly implemented and numerically verified against the source. ✅

@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== Opus 4.8 / 4.6 / 4.7 entries in put_builtin_pricing ==="
rg -n "opus-4-[5678]|opus_4_[5678]|4-8\|4-7\|4-6" --type rust -C 6 rust/

echo ""
echo "=== fast-multiplier-overrides.json ==="
cat rust/crates/ccusage/src/fast-multiplier-overrides.json 2>/dev/null || fd "fast-multiplier" --exec cat {}

echo ""
echo "=== Test cases that verify fast-mode dollar amounts ==="
rg -n "10.*50\|50.*10\|30.*150\|150.*30\|fast.*4\\.8\|4\\.8.*fast\|fast.*opus" --type rust -C 4 | head -120

echo ""
echo "=== All embedded pricing entries for claude-opus-4 variants ==="
rg -n "claude-opus-4" --type rust -C 3 rust/ | head -200

Length of output: 39486



@ryoppippi Here's a precise, line-by-line verification of every figure you listed:


1. Opus 4.8 standard embedded pricing ✅

From pricing.rs Lines 263–277:

Rate Code value Per MTok
input 5e-6 $5
output 25e-6 $25
cache_create 6.25e-6 $6.25
cache_read 0.5e-6 $0.50

Confirmed also by embedded_pricing_resolves_opus_48_dot_model_names test (Line 894–898), which asserts all four exact values.


2. Fast-mode effective rates ✅

fast-multiplier-overrides.json:

"claude-opus-4-6": 6.0,
"claude-opus-4-7": 6.0,
"claude-opus-4-8": 2.0

Base rates are identical across 4.6/4.7/4.8 (5e-6 in, 25e-6 out), so effective fast-mode costs are:

Model Multiplier Fast input Fast output
claude-opus-4-8 5e-6 × 2 = $10/MTok 25e-6 × 2 = $50/MTok
claude-opus-4-7 5e-6 × 6 = $30/MTok 25e-6 × 6 = $150/MTok
claude-opus-4-6 5e-6 × 6 = $30/MTok 25e-6 × 6 = $150/MTok

Validated by embedded_pricing_includes_claude_fast_multiplier_for_provider_models test (Lines 849–869): asserts fast_multiplier == 2.0 for anthropic.claude-opus-4-8 and 6.0 for anthropic.claude-opus-4-6-v1 / anthropic.claude-opus-4-7.


3. Fuzzy matching ✅

Two dedicated tests confirm the guard behaviour:

  • fuzzy_match_requires_model_key_boundaries (Line 960):
    find("claude-opus-4.70")None even though both claude-opus-4 and claude-opus-4-7 are in the map. .70 is detected as a new numeric version → blocked.

  • fuzzy_match_does_not_fall_back_across_numeric_model_versions (Lines 982–984):
    When map contains only claude-opus-4:

    • find("claude-opus-4.8-20260528")None (.8 = numeric version boundary) ✅
    • find("claude-opus-4.70")None
    • find("claude-opus-4-20250514")Some(...) (8-digit date suffix exemption) ✅

All three requirements pass with exact dollar amounts matching Anthropic's published pricing.

@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown

Tip

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

@ryoppippi Here is the verified summary for all three pricing resolution behaviors:


1. Claude Opus 4.8 embedded/offline pricing ✅

From pricing.rs (put_builtin_pricing):

Rate Code value Per MTok
Input 5e-6 $5
Output 25e-6 $25
Cache write 6.25e-6 $6.25
Cache read 0.5e-6 $0.50

cache_read_explicit: true marks the cache-read rate as authoritative. These builtin entries are applied after the LiteLLM JSON, so they correctly override any stale data for offline/refresh-failure scenarios.


2. Fast-mode multipliers ✅

From fast-multiplier-overrides.json:

"claude-opus-4-6": 6.0,
"claude-opus-4-7": 6.0,
"claude-opus-4-8": 2.0
Model Multiplier Fast input Fast output
Opus 4.8 $10/MTok $50/MTok
Opus 4.6 $30/MTok $150/MTok
Opus 4.7 $30/MTok $150/MTok

The normalized_prefix matching also covers provider-prefixed variants (e.g. anthropic.claude-opus-4-8) — verified by the embedded_pricing_includes_claude_fast_multiplier_for_provider_models test.


3. Fuzzy model matching ✅

suffix_starts_with_numeric_model_version is the gate:

Model queried Expected Result
claude-opus-4.8-20260528 resolves via claude-opus-4-8 ✅ date-suffix allowed
claude-opus-4-20250514 resolves via claude-opus-4 ✅ date-suffix allowed
claude-opus-4.8 no fallback to claude-opus-4 ✅ numeric version blocked
claude-opus-4.70 no fallback to claude-opus-4 ✅ numeric version blocked

Tests covering these cases: embedded_pricing_resolves_opus_48_dot_model_names, fuzzy_match_requires_model_key_boundaries, fuzzy_match_does_not_fall_back_across_numeric_model_versions, and fills_claude_fast_multiplier_when_litellm_pricing_omits_it.


All three requirements are correctly implemented and verified against the source. ✅

@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 2 files

Re-trigger cubic

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
rust/crates/ccusage/src/pricing.rs (1)

636-655: ⚡ Quick win

Logic is correct; document the 8 date-length heuristic.

The boundary rules check out against the tests. The one snag for future maintainers is digit_len == 8 — it silently encodes "an 8-digit run is an Anthropic YYYYMMDD date alias (allowed), anything else is a numeric model revision (blocked)". This is central to correctness but invisible at the call site. A named constant or short comment prevents an accidental future edit from breaking version boundaries.

♻️ Name the date-suffix length
+/// Length of an Anthropic model date suffix (`YYYYMMDD`); treated as an alias,
+/// not a distinct numeric model version.
+const MODEL_DATE_SUFFIX_DIGITS: usize = 8;
+
 fn suffix_starts_with_numeric_model_version(key: &str, suffix: &str) -> bool {
     if !key.as_bytes().last().is_some_and(u8::is_ascii_digit) {
         return false;
     }
     if !matches!(suffix.as_bytes().first(), Some(b'-' | b'.')) {
         return false;
     }

     let rest = &suffix[1..];
     let digit_len = rest
         .as_bytes()
         .iter()
         .take_while(|byte| byte.is_ascii_digit())
         .count();
     if digit_len == 0 {
         return false;
     }
     let after_digits = rest.as_bytes().get(digit_len).copied();
-    !(digit_len == 8 && after_digits.is_none_or(is_pricing_key_boundary))
+    !(digit_len == MODEL_DATE_SUFFIX_DIGITS && after_digits.is_none_or(is_pricing_key_boundary))
 }
🤖 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/pricing.rs` around lines 636 - 655, The function
suffix_starts_with_numeric_model_version currently treats a digit_len == 8
specially without explanation; update this by introducing a named constant
(e.g., DATE_SUFFIX_LEN or ANTHROPIC_DATE_LEN) or a brief inline comment inside
suffix_starts_with_numeric_model_version explaining that an 8-digit run is
treated as a YYYYMMDD Anthropic date alias (allowed) while other numeric runs
mark numeric model revisions (blocked). Ensure the code replaces the literal 8
with the constant (or places the comment immediately adjacent to the check) so
future maintainers understand the heuristic used in the digit_len == 8 &&
after_digits.is_none_or(is_pricing_key_boundary) condition.
🤖 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/pricing.rs`:
- Around line 262-278: The pricing entry for "claude-opus-4-8" must reflect
public pricing and validated cache rates: verify that the fast multiplier
resolved by fast_multiplier_overrides.multiplier_for("claude-opus-4-8") is 2.0
(so fast mode yields $10/M input and $50/M output) and, separately, confirm
Anthropic’s prompt-caching rates match the embedded cache_create: 6.25e-6,
cache_read: 0.5e-6 and cache_read_explicit: true; if the docs differ, update the
Pricing fields (input, output, cache_create, cache_read, cache_read_explicit)
for the "claude-opus-4-8" entry accordingly and ensure any override for that
model explicitly sets multiplier 2.0.

---

Nitpick comments:
In `@rust/crates/ccusage/src/pricing.rs`:
- Around line 636-655: The function suffix_starts_with_numeric_model_version
currently treats a digit_len == 8 specially without explanation; update this by
introducing a named constant (e.g., DATE_SUFFIX_LEN or ANTHROPIC_DATE_LEN) or a
brief inline comment inside suffix_starts_with_numeric_model_version explaining
that an 8-digit run is treated as a YYYYMMDD Anthropic date alias (allowed)
while other numeric runs mark numeric model revisions (blocked). Ensure the code
replaces the literal 8 with the constant (or places the comment immediately
adjacent to the check) so future maintainers understand the heuristic used in
the digit_len == 8 && after_digits.is_none_or(is_pricing_key_boundary)
condition.
🪄 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: 7cf341e3-b7a6-4127-b508-cd9eb4685b02

📥 Commits

Reviewing files that changed from the base of the PR and between 284899c and dc2a90d.

📒 Files selected for processing (2)
  • rust/crates/ccusage/src/fast-multiplier-overrides.json
  • rust/crates/ccusage/src/pricing.rs

Comment thread rust/crates/ccusage/src/pricing.rs
Address CodeRabbit feedback by replacing the raw 8 used for Anthropic YYYYMMDD model aliases with a named constant. This keeps the numeric version boundary rule unchanged while making the date-alias exception explicit in code.
@ryoppippi

Copy link
Copy Markdown
Member Author

@coderabbitai review latest push a5c1279. I addressed your date suffix nit by replacing the raw 8 with MODEL_DATE_SUFFIX_DIGITS, and the pricing/cache-rate thread has been replied to with the Anthropic pricing confirmation.

@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== Commit a5c1279 diff ==="
git show a5c1279 --stat

echo ""
echo "=== Full diff for a5c1279 ==="
git show a5c1279

echo ""
echo "=== Search for MODEL_DATE_SUFFIX_DIGITS in codebase ==="
rg -n "MODEL_DATE_SUFFIX_DIGITS" --type rust -C4 rust/

Length of output: 3812



@ryoppippi The commit looks great. MODEL_DATE_SUFFIX_DIGITS: usize = 8 is declared at Line 14 and correctly replaces the raw 8 in suffix_starts_with_numeric_model_version at Line 655 — the YYYYMMDD date-alias exception is now self-documenting without any change to the underlying logic.

All the items raised in this review thread are resolved: embedded Opus 4.8 pricing ($5/$25 base, $6.25/$0.50 cache), 2× fast-mode multiplier for Opus 4.8 vs 6× for 4.6/4.7, and the numeric-version boundary guard with the named date-suffix constant. The PR is in good shape. ✅

(。•̀ᴗ-)✧

[approve]

@pkg-pr-new

pkg-pr-new Bot commented May 29, 2026

Copy link
Copy Markdown

Open in StackBlitz

ccusage

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

@ccusage/ccusage-darwin-arm64

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

@ccusage/ccusage-darwin-x64

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

@ccusage/ccusage-linux-arm64

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

@ccusage/ccusage-linux-x64

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

@ccusage/ccusage-win32-arm64

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

@ccusage/ccusage-win32-x64

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

commit: a5c1279

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: dc2a90dfce5f
Base SHA: 284899cc1ddb

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 284899cc1ddb 949.1ms 604.0ms 34.5ms 3
PR pkg.pr.new dc2a90d 953.1ms 599.1ms 34.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: 284899cc1ddb; PR package: dc2a90d. 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 544.9ms 557.2ms 0.98x 323.08 MiB 296.64 MiB 0.92x 1.85 GiB/s 1.81 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 372.5ms 388.7ms 0.96x 80.45 MiB 67.08 MiB 0.83x 2.70 GiB/s 2.59 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.0ms 1.82 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 520.7ms 1.93 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 373.3ms 2.70 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 344.1ms 2.93 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 30.8ms 4.1ms 7.49x 43.61 MiB 2.89 MiB 0.07x 0.05 MiB/s 0.38 MiB/s
claude session --offline --json 0.00 MiB 30.5ms 4.1ms 7.51x 43.48 MiB 2.70 MiB 0.06x 0.05 MiB/s 0.38 MiB/s
codex daily --offline --json 0.00 MiB 30.6ms 3.8ms 7.97x 43.61 MiB 2.83 MiB 0.06x 0.03 MiB/s 0.22 MiB/s
codex session --offline --json 0.00 MiB 30.5ms 3.9ms 7.88x 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 547.8ms 523.5ms 1.05x 308.14 MiB 322.20 MiB 1.05x 1.84 GiB/s 1.92 GiB/s
codex --offline --json 1.01 GiB 360.4ms 337.1ms 1.07x 78.58 MiB 80.58 MiB 1.03x 2.79 GiB/s 2.99 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
Contributor

ccusage performance comparison

PR SHA: dc2a90dfce5f
Base SHA: 284899cc1ddb

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 284899cc1ddb 792.6ms 596.2ms 34.0ms 3
PR pkg.pr.new dc2a90d 746.4ms 830.7ms 33.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: 284899cc1ddb; PR package: dc2a90d. 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 552.0ms 548.8ms 1.01x 301.26 MiB 285.08 MiB 0.95x 1.82 GiB/s 1.83 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 365.5ms 369.6ms 0.99x 79.33 MiB 69.20 MiB 0.87x 2.75 GiB/s 2.72 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 546.7ms 1.84 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 503.4ms 2.00 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 366.1ms 2.75 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 341.2ms 2.95 GiB/s 1

Committed fixture performance

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

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

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude daily --offline --json 0.00 MiB 30.1ms 30.2ms 1.00x 43.61 MiB 43.61 MiB 1.00x 0.05 MiB/s 0.05 MiB/s
claude session --offline --json 0.00 MiB 30.5ms 30.2ms 1.01x 43.73 MiB 43.48 MiB 0.99x 0.05 MiB/s 0.05 MiB/s
codex daily --offline --json 0.00 MiB 30.4ms 29.8ms 1.02x 43.61 MiB 43.48 MiB 1.00x 0.03 MiB/s 0.03 MiB/s
codex session --offline --json 0.00 MiB 30.2ms 30.3ms 0.99x 43.73 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 548.5ms 552.3ms 0.99x 301.76 MiB 327.39 MiB 1.08x 1.84 GiB/s 1.82 GiB/s
codex --offline --json 1.01 GiB 362.7ms 363.7ms 1.00x - 81.70 MiB - 2.78 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.

Document that the eight-digit exception in pricing-key matching corresponds to Anthropic YYYYMMDD model aliases, while other numeric suffixes are treated as distinct model versions.
@ryoppippi

Copy link
Copy Markdown
Member Author

@coderabbitai review latest push 2688af0. This is a comment-only follow-up documenting why the date suffix length is 8 (Anthropic YYYYMMDD aliases); the commit is marked [ci skip].

@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== Commit 2688af0 stat ==="
git show 2688af0 --stat

echo ""
echo "=== Full diff for 2688af0 ==="
git show 2688af0

Length of output: 1780



@ryoppippi Verified — commit 2688af0 is exactly as described: two comment lines added above MODEL_DATE_SUFFIX_DIGITS in pricing.rs, no logic touched.

// Anthropic date-suffixed model aliases use YYYYMMDD, while other numeric
// suffixes are treated as distinct model versions.
const MODEL_DATE_SUFFIX_DIGITS: usize = 8;

The comment accurately captures the intent: the 8-digit exception is specifically for Anthropic's YYYYMMDD alias scheme, and anything else (.8, .70, etc.) is treated as a distinct model version. Pairs perfectly with the named constant from the prior commit. ✅

(ᵔᴥᵔ)

[approve]

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: a5c1279365d5
Base SHA: 284899cc1ddb

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 284899cc1ddb 470.3ms 462.8ms 33.9ms 3
PR pkg.pr.new a5c1279 445.9ms 533.1ms 35.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: 284899cc1ddb; PR package: a5c1279. 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 564.5ms 556.4ms 1.01x 286.26 MiB 294.89 MiB 1.03x 1.78 GiB/s 1.81 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 380.6ms 376.5ms 1.01x 71.58 MiB 79.45 MiB 1.11x 2.65 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 544.6ms 1.85 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 528.4ms 1.91 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 371.5ms 2.71 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 346.3ms 2.91 GiB/s 1

Committed fixture performance

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

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

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude daily --offline --json 0.00 MiB 30.0ms 30.1ms 1.00x 43.48 MiB 43.48 MiB 1.00x 0.05 MiB/s 0.05 MiB/s
claude session --offline --json 0.00 MiB 30.5ms 30.1ms 1.01x - 43.73 MiB - 0.05 MiB/s 0.05 MiB/s
codex daily --offline --json 0.00 MiB 30.0ms 30.0ms 1.00x 43.48 MiB - - 0.03 MiB/s 0.03 MiB/s
codex session --offline --json 0.00 MiB 30.0ms 29.4ms 1.02x - 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 547.7ms 539.9ms 1.01x 312.14 MiB 294.89 MiB 0.94x 1.84 GiB/s 1.86 GiB/s
codex --offline --json 1.01 GiB 361.3ms 367.5ms 0.98x 79.70 MiB 78.33 MiB 0.98x 2.79 GiB/s 2.74 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
Contributor

ccusage performance comparison

PR SHA: a5c1279365d5
Base SHA: 284899cc1ddb

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 284899cc1ddb 621.2ms 517.6ms 35.2ms 3
PR pkg.pr.new a5c1279 596.0ms 609.8ms 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: 284899cc1ddb; PR package: a5c1279. 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 568.9ms 570.0ms 1.00x 338.58 MiB 333.14 MiB 0.98x 1.77 GiB/s 1.77 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 380.4ms 381.1ms 1.00x 80.83 MiB 78.63 MiB 0.97x 2.65 GiB/s 2.64 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 580.8ms 1.73 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 550.0ms 1.83 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 373.1ms 2.70 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 345.4ms 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 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.8ms 4.2ms 7.55x 43.61 MiB 2.89 MiB 0.07x 0.05 MiB/s 0.37 MiB/s
claude session --offline --json 0.00 MiB 32.6ms 4.6ms 7.06x 43.61 MiB 2.70 MiB 0.06x 0.05 MiB/s 0.33 MiB/s
codex daily --offline --json 0.00 MiB 32.1ms 4.0ms 7.99x 43.61 MiB 2.83 MiB 0.06x 0.03 MiB/s 0.21 MiB/s
codex session --offline --json 0.00 MiB 32.0ms 4.1ms 7.84x 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 565.5ms 543.1ms 1.04x 325.51 MiB 279.51 MiB 0.86x 1.78 GiB/s 1.85 GiB/s
codex --offline --json 1.01 GiB 379.0ms 346.1ms 1.09x 78.45 MiB 78.70 MiB 1.00x 2.66 GiB/s 2.91 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.

@ryoppippi ryoppippi merged commit f38b057 into main May 29, 2026
5 checks passed
@ryoppippi ryoppippi deleted the codex/fix-opus-48-pricing branch May 29, 2026 08:58
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