Exploration notes: cheaper window-expiry processing from retained contributions #130
Description
Following the #121 review suggestion to explore cheaper expiry processing from retained contributions — some measurements and a structural finding from a workstation with a 976-file, 1.58 GB history.
Measured cost today (four days of live logs)
- Passes that re-read 1–14 bodies (appends plus window-drift re-reads): 237, of which ~91 moved ≥1 MB, i.e. real body re-reads rather than tail appends. Total read-parse across all of them: ~243 s over four days.
- Deletion-triggered full rebuilds: ~9 (~30 s each) — addressed by perf: deleting a transcript no longer re-reads the whole history (#99) #127.
- Rewrite-triggered full rebuilds: ~31 (~20–40 s each) — addressed by perf: rewriting a transcript no longer re-reads the whole history (#99) #128.
- Cold-start full reads (one per window start): 7 — the remaining big rock; presumably covered by the checkpoint work that just landed for Codex caches.
So exact per-drift boundary re-reads cost roughly 3–4 minutes per four days here — real, but an order of magnitude below what the mutation rebuilds cost.
Structural finding
Exact expiry subtraction needs to remove, from a file's retained AnalysisAcc, precisely the events that crossed the cutoff:
structuralEventscarry no timestamps, so expired tool events cannot be selected from them;seenUuidsexpiry interacts with first-owner dedup: an expired UUID may have an in-window twin whose ownership must be restored (the'ownership'plan machinery would need the expired UUIDs enumerated);- prompts do carry
observedAtEpochMs, so the bounded tail is fine.
Closing the gap means retaining per-event (or per-bucket-per-timestamp) data for the whole 30-day window — a memory cost paid on every refresh to save a small one-off read per boundary file. An exact middle ground I sketched is an offset-slice re-read: keep the byte offset of the oldest retained line per file, and on drift re-read only the newly expired prefix slice (transcripts are append-only and near-monotonic in time, with a full-read fallback when the guard trips). That keeps retention flat but still touches parse, subtraction for every sub-structure, and the ownership handoff.
My conclusion: not worth the contract churn now — #127 and #128 remove the storms, and the drift re-reads are already bounded to the few files the cutoff is crossing. Filing this so the exploration is on record; happy to build the offset-slice variant if you want it anyway.
🤖 Generated with Claude Code
Activity
github-actions commentedon Oct 9, 2026
🤖 Automated first-pass reply
TL;DR
The measurements are clear and the cost is small: ~3–4 minutes of read-parse per four days from drift re-reads, an order of magnitude below the ~9 deletion rebuilds (#127) and ~31 rewrite rebuilds (#128). The structural finding is the real conclusion: exact expiry subtraction would require retaining per-event or per-bucket-per-timestamp data for the full 30-day window, paid on every refresh. Not worth the contract churn now.
Analysis
claudeIncrementalIndex.ts— "Runtime refreshes must not fall back to a full-corpus body read", with append/truncate/replace/move/delete work "limited to affected files and affected aggregate groups while preserving the established response-identity and content-analysis semantics." The exact per-drift boundary re-read is exactly this "affected files" set.structuralEventscarry no timestamps (so expired tool events cannot be selected),seenUuidsexpiry couples to first-owner dedup via the'ownership'plan machinery (so expired UUIDs would need enumeration to restore an in-window twin's ownership), while prompts do carryobservedAtEpochMsand the bounded tail is already fine.Suggested next step(s)
claudeIncrementalIndex.ts. A cheap prerequisite measurement would be how often the near-monotonic-time guard trips on real transcripts, since that bounds the fallback cost.🤖 Generated by DeepSeek as an automated first pass — not a maintainer decision.
Carl723000 commentedon Oct 15, 2026
Thanks @rsyuzyov for the measurements and for spelling out the expiry/ownership trade-off. This is useful exploration to keep on record. The current exact rolling-window contract is retained; an offset-slice implementation would need a separate proposal and regressions for out-of-order timestamps, UUID first-owner restoration and full-loader content-analysis equivalence.
One important scope distinction: Codex's persistent checkpoints do not eliminate Claude's cold-start in-memory build. Also, #127 and #128 are still open, so their mutation-rebuild optimizations should not be read as already shipped in 2.5.0.
Closing this exploration as not planned for the current scope, rather than as an implemented optimization. The original contribution and measurements remain here; #99 and the original performance PRs continue to track the remaining work. A future offset-slice proposal can link back to these findings.
🤖 Generated by OpenAI Codex as an automated first pass — not a maintainer decision.