Picking the best terminal for Linux usually comes down to somebody’s screenshot and a claim that their favourite is “blazing fast”. I wanted numbers, so I put fifteen terminal emulators on the same Ubuntu desktop and timed each one from launch to its first drawn frame, measured how much memory it holds at idle, and clocked how long it takes to push 16 MiB of text through a 100×30 window. A few results surprised me, and one of them has a two-second fix.
The list covers the GPU-rendered crowd (Ghostty, Kitty, Alacritty, WezTerm, Rio), the GTK and Qt terminals most distros ship (Ptyxis, GNOME Console, GNOME Terminal, Konsole, Tilix, Terminator), and the small old guard (foot, st, rxvt-unicode, xterm). Each one gets its measured numbers, what it is good at, and the install command we used, and Warp and Tabby got a first-launch look too. Every number came off one Ubuntu 26.04 desktop VM with GNOME 50 in October 2026, and when Ghostty 1.4.0 landed on the 27th we built it and reran its tests on the same host the next day.
Linux terminal benchmark results
foot is the fastest terminal emulator for Linux on both speed tests here: it drew its first frame in 39 ms and finished the 16 MiB dump in 168 ms, while idling at 6.9 MiB (only st used less). The surprise at the other end is Kitty, which needed 558 ms to open as Ubuntu ships it, then dropped to 199 ms once its Python bytecode was compiled (section 4 has the command). Sorted by first frame, lower is better in every column:
| Terminal | Renders with | First frame (ms) | Idle memory (MiB PSS) | cat 16 MiB (ms) | Tested build |
|---|---|---|---|---|---|
| foot | CPU (pixman), Wayland only | 39 | 6.9 | 168 | 1.25.0 |
| st | CPU (Xlib, XWayland) | 45 | 3.4 | 278 | 0.9.3 |
| rxvt-unicode | CPU (Xlib, XWayland) | 62 | 10.1 | 215 | 9.31 |
| Rio | GPU (wgpu) | 98 | 60.8 | 215 | 0.5.28 |
| Alacritty | GPU (OpenGL) | 100 | 39.0 | 256 | 0.16.1 |
| WezTerm | GPU (OpenGL) | 101 | 66.8 | 916 | nightly 20260929 |
| xterm | CPU (Xlib, XWayland) | 125 | 7.0 | 485 | 407 |
| Konsole | Qt | 136 | 40.7 | 477 | 25.12.3 |
| Tilix | VTE (GTK3) | 185 | 36.7 | 376 | 1.9.6 |
| Terminator | VTE (GTK3) | 263 | 36.8 | 296 | 2.1.5 |
| Ghostty | GPU (OpenGL over EGL, GTK4) | 308 | 78.9 | 195 | 1.4.0 |
| GNOME Console | VTE (GTK4) | 317 | 67.2 | 461 | 49.2 |
| GNOME Terminal | VTE (GTK3) | 322 | 25.3 | 325 | 3.58.0 |
| Ptyxis | VTE (GTK4) | 348 | 68.2 | 346 | 50.1 |
| Kitty (stock package) | GPU (OpenGL) | 558 | 88.0 | 212 | 0.45.0 |
| Kitty (bytecode compiled) | GPU (OpenGL) | 199 | 88.0 | 212 | 0.45.0 |
The same three measurements as a chart, best at the top of each panel:

