In-Band Terminal Multiplexing Considered Harmful
A consideration of why the reliability of a terminal environment is a decreasing function of the density of in-band multiplexers.
For a number of years I have been familiar with the observation that the reliability and responsiveness of a developer’s terminal environment is a decreasing function of the density of terminal multiplexers operating between their shell and their display. More recently I discovered why the use of an in-band multiplexer produces such disastrous architectural effects, and I became convinced that the terminal multiplexer nested inside a graphical terminal emulator should be abolished.
My first remark is that, although the developer’s activity ends when their environment is configured, the processes taking place across the communication channel are the true subject matter of the system. It is this dynamic process that must satisfy the desired specifications. Yet once commands are invoked, the rendering of the corresponding display is delegated to the host terminal emulator.
My second remark is that our computing abstractions function best when we maintain a trivial correspondence between the static spatial presentation (the rectangular window on a display) and the dynamic process (the asynchronous stream generated over a pseudoterminal). For that reason we should do (as wise developers aware of our limitations) our utmost to shorten the conceptual gap between the static spatial surface (spread out on a display) and the dynamic process (spread out in time), to make the correspondence between presentation and process as trivial as possible.
Let us now consider how we can characterize the state of a terminal session. In a well-structured terminal architecture, three independent coordinates define the system:
- The spatial coordinate: The geometry of rectangular surfaces, typography, font metrics, display scale factors, GPU rasterization, and operating system clipboards. This coordinate belongs to the host terminal emulator and the desktop window manager.
- The process coordinate: The lifecycle of the executing process, its file descriptors, and its persistence across network disconnects. This coordinate belongs to the operating system kernel and headless process daemons.
- The supervisory coordinate: The lifecycle state of background workloads (such as an autonomous task running, waiting for input, or complete). This coordinate belongs to inter-process communication protocols and desktop notification services.
The main point is that these coordinates are naturally orthogonal. They provide independent planes in which to reason about the state of our computing environment.
The unbridled use of in-band terminal multiplexers such as GNU Screen and tmux has as an immediate consequence that it destroys this independent coordinate system.
By forcing spatial window management into the byte stream of a pseudoterminal, the multiplexer inserts an entire virtual terminal emulator directly into the pipeline of the real terminal emulator. The resulting execution flow incurs severe structural damage.
First, every byte pays a double translation penalty. The executing program writes ANSI escape sequences to a pseudoterminal. The multiplexer parses this stream, updates an internal matrix of text cells, and synthesizes a second stream of escape sequences. The host terminal emulator then parses this synthetic stream a second time before delivering vertices to the GPU. Mitchell Hashimoto, creator of Ghostty, aptly compared this arrangement to running a Windows virtual machine inside macOS merely to launch an application.1 Every character cell undergoes duplicate parsing and memory synchronization, introducing latency and burning processor cycles.
Second, the intermediary emulator creates a semantic disconnect. When the multiplexer reconstructs the screen, it flattens rich terminal protocols into its own internal cell model. Modern terminal capabilities: OSC 8 hyperlinks, the Kitty graphics protocol, styled undercurls (SGR 4:3), 24-bit RGB color, and disambiguated keyboard protocols: are silently discarded or corrupted unless the multiplexer explicitly implements passthrough emulation.
Third, the multiplexer destroys input transparency. By intercepting keystrokes behind modal prefix keys (Ctrl-a, Ctrl-b), the multiplexer steals key events from interactive shells, command-line utilities, and text editors. Over years of maintaining tmux.conf, developer dotfiles accumulate defensive overrides solely to recover capabilities that the host terminal possessed natively:
# ~/.config/tmux/tmux.conf
# Force truecolor coordinates through the multiplexer
set -g default-terminal "tmux-256color"
set -ga terminal-overrides ",xterm-256color:Tc"
# Recover Kitty extended keyboard protocols
set -sas terminal-overrides ',xterm-kitty:_extkeys'
set -sas terminal-features 'xterm-kitty:extkeys'
# Work around broken operating system clipboard access
if-shell "type 'reattach-to-user-namespace' >/dev/null" \
"set -g default-command 'reattach-to-user-namespace -l /bin/zsh'"
The arrival of autonomous coding agents has triggered a modern resurgence of this construct. Tools such as Herdr present themselves as dedicated runtimes for AI agents, designed to supervise concurrent runs of tools like Claude Code, Codex, or OpenCode.2
Inspection of Herdr’s implementation confirms that it embraces the exact architecture of tmux. It allocates child pseudoterminals using portable-pty, parses escape sequences with a vendored copy of libghostty-vt, renders a tiled character matrix through ratatui and crossterm, and intercepts input behind a Ctrl+b prefix key. It incurs the same double parsing tax and inserts an intermediate terminal emulator directly between the agent and the host display.
Herdr’s defenders justify this middleman by pointing to attention management: the need to observe whether an agent is working, idle, or blocked on user confirmation. Yet supervising asynchronous text streams is an established problem. Decades ago, IRC bouncers like WeeChat and tmux activity monitors (monitor-activity, monitor-silence) tracked background conversations across hidden channels. Modern terminal emulators already expose urgency flags, tab badges, and OSC 9/777 desktop notification escape codes to surface background state to the operating system.
Packaging screen-scraping heuristics into an out-of-the-box binary offers undeniable distribution convenience for developers running multiple agents. Yet implementing that supervisor as an in-terminal display multiplexer resurrects the original architectural conflation. A user seeking an attention queue for background agents must once again surrender native window management, accept keybinding collisions, and insert an intermediary parser into their terminal stream.
The terminal multiplexer as an in-band display emulator is just too primitive; it is too much an invitation to make a mess of one’s terminal environment.
The proper remedy lies in restoring independent coordinates through a clean separation of concerns:
- Spatial presentation belongs to the host terminal emulator and the desktop environment. Tools like Kitty and Ghostty handle window geometry, splits, tabs, font rendering, and GPU rasterization with native performance and clean operating system integration.
- Process persistence belongs to a dedicated headless daemon. Preserving long-running processes across network disconnects requires managing background PTY sessions independently of display layouts. Tools like zmx (developed by neurosnap) demonstrate this separation.3 zmx maintains headless PTY sessions in the background and uses
libghosttyto snapshot and restore terminal state only when a client reattaches, completely avoiding window management, pane splits, or key prefix hijacking. - Attention management belongs to structured inter-process communication. Agent runtimes communicate their state through Unix sockets, desktop notifications, or native operating system consoles rather than parsing ASCII escape streams.
The distinction is essential: session durability and remote persistence represent legitimate operational needs, but implementing them via in-band terminal emulation remains an architectural mistake. A sound architecture unifies the terminal with a durable session layer (the approach pursued by Mitchell Hashimoto at Superlogical with Rex) or isolates persistence into a headless daemon (such as zmx). In either design, the nested in-band emulator is abolished.
It is hard to end this paper without a fair acknowledgement: am I to judge by whom my thinking has been influenced? It is obvious that I am indebted to Kovid Goyal, creator of Kitty, who documented terminal multiplexers as an architectural compromise and an impediment to performance and energy efficiency.4 I am equally indebted to Mitchell Hashimoto, creator of Ghostty, who identified the double-parsing tax and semantic disconnect imposed by intermediary emulators, and whose work at Superlogical demonstrates how to build durable sessions without in-band PTY compromises. Finally, I should record how neurosnap demonstrated that process persistence can be isolated into a minimalist daemon with zmx. The remark about the undesirability of in-band terminal multiplexers is far from new; it is time we accepted its architectural consequences.
References
- Kitty FAQ: I am using tmux/zellij and have a problem. Kovid Goyal on terminal multiplexer performance and complexity.
- Ghostty. Mitchell Hashimoto’s terminal emulator with native tabs and splits.
- Superlogical. Mitchell Hashimoto’s company building Rex, a unified native terminal and durable session layer.
- Herdr. Terminal workspace manager and runtime for AI coding agents.
- zmx. A minimalist terminal session manager by neurosnap focusing on session persistence.
- tmux. The terminal multiplexer repository.
Footnotes
-
Mitchell Hashimoto discussed the double parsing tax and architectural compromises of running multiplexers inside modern terminal emulators during discussions around Ghostty and Superlogical. ↩
-
Herdr vendors
libghostty-vtand allocates child PTYs withportable-ptyto draw an in-terminal agent workspace. See the Herdr repository. ↩ -
neurosnap details the design principles of headless session persistence and programmatic terminal access in the zmx repository and zmx documentation. ↩
-
Kovid Goyal outlines architectural objections to terminal multiplexers in the Kitty FAQ: I am using tmux/zellij and have a problem and kitty issue #391. ↩
This post was written with AI assistance.