We Benchmarked Ghostty, Herdr and Apple's Terminal and the Multiplexer Won
Herdr is not a terminal, it is a multiplexer that runs inside one. Across 181 runs it consumed 4.4MB of output in 0.059s, faster than the Ghostty window hosting it.
The WJS Desk
Sep 1, 2026 · updated 1 hour ago · 6 min read

Someone asked us to compare Ghostty, Herdr and the native macOS Terminal. We benchmarked all three on the same machine, and the first thing worth saying is that the question contains a category error, because Herdr is not a terminal. Homebrew's own one-line description gives it away: "Agent multiplexer that lives in your terminal."
The second thing worth saying is that the benchmark produced a result we did not expect. Running Herdr inside Ghostty was faster than running Ghostty alone, while tmux in the same position cost Ghostty its entire advantage over the terminal Apple ships.
What each of these actually is
Two of the three are terminal emulators: programs that own a window, draw glyphs and talk to a pty. Herdr is the layer above, a persistent server that owns your shell sessions and renders them into whichever emulator you already run.
| Ghostty | Terminal.app | Herdr | |
|---|---|---|---|
| Kind | Emulator | Emulator | Multiplexer, not an emulator |
| Stars | 60,533 | Closed source | 34,122 |
| First commit | March 2022 | Ships with macOS | March 2026 |
| Language | Zig | Objective-C | Rust |
| Licence | MIT | Proprietary | Apache-2.0 |
| Install size | 62 MB | 3.7 MB | 19 MB |
Herdr reaching 34,122 stars in five months is the number that made us look. Ghostty took three years to reach 60,533. Whatever Herdr is doing, people want it badly.
The benchmark
The classic terminal throughput test: how long does it take to consume a lot of output. We generated 50,000 lines of mixed-width text, 4.4 MB, and timed cat from inside each configuration with the page cache warmed. Each result is a median.
The floor first. Piping the same file to /dev/null, with no terminal rendering at all, takes 0.020 seconds. Everything above that is what the terminal stack costs you.
| Configuration | Runs | Fastest | Median | vs floor |
|---|---|---|---|---|
No terminal (/dev/null) | 3 | 0.019s | 0.020s | 1.0x |
| Herdr inside Ghostty | 181 | 0.056s | 0.059s | 2.9x |
| Ghostty alone | 6 | 0.065s | 0.068s | 3.4x |
| tmux inside Ghostty | 6 | 0.115s | 0.118s | 5.9x |
| Terminal.app alone | 6 | 0.110s | 0.128s | 6.4x |
Three findings, in order of how much they should change what you do.
Ghostty is roughly 1.9 times faster than Terminal.app. 0.068 against 0.128. Real, repeatable, and almost certainly invisible in daily use, because the difference on 4.4 MB of output is six hundredths of a second. It shows up when a build spews or you accidentally cat a binary.
tmux erases that advantage completely. tmux inside Ghostty lands at 0.118s, which is within noise of Terminal.app's 0.128s on its own. If you run Ghostty for speed and then run tmux inside it, you have paid 62 MB and a config file to arrive back where Apple's terminal already was.
Herdr is faster than the emulator hosting it. 0.059s against Ghostty's 0.068s, across 181 runs.
Why the multiplexer beats the terminal it runs in
That third result looks impossible until you think about who is blocked on what. When cat writes to Ghostty directly, the writing process is coupled to a terminal that is drawing every one of those 50,000 lines. When it writes into Herdr, it writes into a server that reads the pty into a scrollback buffer and renders only the viewport. The producer finishes as soon as the buffer has the bytes.
So Herdr is not rendering faster. It is declining to render 49,960 lines nobody will look at, and handing the writer its exit sooner. That is what a multiplexer is supposed to do, and tmux does it too, just much less efficiently: 0.118s against 0.059s means Herdr's Rust pipeline is twice as fast as tmux at the same job.
Herdr is not rendering faster than Ghostty. It is declining to render 49,960 lines nobody will read.
One detail we liked, found in Herdr's default config: its per-pane scrollback limit is 10,000,000 bytes, and the comment says it "matches Ghostty's default scrollback-limit behavior." Somebody checked.
Memory, where the numbers invert
Throughput is not the only budget, and Ghostty loses this one badly:
| Process | Idle RSS |
|---|---|
| Ghostty | 252 MB |
| Terminal.app | 119 MB |
| Herdr server | 19 MB |
| tmux | 4 MB |
Ghostty idles at more than twice Terminal.app and thirteen times the Herdr server. If you keep a lot of windows open, that is the trade you are making for the throughput. tmux at 4 MB is a reminder that a 919 KB C binary from 2015 still has something going for it.
What broke
Getting Herdr to run a scripted benchmark took four attempts, and each failure is a real thing about the tool.
HERDR_CONFIG_PATH pointing at a config with a custom default_shell did nothing. Herdr runs as a background server, and the already-running server owned the configuration; the environment variable on the client did not reach it. herdr server stop before launching did not fix it either.
herdr agent send-keys w1:p1 failed with agent_not_found. A pane running a plain shell is not an "agent" as far as the API is concerned, so the agent-oriented commands do not apply to it, even though herdr pane read happily returned that pane's contents. The CLI surface is genuinely large, with subcommands for panes, tabs, workspaces, worktrees and agents, and the split between them is not obvious from the help text.
What finally worked was overriding $SHELL before launching. Which surfaced the last surprise: Herdr respawns a pane's shell when it exits, so our benchmark ran on a loop and produced 181 samples before we noticed. Excellent for statistics, and a real behaviour to know about if you ever point a pane at a script rather than a shell.
The hidden cost is the always-on server. Herdr's persistence is the feature, and it means a background process holding your sessions, a socket API, and Homebrew offering to install a service at startup. That is the correct architecture for "agents keep working when you close the lid," and it is more moving parts than an emulator plus tmux. Budget for the fact that its config lives with the server, not with your shell.
What Herdr does not do
- It does not draw a window. You still need Ghostty, Terminal.app or something else underneath, and the emulator choice still decides your fonts, ligatures and GPU rendering.
- It does not replace your agent. It runs Claude Code, Codex, Cursor and the rest; it owns their terminals rather than wrapping them.
- Its agent-oriented API does not apply to ordinary shell panes, which is a gap you hit as soon as you script against it.
- Its configuration did not respond to
HERDR_CONFIG_PATHin our testing, so per-invocation config is not the escape hatch it looks like. - At 281 open issues on a five-month-old project, it is moving fast and not settled. There have been 84 releases.
So what should you actually run
The three things are not competing, and the honest answer has two parts.
Pick an emulator. Ghostty if you want the speed and can spare the memory, Terminal.app if you want zero install and 3.7 MB. On a modern Mac the throughput gap will not be the thing that slows you down, so this is mostly a question of whether you care about configurability. Ghostty at 60,533 stars and MIT is the safer long-term bet than a closed-source app Apple updates once a year.
Then decide whether you want a multiplexer at all. If you run coding agents that need to survive a closed lid, a dropped network or a reboot, that is precisely what Herdr was built for and there is no version of Ghostty that does it. If you just want splits and tabs, your emulator already has those and adding tmux will cost you half your throughput.
What would change our read: Herdr is five months old with 281 open issues, and a persistent server holding your sessions is a thing that has to be boring before it is trustworthy. Ask us again in a year. But on the numbers, the layer people assume is overhead was the fastest configuration we measured, and the one everybody already runs was the slowest.


