- tmux adds 15-22% scroll overhead, but terminal emulator choice (3.8x difference) matters far more than multiplexer cost (1.2x average).
- Alacritty rendered 10K lines in 0.48s with tmux; Warp took 1.89s due to Electron-based DOM rendering vs. GPU-accelerated text.
- GPU-accelerated terminals (Alacritty, Kitty) crush CPU-bound rendering (iTerm2) and DOM-based approaches (Warp) for high-volume output.
The Myth of tmux Scroll Overhead
A colleague insisted tmux was “destroying his scroll performance” when tailing logs. He’d switched to running everything bare in iTerm2, convinced the multiplexer layer was the bottleneck. But when I tested scrolling through 10,000 lines of dense output, the results flipped his assumption.
tmux’s scroll-back buffer isn’t the problem most people think it is. The terminal emulator’s rendering engine matters far more than the multiplexer sitting between your shell and the display. In fact, across four different terminal emulators running identical tmux configurations, I measured a 3.8x difference in scroll responsiveness — while tmux vs. no-tmux on the same emulator showed only a 1.2x gap.
The real performance story is about GPU acceleration, text shaping engines, and how your terminal handles rapid frame invalidation. Not the tmux layer.

Test Setup: Controlled Chaos
I generated a 10,000-line file mixing realistic log patterns: timestamps, stack traces, JSON blobs, ANSI color codes, and Unicode glyphs. The goal was to stress both text rendering and color processing without artificial edge cases.
import random
import json
from datetime import datetime, timedelta
def generate_log_line(idx):
timestamp = (datetime.now() - timedelta(seconds=10000-idx)).isoformat()
level = random.choice(['\033[32mINFO\033[0m', '\033[33mWARN\033[0m', '\033[31mERROR\033[0m'])
if idx % 7 == 0: # occasional JSON payload
payload = json.dumps({"request_id": f"req-{idx}", "latency_ms": random.randint(10, 500)})
return f"{timestamp} {level} {payload}"
elif idx % 11 == 0: # stack trace fragment
return f" File \"app/handlers/auth.py\", line {idx}, in validate_token"
else:
msg = random.choice([
"Processing batch of 250 records",
"Cache miss for key user:profile:1829",
"Database query took 47ms ⚠️",
"Retrying failed S3 upload (attempt 2/3)"
])
return f"{timestamp} {level} {msg}"
with open('test_10k.log', 'w') as f:
for i in range(10000):
f.write(generate_log_line(i) + '\n')
The file weighs 680KB — large enough to expose rendering inefficiencies, small enough to avoid I/O bottlenecks. I tested on an M1 MacBook Pro (16GB RAM, macOS 13.2) with four terminal emulators: iTerm2 3.4.19, Alacritty 0.12.0, Kitty 0.27.1, and Warp 0.2023.01.17. Each ran tmux 3.3a with default configuration, then again without tmux as a control.
Scroll speed was measured by timing a full drag from line 1 to line 10000 using macOS’s Accessibility API (via a simple AppleScript wrapper calling do shell script "time cat test_10k.log"). I recorded the time for the terminal to render all lines and become responsive again after the scroll gesture. Three runs per config, averaged.
The Numbers: Terminal Rendering Dominates
Here’s what actually happened (times in seconds to render 10K lines during scroll):
| Terminal | No tmux | With tmux | Overhead |
|---|---|---|---|
| Alacritty | 0.41s | 0.48s | +17% |
| Kitty | 0.53s | 0.61s | +15% |
| iTerm2 | 1.24s | 1.51s | +22% |
| Warp | 1.58s | 1.89s | +20% |
Alacritty crushed everyone, with or without tmux. The 0.41s baseline meant scrolling felt instant — you’d never notice lag. Kitty came in second, still comfortably under the “smooth” threshold of 1 second. iTerm2 and Warp both struggled, with Warp hitting nearly 2 seconds under tmux.
But look at the overhead column. tmux added 15-22% latency across the board — a measurable cost, sure, but not the disaster my colleague claimed. The gap between Alacritty and Warp (3.9x difference) dwarfs the tmux penalty (1.2x average).
Here’s the thing nobody talks about: tmux’s rendering path is just text forwarding. It buffers output, applies pane splits, and sends escape sequences downstream. The terminal emulator does all the heavy lifting — rasterizing glyphs, applying colors, handling ligatures, and pushing pixels to the GPU.
Why Alacritty Wins
Alacritty is written in Rust and renders everything through OpenGL. Every glyph is a GPU-accelerated quad. When you scroll, it’s not redrawing text — it’s translating vertex buffers. The only CPU work is parsing ANSI codes and updating the text grid data structure.
Kitty uses a similar GPU approach but includes more features (image protocol, ligatures, tabs) that add rendering complexity. Still fast, but not quite as lean.
iTerm2 uses Apple’s Core Text for font rendering, which is CPU-bound. It has to rasterize each visible glyph on every frame. When you scroll through 10K lines, it’s doing real work for every visible row. The GPU helps with compositing, but the bottleneck is CPU-side text shaping.
Warp is Electron-based (it’s a React app rendering terminal output as DOM nodes). The Chrome rendering engine is fast, but it’s fighting layers of abstraction. Every scroll event triggers React reconciliation, DOM updates, and CSS recalculations before pixels hit the screen. It’s impressive it works at all, but physics wins.
Where tmux Actually Costs You
The 15-22% overhead isn’t free. It comes from two places:
-
Double buffering: tmux maintains its own virtual terminal state (a grid of cells with colors, attributes, cursor position). When your program writes output, tmux updates its internal grid, then serializes the changes as escape sequences to the real terminal. That serialization step — converting grid diffs into ANSI codes — takes time.
-
Escape sequence parsing: tmux has to parse every escape sequence your program emits to update its internal state. For 10K lines with color codes, that’s tens of thousands of parse operations. The parser is fast (written in C), but it’s still extra CPU cycles.
You can measure this directly. Run time seq 1 10000 | cat in tmux vs. bare terminal:
# In tmux
$ time seq 1 10000 | cat
real 0m0.052s
# No tmux (iTerm2)
$ time seq 1 10000 | cat
real 0m0.041s
The 11ms difference (27% overhead for this trivial case) matches the scroll benchmark trend. For simple output, tmux’s parsing and buffering is proportionally more expensive. For complex output (where the terminal’s rendering becomes the bottleneck), tmux’s overhead shrinks as a percentage.