Two patterns stand out. The GNOME terminals on VTE (Ptyxis, GNOME Console and GNOME Terminal) and Ghostty, which also builds its window with GTK4, all land between 308 and 348 ms to first frame, so toolkit startup sets the floor there, not the renderer. And throughput does not track the “GPU accelerated” label: the GPU terminals Ghostty, Kitty and Rio sit right behind foot, while WezTerm, also GPU-rendered, was the slowest at 916 ms. Ghostty only joined that front group with its 1.4 release, which cut its dump time from 542 ms to 195 ms on the same VM.
How I tested the terminals
Everything ran in one Ubuntu 26.04 LTS desktop VM on my Proxmox box: 4 vCPU on an 11th gen Core i7-1165G7, 8 GB of RAM, GNOME 50 on Wayland at 1280×800. GPU terminals need real OpenGL to be judged fairly, so the VM used VirGL, which hands OpenGL 4.3 calls through to the Iris Xe on the host instead of falling back to software rendering. That still adds a translation layer, so treat the GPU-terminal numbers as a ranking on this box, not as bare-metal figures. Each terminal ran its distro defaults (fonts, theme, scrollback) apart from the window size, which I forced to 100 columns by 30 rows and checked with stty size after every run. The Ghostty row comes from a rerun on October 28 with the 1.4.0 release on a fresh clone of the same VM and host, with the Ubuntu 1.3 package run alongside it as a control.
- First frame: a small GNOME Shell extension logs the moment the compositor receives the first frame of each new window. The number is the gap between forking the terminal and that log line, median of 20 launches after 3 warm-ups.
- Idle memory: the summed PSS from
/proc/<pid>/smaps_rollupof every process the terminal started (includinggnome-terminal-serverandptyxis-agent, excluding the shell inside), 10 seconds after launch, median of 3. I checked the method once againstsmem: 41.6 MiB from smaps_rollup against 41.5 MiB from smem for Alacritty. - Throughput:
catof a 16 MiB file of 96-character base64 lines, timed inside the terminal withdate +%s%N, median of the last 5 of 6 runs.
Why first frame and not the usual hyperfine 'alacritty -e true'? Because that one is misleading. I ran it too, plus a “time until the shell starts” probe, and the gap is big for some terminals:
| Terminal | Launch to shell running (ms) | hyperfine -e true (ms) | Launch to first frame (ms) |
|---|---|---|---|
| foot | 15 | 34 | 39 |
| WezTerm | 35 | 49 | 101 |
| Alacritty | 77 | 94 | 100 |
| GNOME Console | 154 | window stays open | 317 |
| GNOME Terminal | 290 | 62 (server already running) | 322 |
| Kitty (stock) | 651 | 721 | 558 |
WezTerm starts the shell long before it draws anything, so a shell-based timer flatters it by about 65 ms. In my check, foot true exited so fast that the compositor never logged a frame for it at all. The 62 ms for GNOME Terminal is the client handing a request to a gnome-terminal-server that is already running. With the server killed between runs, as in the first-frame column, it is 322 ms. The harness, the extension and every raw result file are in the lab notes I keep for each article, and the method lines up with what I used for the lightweight distro benchmarks.
1. foot: the fastest terminal emulator on Wayland
foot won every column except memory, where only st beat it: 39 ms to first frame, 6.9 MiB at idle and 168 ms for the 16 MiB dump. It is Wayland-only, renders on the CPU with pixman, and its server mode (foot --server plus footclient) makes new windows even cheaper. It has no tabs and no GUI settings; you edit ~/.config/foot/foot.ini and pair it with tmux for splits. On GNOME it draws its own title bar because Mutter has no server-side decorations, which is purely cosmetic.
The one thing that will throw you on first launch: the default font is 8 pt monospace, visibly smaller than every other terminal here.

foot is in the Ubuntu archive:
sudo apt install foot
If you are on X11 rather than Wayland, foot will not start at all, so look at st or rxvt-unicode instead.
2. Alacritty: fast, simple, cross-platform
Alacritty is the terminal I would recommend to someone who wants GPU rendering without a feature list to learn. It opened in 100 ms, held 39.0 MiB and cleared the dump in 256 ms, all near the top of the table, and it behaves the same on Linux, macOS and Windows with one TOML config file. Like foot, it leaves tabs and splits to tmux or your window manager. Vi mode, regex hints and live config reload cover most of what I want day to day.

