Session Benchmark v4

v4: Performance profiling of session query, search, highlight, and cross-reference operations

iTerm Panes
1
JSONL Files
353
JSONL Total
628 MB
Trials/Op
5

Single Operations (5 trials each)

OperationWhat it measuresMedianMin–MaxStdevDistribution
session_tool list Full session listing: load YAML, query iTerm panes, read JSONL versions, detect quiescence via buffer reads, detect JSONL wait states — all in parallel 784ms 764–796 ±12 784ms (n=5)
session_tool cleanup Load sessions.yaml + it2api list-sessions, find entries whose iTerm pane is gone 403ms 401–416 ±6 403ms (n=5)
rg content search ripgrep counts of 'model' across -Users-tchklovski-all-code-rivus/ — the raw I/O cost of searching all session logs 56ms 53–355 ±134 56ms (n=5)
read 1 pane buffer Single it2api get-buffer call — reads terminal screen contents from one iTerm pane. ~300ms is Python process startup overhead 301ms 292–317 ±10 301ms (n=5)
tab color cycle (1 pane) Set tab_color → enable use_tab_color → disable use_tab_color on one pane. 3 sequential it2api calls 961ms 950–995 ±18 961ms (n=5)
highlight flow (1 panes) End-to-end: it2api list-sessions → set tab color on 1 panes → unset all. Simulates 'find + highlight' without rg search 1268ms 1261–1330 ±30 1268ms (n=5)
YAML ↔ iTerm cross-ref Load sessions.yaml + it2api list-sessions, then match registered sessions to live panes. Measures the minimum cost of 'are my sessions still alive?' 305ms 295–319 ±10 305ms (n=5)
find --state idle State-only filter: loads sessions.yaml + it2api list-sessions, filters by title state. No rg search, no JSONL reads — fastest possible find 407ms 405–422 ±7 407ms (n=5)
find 'model' Keyword search: checks badge+name (in-memory), then rg across all JSONL files for content matches. Ranks by badge(+10) > name(+8) > JSONL hits(+3-8) 778ms 766–871 ±42 778ms (n=5)
find 'benchmark' --all Keyword search including dead sessions (no live pane). Same as keyword search but doesn't skip sessions without iTerm panes — shows historical matches 794ms 766–826 ±22 794ms (n=5)

Find Command Performance

session find uses a 3-phase search: (1) metadata match — badge + name, (2) rg content search across JSONL, (3) parallel buffer reads for state enrichment. Phases are skipped when not needed (e.g., state-only queries skip rg entirely).

QueryGoalPhases UsedMin (ms)Median (ms)Max (ms)Bar
find --state idle Find all idle sessions metadata only 405 407 422 407ms
find 'model' 766 778 871 778ms
find 'benchmark' --all Search including dead sessions metadata + rg (all) 766 794 826 794ms

Find Query Anatomy

PhaseWhatCostWhen
1. MetadataLoad sessions.yaml + it2api list-sessions + hub badges~320msAlways
2. Contentrg across 620MB JSONL~60msOnly if query provided
3. EnrichParallel it2api get-buffer for alive matchesN × 320ms / threadsOnly if state filter or permission detection needed

With N panes: Phase 3 is the parallelism opportunity. Sequential: N × 320ms. ThreadPool(8): ceil(N/8) × 320ms. MCPretentious: N × 1.2ms.

Scenario1 pane5 panes15 panes
Sequential it2api320ms1,600ms4,800ms
ThreadPool(8)320ms320ms640ms
MCPretentious1ms6ms18ms

Parallelism Comparison (Sequential vs Concurrent)

OperationSequential (ms)Concurrent (ms)SpeedupVisual
buffer reads x1 298 306 0.97x
seq 298ms
conc 306ms
tab color x1 944 1052 0.90x
seq 944ms
conc 1052ms
rg x4 patterns 277 181 1.53x
seq 277ms
conc 181ms

session_tool list Breakdown (Why is it 14+ seconds?)

Each component of get_enriched_sessions() measured independently. The total explains the ~14s wall time of session_tool list.

ComponentMedian (ms)% of TotalWaterfall
claude --version 52 3.9% 52ms
it2api list-sessions 316 23.6% 316ms
JSONL rglob+version (1 session) 13 1.0% 13ms
JSONL rglob+version (43 sessions) 654 48.9% 654ms
it2api get-buffer x1 seq (all alive) 302 22.6% 302ms
Hub DB badge load 1 0.1% 1ms
JSONL wait state detect (1 session) 1 0.0% 1ms
SUM (estimated) 1339 100%

All Results (raw)

OperationCategoryMinMedianMeanMaxStdevTrials
session_tool list sequential 764 784 782 796 12 5
session_tool cleanup sequential 401 403 406 416 6 5
rg content search sequential 53 56 116 355 134 5
read 1 pane buffer sequential 292 301 303 317 10 5
tab color cycle (1 pane) sequential 950 961 966 995 18 5
highlight flow (1 panes) sequential 1261 1268 1285 1330 30 5
YAML ↔ iTerm cross-ref sequential 295 305 309 319 10 5
find --state idle sequential 405 407 410 422 7 5
find 'model' sequential 766 778 796 871 42 5
find 'benchmark' --all sequential 766 794 795 826 22 5
buffer reads x1 (sequential) sequential 288 298 298 306 8 5
buffer reads x1 (concurrent) concurrent 290 306 305 317 10 5
tab color x1 (sequential) sequential 937 944 966 1036 42 5
tab color x1 (concurrent) concurrent 940 1052 1077 1328 151 5
rg x4 patterns (sequential) sequential 206 277 321 624 173 5
rg x4 patterns (concurrent) concurrent 166 181 188 212 22 5

Optimization Roadmap

Current Bottleneck: it2api subprocess overhead (~300ms/call)

Each it2api call spawns a Python process. With 15+ alive panes needing buffer reads, that's 15 × 305ms = 4.5s just in process startup overhead.

Projected: session_tool list latency

ScenarioBuffer ReadsJSONL Versionlist-sessionsOtherTotalvs Current
Current (it2api, sequential) 302ms 654ms 316ms 62ms 1334ms baseline
+ ThreadPool parallelism 101ms 654ms 316ms 62ms 1132ms 1.2x
+ MCPretentious (255x buffer) 1ms 654ms 158ms 62ms 875ms 1.5x
+ direct JSONL path (no rglob) 1ms 50ms 158ms 62ms 271ms 5x

Action Items (by impact)

#ChangeSavesEffort
1 MCPretentious for get-buffer + send-text
Replace it2api subprocess calls in supervisor/adapters/iterm2.py with persistent WebSocket
~301ms (255x) medium
2 Direct JSONL path instead of rglob
JSONL_DIR / f"{sid}.jsonl" instead of rglob(f"{sid}.jsonl")
~604ms trivial
3 ThreadPool for remaining it2api calls
Parallelize badge/title/profile property calls that can't use MCPretentious
~201ms (if no MCP) easy
4 Cache claude --version
Version doesn't change within a session — cache for 5 min
~52ms trivial

Bottleneck Analysis

Primary bottleneck: it2api calls

Parallelism Gains (measured)

MCPretentious Gains (from evaluation)

Ranked by Latency (slowest first)

Generated: 2026-02-06 11:48:54