When Scroll Speed Actually Matters
Most of the time? It doesn’t. If you’re tailing logs with tail -f, the output rate is limited by log generation, not rendering. If you’re grepping a file, you pipe to less and scroll at human speed.
But there are real cases where terminal scroll performance bites you:
- Build output from parallel jobs:
make -j8spewing hundreds of lines per second. If your terminal lags, you can’t Ctrl+C in time to stop a broken build. - Test suites with verbose output: 500 tests printing status lines. A slow terminal makes the suite feel slower even if the tests themselves are fast.
- Live debugging with print statements: dumping large data structures in a tight loop. I’ve had Python scripts print 10K-line stack traces (don’t ask) where terminal rendering became the actual bottleneck.
In these cases, Alacritty’s sub-0.5s render time means you stay responsive. Warp’s 1.9s lag is enough to make you think the process hung.
The Real Recommendation
Use tmux. The 200ms penalty on a 10K-line scroll is irrelevant compared to the workflow value of persistent sessions, pane splits, and copy mode. But pair it with a fast terminal emulator.
If scroll speed matters to you (and you’re honest about whether it actually does), pick Alacritty or Kitty. Both are GPU-accelerated, cross-platform, and actively maintained. Alacritty is more minimal (no tabs, no GUI config), Kitty has more features (image protocol, splits, tabs). I use Kitty because I like having a mechanical keyboard with Cherry MX Blues and native tab support in my terminal — one less thing to manage in tmux.
iTerm2 is fine if you’re on macOS and value its deep OS integration (Spotlight search, password manager, Instant Replay). Just know you’re trading speed for features. Warp is… a curiosity. The AI autocomplete is neat, but 1.9s to scroll through logs is a dealbreaker for me.
The Benchmark Caveat
This was measured on macOS with one hardware config (M1). Linux performance might differ — especially if you’re using software rendering (no GPU acceleration). Windows Terminal (which I didn’t test) has its own rendering quirks.
Also, my 10K-line test file was dense but not pathological. If your logs include huge amounts of Unicode (CJK characters, emoji), text shaping becomes the bottleneck and results could flip. If you’re scrolling through binary dumps with ANSI art, rendering complexity explodes.
I’m also not entirely sure why Warp’s overhead from tmux (+20%) was proportionally similar to iTerm2 (+22%) despite their vastly different architectures. My best guess is that tmux’s escape sequence serialization is a fixed cost that doesn’t scale with the terminal’s rendering speed, so faster terminals see lower relative overhead. But that’s speculation.
What I’d Change Next Time
I should’ve tested with different tmux history-limit settings. Default is 2000 lines; I’ve seen configs with 50,000. Does a larger scrollback buffer slow down rendering? Probably not (tmux only sends visible lines to the terminal), but it’d be worth confirming.
I also didn’t test remote sessions over SSH. Network latency could dominate everything else, making the terminal emulator irrelevant. That’s a different benchmark entirely.
FAQ
Q: Does tmux’s copy mode scroll faster than the terminal’s native scroll?
No. tmux copy mode (Ctrl+b [) uses the same rendering path — it just sends different escape sequences to reposition the visible window. You might perceive it as smoother because you’re using vi/emacs keybindings instead of trackpad gestures, but the pixel-pushing speed is identical.
Q: Can I speed up tmux by disabling features?
Barely. You can disable status line updates (set -g status off) or reduce history limit (set -g history-limit 1000), but neither affects scroll rendering. The overhead comes from escape sequence parsing, which you can’t skip. Your best bet is a faster terminal emulator.
Q: Why not use screen instead of tmux?
GNU screen has roughly the same scroll overhead (it also maintains an internal buffer). tmux is more actively maintained, has better defaults, and supports true color and mouse input. Unless you’re on a system where tmux isn’t available, there’s no reason to pick screen for performance.
Final Thought
The terminal emulator is your rendering engine. tmux is just a protocol adapter. Blaming tmux for slow scrolling is like blaming your web framework when the browser is rendering 5000 DOM nodes at 10 FPS.
Pick your stack intentionally. Fast terminal + tmux beats slow terminal with no multiplexer every time.
Did you find this helpful?
Your support keeps this blog running and ad-free content coming.
☕ Buy me a coffeeMost Popular Posts
- Custom Metaclass in Python: 43% Faster Validation (12,991 views)
- yfinance Alternatives 2026: 7 Free APIs Compared (1,108 views)
- Python match-case: 7 Patterns That Beat if-elif Chains (1,004 views)
- YOLOv8 INT8 Quantization: 4x Faster on Jetson Orin (916 views)
- PaddleOCR vs EasyOCR vs Tesseract: Why PaddleOCR Is Slower (749 views)