Skip to content

perf(session): cut per-turn store walks, re-parses and stringifies - #1434

Merged
TheGreatAxios merged 2 commits into
mainfrom
cl-10666-session-perf-cut-per-turn-walks-re-parses-stringifies
Oct 15, 2026
Merged

TheGreatAxios merged 2 commits into
mainfrom
cl-10666-session-perf-cut-per-turn-walks-re-parses-stringifies

Conversation

@TheGreatAxios

Copy link
Copy Markdown
Collaborator

Summary

  • Cuts per-turn session-store I/O: one cached worktree survey replaces per-candidate stat probes inside commit() (fs-op census: 139 → 124 ops/turn on a 200-turn simulation; fs.access 2,697 → 3 per run); a per-store turns cache with per-segment stat fingerprints + explicit mutation-site invalidation parses each segment once (the three separate full-history parses per turn become one shared generation, parsing only changed/new segments); contentPrefixLength/promptEqualsLiveTurns memoize turn JSON instead of re-stringifying full history; the well-formedness prefix check becomes a single forward pass (O(E²) → O(E), equivalence probed on 50,000 randomized interleavings before ship); readAt resolves a commit-time segment-manifest.json and parallel-reads segment blobs, degrading to the old ref-tree walk on missing/torn/foreign manifests; attachment blob reads dedupe per id; aged-image markers prefilter before regex; the anthropic-cache prompt builds its tool-name/boundary maps in one forward scan; compaction call identities are cached per persisted block.
  • Cache invalidation is wider than the reads it replaces: every segment mutation site (appends, staged rewrites, heal unlinks, failed-commit restores) drops the cache in-process; external writers surface via stat fingerprints; foreign same-size/same mtime+ino rewrites are the one theoretical evader (noted, mitigated only by extreme coincidence).
  • Durability first: the resume/rebuild contract is unchanged; the manifest is name-based (never stale after gc/history rewrite) and every read path has a verified fallback to the pre-existing walk.
  • Ships with a repeatable measurement harness (scripts/context-store-perf.ts, standalone; fs-op census deterministic, wall noisy).

Verification

  • bun run check exit 0: 8,945 pass / 0 fail across 580 files; src/session suites 62 store tests (4 new) + 7 attachment tests (2 new) green.
  • Independent review: invalidation enumerated per mutation site; memo preconditions verified against frozen turn boundaries; well-formedness equivalence probed; harness honesty verified (never picked up by the test suites).
  • Before/after (documented): fs ops −11%/turn; wall median ~8.3 → 7.3 ms/turn over 4 paired runs (host-noisy; census is the reliable number).

Fixes CL-10666

A 200-turn simulation dropped 139 to 124 fs ops per turn (access
probes 2697 to 3) and wall median ~13%. commit() now surveys the
worktree once instead of stat-probing every candidate segment; a
per-store turns cache with per-segment stat fingerprints plus explicit
mutation-site invalidation loads each segment at most once, so load/
readLiveTurns/prompt-write parse once per content instead of three
times. contentPrefixLength/promptEqualsLiveTurns memoize turn JSON
instead of stringifying full history; the well-formedness prefix scan
is a single forward pass instead of O(E^2); readAt reads a commit-time
segment manifest and parallel blob reads, degrading to the ref-walk
when the manifest is absent or torn; attachment blob reads dedupe;
aged-image markers prefilter before regex; anthropic cache prompt
aggregates one forward scan; compaction identities are cached per
tool_call block.

Invalidation is strictly wider than the reads it replaced: mutation
sites and failed-commit restores drop the caches; corrupt manifests
degrade to the walk.
@linear-code

linear-code Bot commented Oct 14, 2026

Copy link
Copy Markdown

CL-10666

@corbits-triage

corbits-triage Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Superseded by the comment below.

@corbits-triage

corbits-triage Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Superseded by the comment below.

@corbits-triage

corbits-triage Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Triage: Pass

No changes needed from you. A maintainer will review this pull request.

@TheGreatAxios
TheGreatAxios changed the base branch from cl-10654-isomorphic-git-1442-batch-remove-hot-path-perf to main October 15, 2026 19:47
…-cut-per-turn-walks-re-parses-stringifies

# Conflicts:
#	src/session/attachment-store.ts
@TheGreatAxios
TheGreatAxios merged commit 8c964b5 into main Oct 15, 2026
13 checks passed
@TheGreatAxios

Copy link
Copy Markdown
Collaborator Author

Independent perf verification for this PR (measure-only lane, no source touched).

Method: the commit's own harness scripts/context-store-perf.ts (fs.promises op shim, split by .git paths), run verbatim on three cells × 3 runs × 200 turns, one machine (Bun 1.4.2, arm64): PRE @ 10042685 (pre-merge parent), POST @ 8d879e94 (landing), MAIN @ origin/main.

  • fs ops/turn: PRE 139.12 / 139.22 / 139.16 (median 139.16) → POST 123.84 / 123.89 / 123.87 (median 123.87). Delta ≈ −15.3 ops/turn (−11%). Claim CONFIRMED. Counts deterministic except mkdir/writeFile ±6 (isogit dir retries); everything else bit-exact across runs.
  • Access probes: PRE 2697 / 2697 / 2697 → POST and origin/main 3 / 3 / 3, constant and scale-free. Claim CONFIRMED exactly. The ~2694 eliminated probes are the per-candidate-segment access/stat walk in commit() replaced by one surveyWorktree readdir.
  • Wall median ~13%: PRE 914/1181/782 (median 914 ms) → POST 702/958/793 (median 793 ms, −13.2%). Directional only — n=3 wall is noisy (ranges overlap).
  • origin/main today: ~124.9 ops/turn, access still 3. Later coalescing shifted composition (readFile up, lstat down) but the headline holds.

No prompt/policy retune indicated — the optimization measures exactly as claimed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant