Skip to content

fix(claude): scope message dedupe by session - #1661

Merged
ryoppippi merged 3 commits into
mainfrom
codex/fix-claude-gateway-message-dedupe
Aug 29, 2026
Merged

ryoppippi merged 3 commits into
mainfrom
codex/fix-claude-gateway-message-dedupe

Conversation

@ryoppippi

@ryoppippi ryoppippi commented Aug 29, 2026 •

Copy link
Copy Markdown
Member

Summary

  • scope Claude Gateway fallback message-ID deduplication by session
  • retain canonical parent records when daily sidechain entries are replaced
  • add regressions for cross-session gateway events and daily replacement

Validation

  • cargo test -p ccusage-adapter-claude
  • cargo test -p ccusage-adapter-all claude
  • cargo fmt --check

Fixes #1635


Summary by cubic

Scopes Claude Gateway message deduplication by session so distinct sessions that reuse a message ID are no longer collapsed, fixing cross-session usage undercounting.

  • Message dedupe now includes the session ID; without a requestId, the daily loader also includes the timestamp, while the regular loader still collapses same-session duplicates across timestamps.
  • Daily sidechain replay matching uses the effective session ID and no longer requires matching timestamps; the regular loader still requires them.
  • Canonical parent records are retained when daily sidechain entries are replaced, and agent progress entries preserve session info.
  • Fixes Claude usage collapses to one entry when sessions share a message id (gateway setups) #1635.

Written for commit 4cfa019. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Bug Fixes
    • Improved Claude usage deduplication to distinguish entries from separate sessions, even when message IDs or timestamps are reused.
    • Continued removing duplicate records from copied transcripts within the same session.
    • Enabled sidechain replay matching across differing timestamps while preserving session boundaries.
    • Improved handling of requestless entries with different timestamps.
  • Tests
    • Added coverage for session-aware and timestamp-independent deduplication.
  • Documentation
    • Documented the updated deduplication behavior.

Fix duplicate Claude Gateway message identifiers without conflating events from separate sessions.

Co-authored-by: Fluffy-Bunny-23 <[email protected]>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 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 Preview URL Updated (UTC)
✅ Deployment successful!
View logs
ccusage-guide 4cfa019 Commit Preview URL

Branch Preview URL
Aug 29 2026, 08:16 PM

@coderabbitai

coderabbitai Bot commented Aug 29, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d0c71364-2e8b-4aa8-a2b3-9f6dff269bc4

📥 Commits

Reviewing files that changed from the base of the PR and between d26dc6d and 4cfa019.

📒 Files selected for processing (4)
  • rust/adapters/claude/src/README.md
  • rust/adapters/claude/src/daily.rs
  • rust/adapters/claude/src/lib.rs
  • rust/crates/ccusage/src/main.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • rust/adapters/claude/src/README.md

Included review availability: Your plan provides up to 10 included reviews per hour; 2 remain after this review.


📝 Walkthrough

Walkthrough

Claude usage deduplication now includes effective session IDs and timestamps. Distinct sessions that reuse message IDs remain separate, while duplicate writes and copied transcripts remain deduplicated. Session metadata propagates through daily usage entries.

Changes

Claude session-aware deduplication

Layer / File(s) Summary
Propagate session metadata
rust/adapters/claude/src/daily.rs
Daily entries retain timestamps and effective session IDs from serialized sessionId values or file paths. Agent progress and advisor entries preserve this metadata.
Scope deduplication keys
rust/adapters/claude/src/lib.rs, rust/adapters/claude/src/daily.rs
General deduplication includes session IDs. Daily requestless matching includes timestamps. Sidechain replay matching uses a session-scoped key. Replacement and insertion indexes use the updated keys.
Validate session-aware behavior
rust/adapters/claude/src/daily.rs, rust/adapters/claude/src/lib.rs, rust/crates/ccusage/src/main.rs, rust/adapters/claude/src/README.md
Tests cover distinct sessions, copied transcripts, requestless timestamps, replay replacement, and metadata propagation. The README documents the matching rules.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Merge Risk: ⚪ Minimal · up to 4cfa0

The change scopes Claude Gateway message deduplication by session and preserves canonical daily records, with no actionable merge-blocking risk remaining beyond normal checks and review.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.17% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 29 functions across 3 files. (1 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the primary change: scoping Claude message deduplication by session.
Linked Issues check ✅ Passed The changes satisfy issue #1635 by adding session-aware deduplication, preserving entries from distinct sessions, retaining same-session duplicate suppression, handling missing requestId values with t…
Out of Scope Changes check ✅ Passed The README updates, Claude adapter changes, and ccusage regression tests directly support the session-scoped deduplication objectives in issue #1635. No unrelated code changes are identified.
Full details: Linked Issues check

Explanation

The changes satisfy issue #1635 by adding session-aware deduplication, preserving entries from distinct sessions, retaining same-session duplicate suppression, handling missing requestId values with timestamps, supporting sidechain replay rules, and adding regression tests.

Full details: Docstring Coverage

Explanation

Docstring coverage is 55.17% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 29 functions across 3 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-claude-gateway-message-dedupe

Warning

Some tools did not complete. Review the errors below.

🔧 Clippy (1.97.1)

Clippy execution failed


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.

@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 sidechain replay fallback can now leave valid /btw replays in the output when their timestamps differ from the parent, causing usage to be overcounted.

Reviewed changes

This review covers the Claude regular and daily deduplication changes, session identity propagation, regression tests, and adapter documentation.

  • Session-scoped deduplication — Includes the effective serialized or path-derived session ID in regular and daily dedupe keys.
  • Timestamp fallback — Uses timestamps for records without requestId so gateway records with reused message IDs remain distinct across sessions while same-session writes still collapse.
  • Daily propagation and indexing — Carries timestamps and session IDs through direct and AgentProgress records and refreshes indexes when a parent replaces a sidechain replay.
  • Regression coverage and documentation — Adds fixture-backed tests for gateway sessions, copied transcripts, AgentProgress metadata, and parent replacement, plus documents the gateway behavior.

Pullfrog  | ⚠️ this action is pinned to a commit SHA, which freezes the cleanup step — switch to @v0 or keep the SHA fresh with Dependabot | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using GPT Luna (free via Pullfrog for OSS) | 𝕏

) -> bool {
entry.data.message.id.as_deref() == Some(message_id)
&& loaded_entry_session_id(entry) == session_id
&& entry.timestamp == timestamp

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.

This adds timestamp equality to the message-only /btw fallback. That fallback handles a parent and sidechain replay with different request IDs; if the replay timestamp differs, the lookup misses and both usage entries survive, overcounting reports. Please keep timestamp in the exact no-request-ID identity, but preserve the previous message/session sidechain fallback across timestamp differences and add a regression for both regular and daily loaders.

Technical details
# Preserve `/btw` replay deduplication across timestamps

## Affected sites
- `rust/adapters/claude/src/lib.rs:258-261` — the message-only sidechain matcher now requires exact `TimestampMs` equality.
- `rust/adapters/claude/src/daily.rs:441-445` — the daily matcher applies the same restriction.

## Required outcome
- Keep session and timestamp scoping for entries with no `requestId`, but do not require timestamps to match when the message-only fallback reconciles a known parent with a sidechain replay carrying a different `requestId`.
- Add regression coverage for the same message and session with different request IDs and timestamps in both loaders.

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

All reported issues were addressed across 4 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread rust/adapters/claude/src/lib.rs Resolved
@pkg-pr-new

pkg-pr-new Bot commented Aug 29, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

ccusage

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

@ccusage/ccusage-darwin-arm64

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

@ccusage/ccusage-darwin-x64

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

@ccusage/ccusage-linux-arm64

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

@ccusage/ccusage-linux-x64

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

@ccusage/ccusage-win32-x64

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

commit: 4cfa019

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: 7ac9de34adfd
Base SHA: 217681507bf7

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 405.8ms 2.48 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 373.5ms 2.70 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 118.2ms 8.52 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 92.0ms 10.94 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 39.6ms 17.5ms 2.27x 55.00 MiB 24.72 MiB 0.45x 0.04 MiB/s 0.09 MiB/s
claude session --offline --json 0.00 MiB 41.7ms 8.8ms 4.72x 55.00 MiB 24.71 MiB 0.45x 0.04 MiB/s 0.17 MiB/s
codex daily --offline --json 0.00 MiB 34.6ms 8.6ms 4.03x 54.75 MiB 24.71 MiB 0.45x 0.02 MiB/s 0.10 MiB/s
codex session --offline --json 0.00 MiB 33.6ms 8.6ms 3.92x 55.00 MiB 24.71 MiB 0.45x 0.03 MiB/s 0.10 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 408.8ms 367.3ms 1.11x 958.84 MiB 956.86 MiB 1.00x 2.46 GiB/s 2.74 GiB/s
codex --offline --json 1.01 GiB 121.4ms 98.0ms 1.24x 407.16 MiB 417.16 MiB 1.02x 8.29 GiB/s 10.27 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 19.16 KiB 19.16 KiB +0.00 KiB 1.00x
installed native package binary 4247.09 KiB 4249.78 KiB +2.69 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: 7ac9de34adfd
Base SHA: 217681507bf7

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 352.0ms 2.86 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 332.2ms 3.03 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 109.0ms 9.24 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 83.4ms 12.07 GiB/s 1

Committed fixture performance

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

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

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude daily --offline --json 0.00 MiB 39.3ms 39.0ms 1.01x 55.25 MiB 55.00 MiB 1.00x 0.04 MiB/s 0.04 MiB/s
claude session --offline --json 0.00 MiB 33.6ms 30.7ms 1.09x 54.75 MiB 55.25 MiB 1.01x 0.05 MiB/s 0.05 MiB/s
codex daily --offline --json 0.00 MiB 31.5ms 30.3ms 1.04x 54.75 MiB 55.00 MiB 1.00x 0.03 MiB/s 0.03 MiB/s
codex session --offline --json 0.00 MiB 31.0ms 30.8ms 1.01x 55.00 MiB 55.00 MiB 1.00x 0.03 MiB/s 0.03 MiB/s

Large real-world-shaped fixture performance

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

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 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 351.1ms 349.9ms 1.00x 956.85 MiB 960.85 MiB 1.00x 2.87 GiB/s 2.88 GiB/s
codex --offline --json 1.01 GiB 106.1ms 109.9ms 0.97x 417.16 MiB 413.17 MiB 0.99x 9.49 GiB/s 9.16 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 19.16 KiB 19.16 KiB +0.00 KiB 1.00x
installed native package binary 4247.09 KiB 4249.78 KiB +2.69 KiB 1.00x

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

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ℹ️ No new issues found in this delta. The previously reported regular-loader /btw replay concern remains open in the existing review thread.

Reviewed changes

This incremental review covers the daily sidechain replay changes added after 7ac9de3.

  • Added session-scoped replay matching — Used a separate message/session replay index so daily parent and sidechain records with different timestamps still collapse without crossing session boundaries.
  • Propagated daily identity — Retained parsed timestamps and effective session IDs through direct and AgentProgress entries.
  • Refreshed replacement indexes — Reindexed the daily entry after a parent replaced a sidechain replay and added regressions for timestamp differences, distinct sessions, requestless entries, and copied transcripts.

Pullfrog  | ⚠️ this action is pinned to a commit SHA, which freezes the cleanup step — switch to @v0 or keep the SHA fresh with Dependabot | Fix it ➔ | View workflow run | Using GPT Luna (free via Pullfrog for OSS) | 𝕏

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: d26dc6d87acf
Base SHA: 217681507bf7

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 388.7ms 2.59 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 353.8ms 2.85 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 142.0ms 7.09 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 101.1ms 9.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 37.5ms 37.1ms 1.01x 55.25 MiB 55.50 MiB 1.00x 0.04 MiB/s 0.04 MiB/s
claude session --offline --json 0.00 MiB 35.4ms 29.9ms 1.18x 54.75 MiB 55.00 MiB 1.00x 0.04 MiB/s 0.05 MiB/s
codex daily --offline --json 0.00 MiB 31.2ms 30.5ms 1.02x 55.25 MiB 55.25 MiB 1.00x 0.03 MiB/s 0.03 MiB/s
codex session --offline --json 0.00 MiB 33.5ms 31.2ms 1.07x 55.25 MiB 55.00 MiB 1.00x 0.03 MiB/s 0.03 MiB/s

Large real-world-shaped fixture performance

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

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 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 360.9ms 382.9ms 0.94x 940.84 MiB 966.85 MiB 1.03x 2.79 GiB/s 2.63 GiB/s
codex --offline --json 1.01 GiB 117.5ms 126.6ms 0.93x 427.16 MiB 417.16 MiB 0.98x 8.57 GiB/s 7.95 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 19.16 KiB 19.20 KiB +0.04 KiB 1.00x
installed native package binary 4247.09 KiB 4249.09 KiB +2.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: d26dc6d87acf
Base SHA: 217681507bf7

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 548.1ms 1.84 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 516.7ms 1.95 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 197.8ms 5.09 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 125.7ms 8.01 GiB/s 1

Committed fixture performance

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

Fixtures: Claude apps/ccusage/test/fixtures/claude (0.00 MiB, 2 files), Codex apps/ccusage/test/fixtures/codex (0.00 MiB, 1 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published 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 33.5ms 16.0ms 2.09x 55.00 MiB 24.71 MiB 0.45x 0.05 MiB/s 0.10 MiB/s
claude session --offline --json 0.00 MiB 32.5ms 8.2ms 3.95x 55.00 MiB 24.71 MiB 0.45x 0.05 MiB/s 0.19 MiB/s
codex daily --offline --json 0.00 MiB 30.6ms 8.5ms 3.59x 55.00 MiB 24.71 MiB 0.45x 0.03 MiB/s 0.10 MiB/s
codex session --offline --json 0.00 MiB 30.7ms 7.8ms 3.95x 55.00 MiB 24.71 MiB 0.45x 0.03 MiB/s 0.11 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 364.9ms 338.8ms 1.08x 956.84 MiB 940.85 MiB 0.98x 2.76 GiB/s 2.97 GiB/s
codex --offline --json 1.01 GiB 169.8ms 124.2ms 1.37x 417.15 MiB 427.16 MiB 1.02x 5.93 GiB/s 8.10 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 19.16 KiB 19.20 KiB +0.04 KiB 1.00x
installed native package binary 4247.09 KiB 4249.09 KiB +2.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.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ℹ️ No new issues found in this delta. The existing regular-loader /btw replay concern remains open.

Reviewed changes

This incremental review covers the follow-up changes since the previous Pullfrog review.

  • Restored regular requestless dedupe — Removed timestamps from the regular exact dedupe identity so same-session records without requestId continue to collapse across timestamps.
  • Separated daily identity — Kept timestamps in daily exact dedupe keys while retaining timestamp-independent, session-scoped sidechain replay matching.
  • Added regression coverage and documentation — Covered same-session requestless duplicates and documented the regular-versus-daily behavior.

Pullfrog  | ⚠️ this action is pinned to a commit SHA, which freezes the cleanup step — switch to @v0 or keep the SHA fresh with Dependabot | Fix it ➔ | View workflow run | Using GPT Luna (free via Pullfrog for OSS) | 𝕏

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: 4cfa01910b2d
Base SHA: 217681507bf7

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 373.7ms 2.69 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 339.7ms 2.96 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 128.3ms 7.85 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 111.3ms 9.04 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.7ms 37.1ms 1.10x 55.25 MiB 55.00 MiB 1.00x 0.04 MiB/s 0.04 MiB/s
claude session --offline --json 0.00 MiB 32.3ms 32.5ms 0.99x 55.25 MiB 55.25 MiB 1.00x 0.05 MiB/s 0.05 MiB/s
codex daily --offline --json 0.00 MiB 29.9ms 28.6ms 1.05x 55.00 MiB 55.00 MiB 1.00x 0.03 MiB/s 0.03 MiB/s
codex session --offline --json 0.00 MiB 29.4ms 29.7ms 0.99x 55.00 MiB 55.00 MiB 1.00x 0.03 MiB/s 0.03 MiB/s

Large real-world-shaped fixture performance

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

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 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 369.0ms 388.5ms 0.95x 962.84 MiB 948.85 MiB 0.99x 2.73 GiB/s 2.59 GiB/s
codex --offline --json 1.01 GiB 123.7ms 120.4ms 1.03x 425.15 MiB 421.16 MiB 0.99x 8.14 GiB/s 8.36 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 19.16 KiB 19.20 KiB +0.04 KiB 1.00x
installed native package binary 4247.09 KiB 4248.97 KiB +1.88 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: 4cfa01910b2d
Base SHA: 217681507bf7

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 358.9ms 2.81 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 328.8ms 3.06 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 117.2ms 8.59 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 95.9ms 10.50 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 35.8ms 16.3ms 2.20x 55.00 MiB 24.71 MiB 0.45x 0.04 MiB/s 0.09 MiB/s
claude session --offline --json 0.00 MiB 29.4ms 8.1ms 3.62x 55.00 MiB 24.71 MiB 0.45x 0.05 MiB/s 0.19 MiB/s
codex daily --offline --json 0.00 MiB 29.9ms 7.9ms 3.79x 55.00 MiB 24.71 MiB 0.45x 0.03 MiB/s 0.11 MiB/s
codex session --offline --json 0.00 MiB 29.3ms 7.6ms 3.84x 54.75 MiB 24.71 MiB 0.45x 0.03 MiB/s 0.11 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 376.9ms 365.3ms 1.03x 950.84 MiB 962.85 MiB 1.01x 2.67 GiB/s 2.76 GiB/s
codex --offline --json 1.01 GiB 118.7ms 98.8ms 1.20x 421.16 MiB 417.16 MiB 0.99x 8.48 GiB/s 10.19 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 19.16 KiB 19.20 KiB +0.04 KiB 1.00x
installed native package binary 4247.09 KiB 4248.97 KiB +1.88 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 a4b8420 into main Aug 29, 2026
41 checks passed
@ryoppippi
ryoppippi deleted the codex/fix-claude-gateway-message-dedupe branch August 29, 2026 20:33
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.

Claude usage collapses to one entry when sessions share a message id (gateway setups)

1 participant