Measuring terminal latency
July 6, 2022
6 minute read
Table of Contents
Out of the six terminal apps I tested on macOS, kitty has the lowest input latency at 29.2ms. Terminal.app and WezTerm follow closely behind, and kitty has a small lead over Alacritty and iTerm2. When tuned, kitty is twice as fast as the latter two, and tied with Sublime Text.
I am using the Ayu theme for fish and Vim. When installing it, I found out that Terminal.app doesn’t support 24-bit color, which led me on a wild rabbit hole of discovery for a new terminal emulator that supported 24-bit color and didn’t suck.
I ended up with 3 emulators that I liked: WezTerm, iTerm2, and kitty. Unable to pick between them, I decided to benchmark their input latency to aid my decision-making, though I’m still not sure what to use. I’ll come back to that later in the post.
I used Is It Snappy? (IIS) for iOS to take slow-motion videos of the screen while pressing keys on my keyboard. I took 2-3 videos of each app and selected input/output markers in IIS. Some of the videos had some impossible delays, so I had filter out the bad ones and use the data that was closer to what I was expecting.
For example, Terminal.app showed a whopping 800ms delay during my first measurement, but later measurements were within a 10ms deviation of the result portrayed here. I think it’s because it was hard to see when the key was fully pressed.
When setting the output marker in IIS, I waited for the screen to completely finish drawing the typed character and the new position of the cursor, to account for input latency and pixel response time.
Because of these variables, and other things unique to my setup, this data is not accurate. It’s close enough for my use, but I encourage you to take your own measurements.
When setting things up for testing, I used the same setup I would use every day, which means custom fonts, themes, and editor plugins. I’m not trying to find the fastest vanilla terminal, I’m trying to find the best balance of performance and features.
I set the size of the terminals at 90x30 columns/rows, and I placed them as close to the vertical middle of the display as possible. Some of the terminals had custom fonts and icons loaded, such as Meslo in Terminal.app, and JetBrains Mono in the others. WezTerm has its own icon glyph set. I added Meslo as a backup font to iTerm2 to support all the icons my CLI apps use. Font ligatures are on by default in WezTerm, but disabled in iTerm2.
I tuned kitty’s performance and ran a separate test, labeled “kitty - unlimited”. These are the settings I used, from the docs:
# 150~ FPS for MBP display (untested) repaint_delay 8 # Remove artificial input delay input_delay 0 # turn off vsync sync_to_monitor no
The bulk of my time spent in the terminal is text editing, so each terminal in the test ran Vim. I also tested the graphical text editors I have installed, as I was curious to see if Vim could beat Sublime Text in input latency.
I’m running macOS 12.4 Monterey on a 2021 MacBook Pro with an M1 Pro CPU and 16GB of RAM. It sits in clamshell mode while hooked up to two 4k 60Hz monitors over USB-C DisplayPort. My keyboard is a HHKB Pro 2.
Estimated default latencies:
|Device||Input latency (ms)||Response time (ms)|
|HHKB Pro 2||20|
I have no way to verify the above numbers, they’re based on a couple sources online, links below. It takes 16ms to draw a full frame on a 4k 60hz display from top to bottom, and things in the exact vertical middle of the display update in 8ms.
I bypassed my USB hub and connected my keyboard directly to the MBP with no discernible difference in results.
- Terminal.app 2.12.7
- WezTerm 20220624
- Alacritty 0.10.1
- iTerm2 3.4.16
- kitty 0.25.2
- cool-retro-term - I threw this one in for kicks
- Sublime Text 4126
- VS Code 1.68.1
- Typora 1.3.7
- Vim 9.0
|kitty - unlimited||29.2|
|kitty - unlimited||29.2|
I’m impressed with how fast kitty is, it’s tied with Sublime Text on input latency while running Vim.
While kitty is the fastest, and I like a lot of its features, I’m leaning against using it because of the maintainer’s attitude towards tmux and other issues. Saying that people are “stagnating the terminal ecosystem” because they need tmux support is a bit much. And kitty doesn’t remember window position on macOS. The issues are one thing, but I have the impression that the issues won’t get fixed, attempts from other people to fix them will get denied, and new exciting issues might crop up later and receive the same treatment.
iTerm2’s GPU latency was something I was curious about, as most of the benchmarks I found made no mention of it. While it’s behind the rest of the pack, its features are strongly growing on me. It’s a lot more user friendly and works better on macOS than the others. The keyboard shortcut to restore a saved window layout is so good, Copy Mode is convenient, and there’s a minimum contrast setting for colors that I wish more terminals had. And there’s a visual drag-and-drop interface for panes so I don’t have to remember the arcane key combo on other terminals.
WezTerm was the first alternative I settled on – for a few days. It supports font ligatures and extra glyphs out of the box, which enables you to use any font you like. It supports panes, and has its own version of iTerm2’s Copy Mode. And it’s fast, scoring just behind kitty and on par with Terminal.app in my tests. It has trouble making some URLs clickable though, and you can’t use the mouse to drag out tabs into new windows like Terminal.app and iTerm2. Definitely one to keep an eye on.
Alacritty is meant to be used with a multiplexer like tmux for tabs and panes, and opening new windows means more Alacritty icons in your dock. Fonts are thick on macOS, and it seems the config setting to fix that has no effect. Latency in my tests was roughly 5ms less than iTerm2, so if given the false dilemma, I’d use iTerm2.
I’m going to use iTerm2 for a week and see how it goes. Here’s a pic of the family running VisiData: