Performance across five setups

Thurbox still adds measurable cost over its raw backend. Attached idle CPU, typing latency, memory and RMUX transport behavior remain gaps; closing the interface brings idle CPU close to raw.

These Linux measurements pin 0b0611eb, after the hidden-output and snapshot fixes. They are a measured source snapshot, not a claim about every later release.

Read every metric, the stage-1 deltas, noise verdicts and ranked causes.

Resource cells show CPU / PSS memory in MiB. CPU is percent of one logical core, including short-lived host helpers; stand-in agents are excluded. 100% means one busy core, or 25% of this four-core machine. Codex echo includes the real agent; its memory has a separate whole-stack denominator.

Five-way Linux comparison; echo/switch cells use the specified quantiles; other cells are medians.
ScenarioThurbox (tmux)Thurbox (RMUX)Raw tmuxRaw RMUXHerdr
Codex eight-byte echo, p5077.21 ms78.80 ms33.73 ms32.91 ms36.34 ms
Codex eight-byte echo, p9579.38 ms80.28 ms45.21 ms44.64 ms39.54 ms
Idle key echo, p503.89 ms4.23 ms1.05 ms1.33 ms2.20 ms
One-session attach95.60 ms2391.19 ms10.52 ms12.68 ms224.47 ms
Session switch, p9542.67 ms2056.04 ms9.18 ms17.09 ms34.56 ms
20 idle sessions, UI open: CPU / PSS20.89% / 34.22 MiB25.63% / 49.04 MiB0.03% / 4.32 MiB0.11% / 14.16 MiB5.49% / 34.90 MiB
20 idle sessions, no UI: CPU / PSS0.03% / 7.59 MiB0.05% / 20.40 MiB0.00% / 2.55 MiB0.00% / 10.75 MiB5.74% / 29.99 MiB
20 idle sessions, UI open: received wakeups/s156.31267.290.0630.23135.91
Two-hour PSS growth, 20 sessions2.93 MiB2.72 MiB0.41 MiB0.00 MiB0.02 MiB

Where a gap remains

  • At twenty attached sessions, default foreground-process probes account for most host CPU. Hook-covered controls reduce it, but do not establish parity for agents without hooks.
  • RMUX conditional resize replies consume snapshot waiters, producing a two-second retry. Hidden output also loses correctly focused input: raw RMUX received ten inputs, the wrapper received none.
  • Codex median echo adds about 43–46 ms; renderer, keeper and backend processes add memory. Large-history search still exceeds its interactive budgets.

What was measured

Five measured repetitions follow a discarded warm-up for core scenarios and real Codex with mocked inference. Idle/wakeup, repaint and memory controls repeat independently three times. One, five and twenty sessions cover off-screen work; core creation/attach controls also include fifty sessions. The alternate-screen fixture models 30/60 Hz repaints rather than running Claude Code.

Every run waits for one-minute load below 1.0. The three two-hour growth cohorts activate all five setups concurrently after admission; their memory results do not provide quiet-host CPU or latency comparisons. A background agent remains running and is audited separately.

For each growth cohort, subtract median memory during seconds 900–1800 from median memory in its final 900 seconds. The comparison table uses the median of those three growth statistics. Concurrent wrappers share executable pages; PSS can change as page sharing changes, even when executable RSS is unchanged.

The burst contains 50,000 lines of 107 bytes: 5,350,000 payload bytes, excluding its twenty-byte end marker. Payload MiB/s divides those bytes by the producer duration and by 1,048,576. Visible completion separately waits for the end marker.

CPU is measured over sixty-five seconds with short-lived descendant accounting. PSS divides shared pages among processes; RSS counts resident mappings without that sharing correction. Geometry and history policies affect comparisons: default outer terminals are 200×50, and a separate 80×24 control does not equalize history retention.

Thurbox's chrome reduces the agent viewport within those outer dimensions. These are whole-host default comparisons; the geometry control does not isolate the cost of identical agent grids or identical scrollback policies.

The machine is a four-core Intel Core i5-6500T at 2.5 GHz, with 15.5 GiB RAM, NixOS 26.05, Linux 6.18.48 and a powersave governor. Tools are tmux 3.7c, RMUX 0.10.0, Herdr 0.9.3, Codex 0.157.1 and Python 3.14.7.

Noise is the larger observed full range of independent per-run statistics in a wrapped/raw pair, with explicit CPU resolution floors. It is not a confidence interval. Timeouts and confirmed transport failures take precedence; percentages with a zero raw denominator are undefined. Before/after deltas measure integrated source snapshots, not isolated fixes. Offline SSH was not exercised; changed packaging, scheduler instrumentation and the Herdr reference version also limit attribution.

Inspect your interface with F12 #

  1. Open Thurbox and press F12. A perf overlay and a ranked panes table appear. Press F12 again to close them. The HUD is on by default; if the key does nothing, set perf_hud = true under [features] in settings.toml in your Thurbox config directory. This setting applies when you save it.
  2. Leave the interface alone for several seconds. frames counts painted screens; skipped counts loop passes that avoided a paint. A slowly rising frame count and rising skips are normal at rest. renders counts pane render calls, and reused r/g shows reused pane trees and published groups. The frame, republ, and tick rows show median and maximum time for drawing, rebuilding shared data, and loop work. slow names a recent slow operation or pane.
  3. Read the panes table, ranked by total time. p95 is the 95th-percentile render time: 95 of 100 renders finish at or below it. share is the pane's portion of measured frame time, and rend/reuse separates renders from cache reuse. The costliest row is red; a ! marks a diagnostic hint. If a pane's render count keeps climbing while you are idle, read that hint and check whether the pane has a clock, animation, or changing data that calls for those renders.
  4. While the HUD is open, run thurbox-cli perf --plugins in another terminal for every loaded pane, longer names, handler and render times, cache reuse, and the hints in full. The TUI publishes a snapshot every few seconds while timing is active; the CLI reads the latest snapshot. Use --json for a script.

These counters diagnose your own interface. They are not the multiplexer benchmark above, and a busy pane can be doing useful work.