Repository navigation
perf(server): skip out-of-window usage records before aggregating - #35
Merged
Merged
Conversation
Every usage summary, even the 24h window, walked all ~275k cached records and rebuilt each Codex dedupe key with a Schema JSON encode per request. The aggregator now exposes a cheap instant bound (exact for hourly windows, a one-day superset for zoned day windows), and unkeyed records outside it are skipped before keying. Equal Codex identities share a timestamp, so skipping never shifts an in-window occurrence count, and keyed records still register their key out of window. Codex identities are memoised per record. Summaries are identical to the old loop on the real 275k-record cache across five zones and five windows. Warm 24h summary: 430-498ms to 154-212ms. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Listing ~3,900 transcripts awaited one stat at a time. Stats now run 32 at a time while results keep walk order, which decides which copy of a duplicated record wins. Warm listing drops from ~60-110ms to ~35ms. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Owner
Author
|
Verdict: PASS+NOTES Head: 6667d6f (independent verifier, fresh worktree) What I ran
Findings
|
andrewcai8
enabled auto-merge (squash)
September 22, 2026 23:30
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Usage page felt slow partly because every
getUsageSummarywalked every cached transcript record, about 275k on a real machine, even for the past-24h view, which uses about 49k. It also rebuilt the Codex dedupe key (Schema.encodeSync) for each record on every request, and stat'ed about 3,800 transcript files one at a time.How it's fixed:
admits(timestamp)check. Records outside the window are skipped before any key is built: exactly for hourly windows, and with one day of slack for day windows so any time-zone offset is safe. The exact day check still decides. Keyed Claude/Grok records still go throughadd, so a copy seen outside the window still suppresses a later copy inside it, as before.addTranscript, which builds each Codex key once per cached record and reuses it.listTranscriptFilesstats files 32 at a time and keeps walk order, which decides which copy of a duplicate wins.Results are unchanged. An equality test compares
addTranscriptwith the old loop across five windows (hourly LA, day LA, +14h, −11h, a UTC month), including moved Codex rollouts and a Claude key first seen out of window. A differential run on the real 275k-record cache matched in 25 of 25 zone/window combinations.Measured on a warm cache (e2e
UsageService.readSummarywithout Cursor, two runs each):The machine was under heavy load during these runs, so the numbers are noisy.
🤖 Generated with Claude Code