Ubuntu ships a build that trails upstream by a release, which is fine for most people:
sudo apt install alacritty
The Alacritty install guide for Ubuntu covers building the current release with cargo and setting up the config file.
3. Ghostty: native feel with GPU rendering
Ghostty is the one most people are asking about, and it is a very good daily driver: real GTK4 tabs and splits, a sane default theme, the Kitty graphics protocol, and a config file that is mostly empty because the defaults are right. On the first pass it was not fast, with 533 ms for the dump on the packaged 1.3 build, which put it behind even the GTK4 VTE terminals. The 1.4 release changed that. On the same VM it pushed the 16 MiB file through in 195 ms, second only to foot, while first frame stayed at about 308 ms because the GTK4 window still sets that floor.
To keep the comparison honest we ran three builds side by side on a fresh clone of the same desktop VM: the Ubuntu package from the first pass, plus 1.3.1 and 1.4.0 built from the release tarballs with the same flags. The Ubuntu package came back within a few percent of its October 1 numbers (303 ms against 299 ms to first frame, 556 ms against 533 ms on the dump), so the new rows sit fairly next to the other fourteen terminals:
| Ghostty build | First frame (ms) | hyperfine -e true (ms) | Idle memory (MiB PSS) | cat 16 MiB (ms) |
|---|---|---|---|---|
| Ubuntu package (reports 1.3.0) | 303 | 390 | 67.4 | 556 |
| 1.3.1 from source | 310 | 397 | 72.6 | 542 |
| 1.4.0 from source | 308 | 387 | 78.9 | 195 |
The throughput jump is the real story. Our test is end to end, from cat starting to the last line drawn, and 1.4 did it 2.8 times faster than 1.3.1 on identical hardware. That fits what the Ghostty 1.4.0 release notes claim for the parser: plain ASCII went from 128 MB/s to 725 MB/s (5.7x) in their benchmarks, a 2.6 GB set of real asciinema recordings is processed about 25% faster, and resizing a terminal with 10,000 lines of scrollback is about 6x faster. Those three figures come from the vendor and we only reproduced the throughput side, but our number shows the parser work survives a real GTK window on Linux.
Idle memory went the other way. A fresh 1.4 window held 78.9 MiB against 72.6 MiB for the 1.3.1 build compiled the same way, and the render path is the obvious suspect. The 1.4 launch log prints an EGL vendor=Mesa Project line that 1.3.1 never did, because 1.4 now renders through EGL on its own thread and hands finished frames to GTK, where 1.3 drew inside the GTK OpenGL widget. The memory headline of the release is about scrollback, which 1.4 compresses while the terminal sits idle and claims cuts the physical memory of that history by 70% to 90% on macOS and 64-bit Linux. That is also why the default scrollback limit rose from 10 MB to 50 MB. We have not measured the compression ourselves yet, so treat the 70% to 90% as the figure Ghostty publishes. If you would rather keep the old behaviour, scrollback-compression = false in ~/.config/ghostty/config.ghostty turns it off.

Ubuntu 26.04 has Ghostty in universe, so the quickest install needs no third-party repo. That package is the 1.3 build, though:
sudo apt install ghostty
Ghostty does not ship Linux binaries itself, and the official install page lists the distro packages, including the COPR build Fedora users need. On October 28 the stable snap channel, the community Ubuntu PPA and the AppImage builds were all still on 1.3.1 (the trade-offs between those formats are in our Snap, Flatpak and AppImage comparison), so we built 1.4 from the release tarball. The build needs GTK 4.18 and libadwaita 1.7 or newer plus Zig 0.17. Ubuntu 26.04 ships GTK 4.22 and libadwaita 1.9, so it qualifies. Ubuntu 24.04 does not, and the release notes point those users to an older Ghostty instead. Start with the build dependencies:
sudo apt install build-essential pkg-config libgtk-4-dev libadwaita-1-dev gettext libxml2-utils blueprint-compiler libgtk4-layer-shell-dev xz-utils curl
Each Ghostty release pins a minimum Zig version in its build.zig.zon, and 1.4 wants 0.17.0, which no Ubuntu release packages. Grab the official tarball and put it on your PATH for this shell:
ZIG=0.17.0 # pin: minimum_zig_version for Ghostty 1.4, https://ziglang.org/download/
curl -LO https://ziglang.org/download/${ZIG}/zig-x86_64-linux-${ZIG}.tar.xz
sudo tar -xf zig-x86_64-linux-${ZIG}.tar.xz -C /opt
export PATH=/opt/zig-x86_64-linux-${ZIG}:$PATH
zig version
Before compiling, check your free memory. On the 8 GB VM the first build died about four minutes in, because the Zig compiler alone grew past 7 GiB and the kernel OOM killer stopped it. With an 8 GB swap file the same build finished in just under 7 minutes on 4 vCPUs. Skip this step on a machine with 16 GB or more. The commands below assume ext4, the Ubuntu default, because a fallocate swap file fails on btrfs:
sudo fallocate -l 8G /swapbuild
sudo chmod 600 /swapbuild
sudo mkswap /swapbuild
sudo swapon /swapbuild
Now fetch the release tarball and compile it. The prefix keeps the whole install under one directory in /opt, so removing it later is a single rm, and Zig downloads the remaining dependencies on the first run:
GHOSTTY=1.4.0 # pin: benchmarked release, https://ghostty.org/docs/install/release-notes/1-4-0
curl -LO https://release.files.ghostty.org/${GHOSTTY}/ghostty-${GHOSTTY}.tar.gz
tar -xzf ghostty-${GHOSTTY}.tar.gz
cd ghostty-${GHOSTTY}
sudo mkdir -p /opt/ghostty-${GHOSTTY}
sudo chown $USER /opt/ghostty-${GHOSTTY}
zig build --prefix /opt/ghostty-${GHOSTTY} -Doptimize=ReleaseFast
When it finishes, remove the swap file with sudo swapoff /swapbuild followed by sudo rm /swapbuild. The new defaults show that you have the 1.4 binary, since the scrollback limit is now 50 MB and compression has its own switch:
/opt/ghostty-1.4.0/bin/ghostty +show-config --default --docs=false | grep -i scrollback
For the same query the 1.3.1 build showed scrollback-limit = 10000000 plus the same palette line. In 1.4.0 that option is renamed scrollback-limit-bytes, and an existing scrollback-limit line in your config still works. Here is the 1.4.0 output:
scrollback-limit-bytes = 50000000
scrollback-limit-lines = unlimited
scrollback-compression = true
command-palette-entry = title:"Clear Screen",description:"Clear the screen and scrollback.",action:"clear_screen"
To start it from the GNOME launcher, point a desktop entry or a symlink at /opt/ghostty-1.4.0/bin/ghostty. One snag when scripting any Ghostty build: --window-height=30 gave me 27 rows on GNOME, and 33 gave the 30 I wanted.
4. Kitty: fast output, slow start until you fix it
Kitty pushed the 16 MiB file through in 212 ms, behind only foot and Ghostty 1.4, and it has the deepest feature set of anything here: tabs, splits with several layouts, its own image protocol, and “kittens” for things like SSH with shell integration and Unicode input. It also uses the most memory at 88.0 MiB. The startup number was the odd one. Stock Kitty from the Ubuntu archive took 558 ms to its first frame, slower than every GTK terminal.
I traced it. Kitty runs its Python code with optimization level 2, so it looks for .opt-2.pyc bytecode files, and the Ubuntu package only byte-compiles plain .pyc files at install. Every launch recompiles the modules in memory and tries, and fails, to cache them under /usr/lib/kitty and the Python standard library. Count the failed writes in one launch:
strace -f -r -e trace=openat,execve -o /tmp/k.trace kitty sh -c "sleep 0.5"
grep -c "opt-2.pyc.*EACCES" /tmp/k.trace
That came back with 135 permission-denied cache writes, 51 of them for modules Kitty ships and the rest Python standard library modules it imports:
135
Compiling them once as root fixes it:
sudo python3 -OO -m compileall -q /usr/lib/kitty
Re-running the 20-launch benchmark after that put the Kitty median first frame at 199 ms, down from 558 ms. A fresh trace still shows 31 cache misses, all in the Python standard library and none in Kitty itself. A package upgrade replaces the files under /usr/lib/kitty, so run the command again after Kitty updates. The Kitty install and config guide covers the config side once it opens quickly.

For the archive build:
sudo apt install kitty
Then run the compileall line above once.
5. WezTerm: a multiplexer in a terminal
The draw of WezTerm is everything it does besides drawing text: a built-in multiplexer with tabs, panes and workspaces that survive detaching, SSH domains that put remote panes in local tabs, and a Lua config you can program. It opened in 101 ms and idled at 66.8 MiB, but it was the slowest of all fifteen on throughput at 916 ms, almost twice the 485 ms of xterm in second-to-last place. If you live in long build logs, that is noticeable. If you use it as a tmux replacement, it is not.

The last tagged WezTerm release dates from February 2024, and the project Linux install page marks Ubuntu 24.04 and newer as “Nightly Only”, so I used the nightly from its APT repo. Add the repository key and source:
curl -fsSL https://apt.fury.io/wez/gpg.key | sudo gpg --yes --dearmor -o /usr/share/keyrings/wezterm-fury.gpg
echo 'deb [signed-by=/usr/share/keyrings/wezterm-fury.gpg] https://apt.fury.io/wez/ * *' | sudo tee /etc/apt/sources.list.d/wezterm.list
sudo chmod 644 /usr/share/keyrings/wezterm-fury.gpg
Then install the nightly package, which conflicts with the old stable one, so pick one:
sudo apt update
sudo apt install wezterm-nightly
The nightly is the build the project actively maintains, and the repo was still getting commits the week I tested.
6. Ptyxis: the default on Ubuntu and Fedora
If you installed Ubuntu 26.04 or Fedora Workstation recently, Ptyxis is already your terminal. On Ubuntu, ubuntu-desktop-minimal depends on it and the xdg-terminal-exec list points at org.gnome.Ptyxis.desktop; Fedora switched in Fedora 41. Its standout feature is container awareness: a new tab opens inside the same podman, Toolbx or Distrobox container as the current one, profiles can be tied to a container, and each tab can run in its own systemd scope. It took 348 ms to first frame and held 68.2 MiB, both at the heavy end, with a mid-pack 346 ms on throughput.

Nothing to install on Ubuntu 26.04 Desktop. On a minimal install or another flavour:
sudo apt install ptyxis
Its window size comes from the org.gnome.Ptyxis GSettings keys default-columns and default-rows, not a command-line flag, which matters if you script it.
7. Konsole: the KDE workhorse
Konsole was the quickest of the full-featured toolkit terminals at 136 ms to first frame, with 40.7 MiB at idle and 477 ms on throughput. It still has the most useful extras of the traditional crowd: split views, per-profile settings, SSH manager and quick commands plugins, and activity or silence monitoring on a tab. It looks at home on Plasma and a little out of place on GNOME, and pulling it onto a GNOME install drags in a chunk of KDE Frameworks.

Konsole is in the Ubuntu archive:
sudo apt install konsole
It is the default on Kubuntu and every Plasma spin, so most KDE users already have it.
8. GNOME Console and GNOME Terminal
GNOME Console (the kgx binary) is the stripped-down GTK4 terminal that GNOME ships as its own default: 317 ms to first frame, 67.2 MiB and 461 ms on throughput. It has tabs with an overview grid and very few preferences, which is the point. GNOME Terminal is the older GTK3 terminal that Ubuntu used for years. It still installs alongside Ptyxis on 26.04 and was the lightest VTE terminal I measured at 25.3 MiB, with 322 ms cold and 325 ms on throughput. Its profiles and keyboard shortcut editor are still more complete than Console’s.
Both are in the archive; this installs the pair:
sudo apt install gnome-console gnome-terminal
Both use the same VTE widget as Ptyxis, Tilix and Terminator, so escape-sequence support is the same across all five. The GTK4 builds (Ptyxis and Console) render through the GTK GSK layer, so font rendering can look slightly different from the GTK3 three.
9. Tilix: tiling in one window
Tilix splits a window into tiled panes with drag-and-drop rearranging, saves and restores layouts, and broadcasts typing to every pane, which is handy when I am patching three VMs at once. It opened in 185 ms, held 36.7 MiB and took 376 ms on throughput. The catch is maintenance: the last release is from November 2023 and the repository only sees occasional commits, so do not expect new features.
sudo apt install tilix
It still works fine on GNOME 50, and the broadcast-input feature is the reason people keep it around.
10. Terminator: splits for sysadmins
Terminator does the same split-and-broadcast job as Tilix and is still actively released. It is written in Python on GTK3, which shows in the 263 ms first frame, though memory (36.8 MiB) and throughput (296 ms) were respectable. Layouts live in a plain config file, and the grouping feature lets you broadcast to a subset of panes rather than all of them.
sudo apt install terminator
Installing it on Ubuntu also makes it the x-terminal-emulator alternative, so check that if other apps start opening Terminator.
11. Rio: the young GPU terminal
Rio is a Rust terminal on wgpu, the same rendering stack Firefox uses for WebGPU. It surprised me: 98 ms to first frame and 215 ms on throughput put it alongside Alacritty, with 60.8 MiB of memory. It has tabs and splits, and window size in its TOML config is set in pixels, not columns.

