You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Runtime Host session retirement drains a batch of M Sessions (packages/runtime-host/src/server/session-retirement-coordinator.ts), and each Session's artifact cleanup triggers its own fully serialized ArtifactStore.purge(). Each individual purge:
Runs a guard scan over all live records (case-insensitive path + inode/symlink alias validation),
Resolves removal entries (realpath/lstat) for every non-target live record,
So retiring M Sessions against a store of N records costs M full-record scans and M full-table metadata commits — O(M×N) on both the filesystem and the metadata side. On a real store with ~11.7k records and hundreds of retiring Sessions, this dominates cold start (profile data in this #4027 comment: ~90 s of the residual ~130 s).
#4031 made per-purge resolution concurrent (8-wide worker pool), which is a constant-factor improvement only — the review there identified batched purge as the converged design.
Proposed direction
A bulk purge path that accepts the whole retiring Session batch at once, reusing the existing multi-ID purge intent mechanism:
One purge intent covering the union of the batch's artifact ids (the intent schema already carries multiple ids),
One guard scan over the live record set (case/alias validation against the union of targets),
This removes the M multiplier without weakening case-insensitive or symlink-alias integrity and without adding another authority. Combined with change-tracked metadata write-back (companion proposal), a retirement batch becomes one O(N) guard scan + one O(changed) metadata commit.
Questions for maintainers
The retirement coordinator currently drains Sessions one at a time; is batching the artifact purge across the whole drain batch acceptable from the lifecycle/ownership point of view, or are there per-Session ordering guarantees the single-purge loop is protecting?
The purge intent record is the crash-recovery evidence for interrupted purges. Does carrying a multi-Session batch in one intent change any recovery-contract expectations (e.g. partial-batch resume semantics), or is "resume the whole intent" already the defined behavior?
Problem
Runtime Host session retirement drains a batch of M Sessions (
packages/runtime-host/src/server/session-retirement-coordinator.ts), and each Session's artifact cleanup triggers its own fully serializedArtifactStore.purge(). Each individual purge:realpath/lstat) for every non-target live record,DELETE+ re-INSERT of every record — see the companion metadata proposal (perf(storage): artifact metadata rewrites the full record table on every mutation (O(M×N) during startup) #4037)).So retiring M Sessions against a store of N records costs M full-record scans and M full-table metadata commits — O(M×N) on both the filesystem and the metadata side. On a real store with ~11.7k records and hundreds of retiring Sessions, this dominates cold start (profile data in this #4027 comment: ~90 s of the residual ~130 s).
#4031 made per-purge resolution concurrent (8-wide worker pool), which is a constant-factor improvement only — the review there identified batched purge as the converged design.
Proposed direction
A bulk purge path that accepts the whole retiring Session batch at once, reusing the existing multi-ID purge intent mechanism:
This removes the M multiplier without weakening case-insensitive or symlink-alias integrity and without adding another authority. Combined with change-tracked metadata write-back (companion proposal), a retirement batch becomes one O(N) guard scan + one O(changed) metadata commit.
Questions for maintainers
Related: #4027 (cold-start investigation), #4031 (bounded purge resolution; review point on the O(M×N) structure and this converged design).
This issue was prepared with AI assistance (Kimi k3-256k), including profiling and analysis.