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
{{ message }}
Repository navigation
perf(boot): bound and prioritise rehydrate spawns instead of launching every pane at once #774
On boot rehydrate.ts:663 spawns every tile leaf of every tab in one Promise.all: today's three boots launched 10–13 claude/codex/opencode CLIs plus 10 mitmdump within ~1 s on a 16 GB machine already at 12–13 GB swap. Claude panes then take 8–30 s to become input-ready (CLI first paint 6–20 s after spawn), each boot adds ~2 GB RSS, and the first usable pane appears after 12–24 s. Codex resumes of large rollouts (93 MB) and opencode TUIs exceed 30 s, which today trips the readiness-kill in ensureSessionLive (#772).
Expected
Spawn the active tab's visible panes first, then the rest with a bounded concurrency (~3 in flight), so the first usable pane appears in ~3–5 s and the herd never starves any single CLI.
Background tabs' sessions are recovered lazily (on first reveal) or at low priority.
The recover IPC and the readiness wait are decoupled from pane mount, so a slow CLI never blocks or kills a pane.
Evidence
Boot audit 2026-09-03 (scratchpad/boot-resume-audit.md): recover IPC 0.5–2.4 s per session (codex 3–7 s) fully parallel; input ready 8–30 s; lifecycle journal kill.request cause=live-entry at 35.6–35.8 s ×3 (run 75117) and 69.5 s (run 95737); panes re-woken by hand at 94 s, 217 s and 556 s after boot.
Fixed on main and never closed — by a stronger mechanism than the one proposed, which is worth recording because the issue's own wording no longer describes the code.
The unbounded Promise.all over every tile leaf is gone. rehydrate.ts:597-599 filters the spawn set through liveProcessIds, and collectLiveProcessIds (sessionOwnership.ts:117-131) returns the focused lane's occupant and nothing else. So "active tab's visible panes first, then bounded concurrency ~3" is superseded by "exactly one at boot", and "background tabs recovered lazily on first reveal" is met literally — every other session wakes on first send, on lane placement, or on terminal mount.
The readiness half is b83ff9cc (Fixes #772, Refs #774): a wake timeout with a live backend now resolves and journals wake.result code:'ready-timeout' instead of killing, so the kill.request cause=live-entry in this issue's evidence cannot recur.
Tests: sessionOwnership.test.ts (describe('collectLiveProcessIds — the boot-spawn set')) and rehydrate.renderer.test.ts.
Worth knowing for anyone reading this later: this is also the root cause of #1031 item 1 — the phone lists only agents with a running process, and boot now starts one. Fixing the boot storm created that.
Activity
Juliusolsson05 commentedon Sep 20, 2026
Fixed on main and never closed — by a stronger mechanism than the one proposed, which is worth recording because the issue's own wording no longer describes the code.
The unbounded
Promise.allover every tile leaf is gone.rehydrate.ts:597-599filters the spawn set throughliveProcessIds, andcollectLiveProcessIds(sessionOwnership.ts:117-131) returns the focused lane's occupant and nothing else. So "active tab's visible panes first, then bounded concurrency ~3" is superseded by "exactly one at boot", and "background tabs recovered lazily on first reveal" is met literally — every other session wakes on first send, on lane placement, or on terminal mount.The readiness half is
b83ff9cc(Fixes #772,Refs #774): a wake timeout with a live backend now resolves and journalswake.result code:'ready-timeout'instead of killing, so thekill.request cause=live-entryin this issue's evidence cannot recur.Tests:
sessionOwnership.test.ts(describe('collectLiveProcessIds — the boot-spawn set')) andrehydrate.renderer.test.ts.Worth knowing for anyone reading this later: this is also the root cause of #1031 item 1 — the phone lists only agents with a running process, and boot now starts one. Fixing the boot storm created that.