Hermes TUI benchmark — Ink (ui-tui) vs OpenTUI (ui-opentui)

61 result files · sha 50e34713b · node v26.3.0 · generated 2026-06-10T22:39:01.273Z
Methodology: docs/plans/opentui-bench-suite.md. Real binaries over a real node-pty PTY (120×40, xterm-256color), fake gateway via HERMES_PYTHON (zero UI changes), external /proc sampling on 100-msg boundaries, 2GB cgroup-v2 caps via systemd-run --user --scope. Median±IQR throughout; instrumented node-count runs are flagged and never headlined.

Determinism gate

configreplay digestsgate
ink7775bee02e57da2b · 7775bee02e57da2bPASS
otui-cappedd5e9558583159eac · d5e9558583159eacPASS

Headline: RSS vs messages

RSS vs fixture messages (clean memory runs, all reps + slope runs) 0 1667 3333 5000 6667 8333 10000 0 464 929 1393 1858 2322 fixture messages (rowsPerTurn accounting) RSS (MB) cap 2048 MB otui-capped otui-uncapped ink × crash @3000 × crash @3000 × crash @3000 × crash @2901 × crash @3000 × crash @3000 × crash @3000 2GB cgroup cap (systemd-run, MemorySwapMax=0). × = cgroup OOM kill. Samples every 100 msgs from /proc/PID/smaps_rollup.

Result matrix (median ± IQR)

configslope MB/1k msgs
(3000-msg runs)
slope MB/1k
(10k run)
plateau RSS MB
(final quartile)
VmHWM MBscroll p50/p90/p99 msCPU ms/event
(paced)
cap hits (2GB)
ink 25.48 [23.89–27.74] 5.88 249 [247–250] 257 [256–258] 2.0 / 36.1 / 98.5 31.04 [30.99–31.23] none
otui-capped 254.74 [250.81–265.46] not run 767 [741–799] 875 [868–879] 2.0 / 3.0 / 17.0 30.00 [30.00–30.05] none
otui-uncapped 297.65 [283.88–311.91] 173.76 807 [796–813] 890 [874–893] 2.0 / 3.0 / 14.0 30.09 [30.09–30.10] none

Mechanism: mounted node count (instrumented)

Mounted node count vs messages (instrumented runs — mechanism witness, never headlined) 0 500 1000 1500 2000 2500 3000 0 84 169 253 337 421 fixture messages live nodes ink live yoga nodes (fd-3 sampler) instrumented:true. Ink: HERMES_TUI_MEMSAMPLE_FD walk of the forked reconciler root. OpenTUI: scripts/mem-bench.tsx renderable walk (headless, diagnostic-only).

Scroll latency

Scroll latency CDF — SGR wheel 30Hz×15s on 2000-msg transcript (all reps pooled) 0 19 37 56 74 93 111 0 20 40 60 80 100 write → first output byte (ms) percentile (%) ink (n=1350) otui-capped (n=1350) otui-uncapped (n=1350) Latency = PTY write of the wheel event to the next PTY output chunk.

Startup

Startup (fake gateway) — median of 10 reps, whiskers = IQR 0.0 46.5 92.9 139 186 232 ms from spawn 66.5 first byte 202 session.create ink 127 first byte 176 session.create otui-capped first byte = first PTY output; session.create = the UI reaches its session bootstrap RPC.

Streaming CPU / PTY throughput

Paced streaming (30 ev/s): PTY output rate + CPU per event — median±IQR over reps 0.0 13.6 27.2 40.7 54.3 67.9 KiB/s · ms/event 58.7 PTY KiB/s 30.1 CPU ms/event otui-uncapped 58.9 PTY KiB/s 30.0 CPU ms/event otui-capped 44.0 PTY KiB/s 31.0 CPU ms/event ink CPU from /proc/PID/stat utime+stime deltas across the stream window (UI process only).

E3 survival (memory-constrained Docker)

cellconfiglimitresultmsgs survivedVmHWMbasis
e3lite-1gink1073741824 completed10000 223 MB
e3lite-1gotui-capped1073741824 died3000 849 MB

Run health

⚠ drain assertion violations (runs kept, flagged):

runmax loop lagviolations >10ms
2026-06-10T2058-50e3471-mem3000-opentui-otui-capped-r0.json18 ms2
2026-06-10T2058-50e3471-mem3000-opentui-otui-uncapped-r0.json22 ms3
2026-06-10T2059-14ee1a5-mem3000-opentui-otui-uncapped-r1.json33 ms3
2026-06-10T2100-197d499-mem3000-opentui-otui-capped-r2.json22 ms3
2026-06-10T2100-197d499-mem3000-opentui-otui-uncapped-r2.json19 ms2
2026-06-10T2107-197d499-cpu800-opentui-otui-uncapped-r0.json11 ms1
2026-06-10T2108-197d499-cpu800-opentui-otui-capped-r0.json15 ms1
2026-06-10T2116-197d499-cpu800-opentui-otui-capped-r1.json11 ms1
2026-06-10T2124-197d499-scroll2000-opentui-otui-capped-r0.json15 ms2
2026-06-10T2125-197d499-scroll2000-opentui-otui-uncapped-r0.json26 ms2
2026-06-10T2126-197d499-scroll2000-opentui-otui-capped-r1.json23 ms2
2026-06-10T2126-197d499-scroll2000-opentui-otui-uncapped-r1.json21 ms2
2026-06-10T2127-197d499-scroll2000-opentui-otui-uncapped-r2.json15 ms2
2026-06-10T2128-197d499-scroll2000-opentui-otui-capped-r2.json20 ms2
2026-06-10T2146-197d499-slope10000-opentui-otui-uncapped-r0.json25 ms4
2026-06-10T2147-e3-e3lite-1g-opentui-otui-capped-r0.json14 ms3
2026-06-10T2236-a939c9a-mem3000-opentui-otui-capped-r0.json24 ms4
2026-06-10T2237-a939c9a-mem3000-opentui-otui-uncapped-r0.json14 ms2
2026-06-10T2237-a939c9a-slope10000-opentui-otui-uncapped-r0.json69 ms17