Rio is not in the Ubuntu archive (the rio package there is an unrelated program), so grab the Wayland .deb from the release page:
curl -fsSLO https://github.com/raphamorim/rio/releases/download/v0.5.28/rioterm_0.5.28_amd64_wayland.deb # pin: benchmarked build, https://github.com/raphamorim/rio/releases
sudo apt install ./rioterm_0.5.28_amd64_wayland.deb
There is a separate _x11.deb for X11 sessions, so pick the one that matches your desktop.
12. st, rxvt-unicode and xterm: the minimal X11 terminals
All three run through XWayland on a modern GNOME desktop, and they are still useful. st from suckless used the least memory of anything here at 3.4 MiB and opened in 45 ms. You configure it by editing config.h and recompiling, and Ubuntu packages it as stterm. rxvt-unicode took 62 ms, 10.1 MiB and 215 ms on throughput, the best throughput of the three, but it has not had a release since January 2023. xterm is the reference most other terminals test their escape-sequence support against. It is small at 7.0 MiB, though it was slow on throughput at 485 ms.
sudo apt install stterm rxvt-unicode xterm
These make sense on old hardware, in a bare window manager, or when you want a terminal that will still start when the GPU stack is broken.
Also tested: Warp and Tabby
Neither made the benchmark table, for the same reason: I could not drive them from a script. Warp has no flag to run a command at launch, and its first launch stops on a “Welcome to Warp” screen with a Get started button. Its client is open source under AGPL v3, and it is built around AI agents and block-based command history, so it suits a different buyer than everything above. Tabby is an Electron terminal with SSH and serial profiles built in. Its tabby run command never executed my probe script on a fresh install within 30 seconds, so I had no timings to compare.

