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(sessions): run session index and history loads off the main thread #769
sessionIndex.extractPrompts runs 64/min with max 380 ms and sessionIndex.search up to 5.6 s on the main thread when the palette opens; historyLoader.loadInitialChunk p95 0.9–1.2 s, max 4.6 s during rehydrate (PR #753 cuts the read to the tail but the parse still runs on main). Both are pure fs + parse with no Electron dependency.
Expected
Run them in a worker_threads worker (or the future session host), returning parsed entries via postMessage; main keeps the cache and the IPC handlers. Removes the 0.4–5.6 s stalls on palette open and boot.
Re-check on origin/main b3a2c481 before building anything (W2, quality loop).
What changed since this was filed:sessionIndex no longer exists; the conversations catalog replaced it. Transcript reads and parses still all run on the main process thread, though. Nothing uses worker_threads, and the three utilityProcess children don't touch transcripts. The heavy paths today:
historyLoader initial tail: 256 KiB blocks parsed synchronously, plus countNewlines over the whole file. The older-chunk marker fallback parses from byte 0.
promptFolder.extractPromptsFromFile: its window grows ×4 up to 16 MiB, and each window is one synchronous split plus parse.
Catalog search: up to 150 rows, and a cold row reads at least 256 KiB before the budget check.
The first claudeHistory refresh parses the whole ~/.claude/history.jsonl.
transcriptEngine.readStableTranscript reads the whole file for rewind, duplicate and switch.
What the owner's recordings say (~/.config/agent-code/performance-monitor/runs, all runs):
transcript.read: 2,436 samples, mean 178 ms. Only 3 slow-operation incidents (1.0 s, 1.3 s, 1.8 s).
14main-stall incidents, none within 10 s of a slow transcript.read. Main-stall incidents carry no operation attribution, so the recordings can't say what does stall main.
Two measurement defects:
Each IPC initial load emits twotranscript.read samples. One span ends at path resolution (result: 'delegated') before the read, which skews the percentiles low.
sessionIndex.extractPrompts, the catalog's prompt extraction and likely the largest synchronous parse, is not mapped into the monitor at all. Catalog search and indexing have no monitor operation.
Proposed order:
Measure first: fix the double sample, and map catalog extraction, search and index refresh into monitor operations.
Then move whichever path the data shows stalling main into a worker, with a build entry like performanceWorker and a verify-build-output update.
Moving historyLoader alone, as the issue asks, is not supported by the current recordings.
Activity
Juliusolsson05 commentedon Sep 27, 2026
Re-check on origin/main
b3a2c481before building anything (W2, quality loop).What changed since this was filed:
sessionIndexno longer exists; the conversations catalog replaced it. Transcript reads and parses still all run on the main process thread, though. Nothing usesworker_threads, and the threeutilityProcesschildren don't touch transcripts. The heavy paths today:historyLoaderinitial tail: 256 KiB blocks parsed synchronously, pluscountNewlinesover the whole file. The older-chunk marker fallback parses from byte 0.promptFolder.extractPromptsFromFile: its window grows ×4 up to 16 MiB, and each window is one synchronoussplitplus parse.claudeHistoryrefresh parses the whole~/.claude/history.jsonl.transcriptEngine.readStableTranscriptreads the whole file for rewind, duplicate and switch.What the owner's recordings say (
~/.config/agent-code/performance-monitor/runs, all runs):transcript.read: 2,436 samples, mean 178 ms. Only 3 slow-operation incidents (1.0 s, 1.3 s, 1.8 s).main-stallincidents, none within 10 s of a slowtranscript.read. Main-stall incidents carry no operation attribution, so the recordings can't say what does stall main.transcript.readsamples. One span ends at path resolution (result: 'delegated') before the read, which skews the percentiles low.sessionIndex.extractPrompts, the catalog's prompt extraction and likely the largest synchronous parse, is not mapped into the monitor at all. Catalog search and indexing have no monitor operation.Proposed order:
performanceWorkerand averify-build-outputupdate.Moving
historyLoaderalone, as the issue asks, is not supported by the current recordings.🤖 Generated with Claude Code
fix(performance): size histograms for every operation, close failed d…