Warp installs from the .deb on its download page, and Tabby from the .deb on its GitHub releases page.
Terminals dropped from the old list
Several Linux terminals that used to show up on lists like this are dead now. I checked each project page before cutting it:
| Terminal | Status | Use instead |
|---|---|---|
| eDEX-UI | Repository archived, last release October 2021 | Ghostty or Kitty with a theme |
| Termite | Archived 2021; its README says it is obsoleted by Alacritty | Alacritty |
| Aminal | Renamed Darktile, marked experimental and abandoned, last push March 2023 | Alacritty or Rio |
| Upterm | Archived, last release May 2018 | Warp |
| Hyper | No stable release since January 2023 (last canary July 2023) | Tabby |
| Terminus | Renamed to Tabby | Tabby |
Which Linux terminal should you use
The best terminal emulator depends on what you do in it, so here is one pick per job, each backed by a number from the table:
| If you want | Use | Because |
|---|---|---|
| The fastest, lightest terminal on Wayland | foot | 39 ms to first frame, 6.9 MiB, fastest throughput |
| GPU rendering with nothing to learn | Alacritty | 100 ms, 39.0 MiB, same config on Linux, macOS and Windows |
| Tabs, splits and a native GTK look | Ghostty | Best defaults of the feature-rich group; 195 ms on throughput since 1.4 |
| The most features and fast output | Kitty | 212 ms on throughput; compile its bytecode and it opens in 199 ms |
| A tmux replacement | WezTerm | Built-in multiplexer and SSH domains; slowest throughput at 916 ms |
| Toolbx and Distrobox work | Ptyxis | New tabs stay in your current container; already installed |
| Broadcast input to many panes | Terminator or Tilix | 263 ms vs 185 ms to first frame, but Terminator still ships releases |
| Old hardware or a bare window manager | st or rxvt-unicode | 3.4 MiB and 10.1 MiB at idle |
Whatever you pick, the terminal is half of it. A patched font from the Nerd Fonts install guide, a decent prompt from the shell prompt roundup, and tmux for sessions that survive a closed window change daily use more than 100 ms of startup.
Errors and quirks I hit while testing
None of these broke a terminal, but each one cost me time, so here they are with the exact text.
Kitty: “opt-2.pyc … = -1 EACCES (Permission denied)”
Lines like this appear 135 times in an strace of one Kitty launch (51 for modules Kitty ships), and they are the reason the Ubuntu package opens in over half a second. The full line for one module looks like this:
openat(AT_FDCWD, "/usr/bin/../lib/kitty/kitty/__pycache__/boss.cpython-314.opt-2.pyc.135542076417712", O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 0644) = -1 EACCES (Permission denied)
The fix is sudo python3 -OO -m compileall -q /usr/lib/kitty, covered in section 4.
foot: “compositor does not implement the XDG toplevel icon protocol”
foot prints this on every launch under GNOME, together with a second warning about decorations:
warn: wayland.c:1794: compositor does not implement the XDG toplevel icon protocol
warn: wayland.c:2061: no decoration manager available - using CSDs unconditionally
Both are warnings, not errors. Mutter does not offer server-side decorations, so foot draws its own title bar.
GNOME Console window stays open after the command exits
kgx -e true runs the command and then just sits there, so my timeout killed it after 15 seconds. Every other terminal here closes when the -e command finishes. Keep that in mind if you call GNOME Console from scripts or keybindings that expect the window to go away.
Tabby eats flags meant for your command
Running tabby run sh -c '...' does not pass -c to the shell. Tabby parses it as its own option, and its log shows the command already mangled:
info: CLI arguments received: {"argv":{"$0":"/opt/Tabby/tabby","_":["run"],"c":"sleep","command":["sh","4;","stty","size",">","/tmp/t"],"sandbox":false},"cwd":"/home/kibet/termlab","secondInstance":false}
Put the command in a script and pass the script path instead. Tabby also prints “Fontconfig warning: We will not regenerate the cache because some cache files were generated by a newer version” on Ubuntu 26.04, because it bundles an older fontconfig than the system copy, and that warning is harmless.
GPU terminals in a Proxmox VM render in software unless you enable VirGL
With the standard VGA display, glxinfo -B in the guest reports llvmpipe (LLVM 21.1.8, 256 bits) with “Accelerated: no”, so every GPU terminal renders on the CPU and its numbers mean nothing. The Proxmox virtio-gl display passes OpenGL through to the host GPU, but the host needs the GL libraries first. On the Proxmox node (9412 was my VM ID, use yours):
apt install -y libgl1 libegl1
qm set 9412 --vga virtio-gl,memory=256
After a cold start of the VM, glxinfo -B in the guest should show the host GPU behind virgl:
Device: virgl (Mesa Intel(R) Xe Graphics (TGL GT2)) (0x1010)
Version: 26.0.8
Accelerated: yes
The catch is that QEMU’s screendump stops working with VirGL (“no surface”), so I switched back to the standard display just for the screenshots in this article.
Ghostty build: “Out of memory: Killed process (zig)”
The first 1.4.0 build on the 8 GB VM stopped after about four minutes. We ran it as a background service, so the build log just ended without a Zig error, and in a terminal you would see the build killed instead of finishing. Either way, sudo dmesg | grep -i "out of memory" shows the reason: Out of memory: Killed process 73543 (zig) total-vm:7837896kB, anon-rss:7525320kB. The 1.3.1 build peaked at about 1 GiB on the same box, while the 1.4.0 build needed 7.0 GiB of resident memory, so a VM or laptop that built older releases fine can fail on this one. Add the swap file from the Ghostty section, or build on a machine with 16 GB, and the same command completes.