Performance

Fast because it does less.

Aizome only redraws what has changed, and its apps draw on the CPU into memory they share with the compositor, without starting OpenGL or Vulkan. An idle desktop draws about one frame a minute, and every part of the desktop has a budget of 4 ms to turn an event into a frame. This page has the measurements behind all that, taken on 2 November 2026 on a single desktop machine, comparing Aizome with GNOME, KDE Plasma and other programs people often use alongside it, including where Aizome loses. Each section links to its full write-up, with the raw data and how to repeat the test.

  • 19 msfor an Aizome app's window to appear, with its content following, where GNOME's and KDE's apps took 66–201 ms as Sekka sets them up (apps)
  • +221 MiBof RAM for the whole desktop in a small VM, against +567 for GNOME and +875 for Plasma as Sekka sets them up (desktops)
  • 1 framedrawn in a minute by an idle desktop, for the menu bar's clock (idle)
  • 0.48×PDFium's time for Shiori's renderer to draw the same 1,179 test pages, and 0.78× on real documents (PDF)

The whole desktop

In a small virtual machine, Aizome boots and logs in faster than GNOME or Plasma, uses much less memory, and gets keystrokes on screen sooner.

We installed the same Sekka system three times, changing only which desktop the installer picked, plus a fourth copy with no desktop at all to show what the base system uses. Each one ran in a virtual machine with 2 CPUs, 4 GiB of RAM and no 3D acceleration, so all three desktops render on the CPU, much like they would in most VMs and cloud desktops. We booted each one three times, taking turns, and timed both the boot and the login. After two minutes at idle, a small probe window measured how long keystrokes took to reach the screen at 75 Hz, with and without two threads keeping the CPU busy. Last, we launched each desktop's own apps, cold and warm.

Memory used by the desktop itself, MiB (lower is better)
Aizome: 221 MiB (591 MiB in use with the desktop up, 370 with none; +206 MiB in a 2 GiB VM)Aizome221GNOME: 567 MiB (937 MiB in use; +560 MiB at 2 GiB)GNOME567KDE Plasma: 875 MiB (1,245 MiB in use, Akonadi's database among it; +842 MiB at 2 GiB)KDE Plasma875

Memory in use 190 s after login, minus the 370 MiB the system uses with no desktop. Median of three boots at 4 GiB, each desktop as Sekka sets it up.

The numbers
MiBNotes
Aizome221591 MiB in use with the desktop up, 370 with none; +206 MiB in a 2 GiB VM
GNOME567937 MiB in use; +560 MiB at 2 GiB
KDE Plasma8751,245 MiB in use, Akonadi's database among it; +842 MiB at 2 GiB
Keystroke to screen with the CPU busy, median, in frames (lower is better)
Aizome: 0.53 frames (7.0 ms at the median, 13.5 at the 99th percentile (1.02 frames))Aizome0.53GNOME: 0.97 frames (13.0 ms, 23.6 at the 99th (1.77 frames); one press took 55 ms)GNOME0.97KDE Plasma: 1.01 frames (13.5 ms, 26.2 at the 99th (1.97 frames); 11.3 ms after each run's first seconds, against Aizome's 7.4)KDE Plasma1.01

220 key presses per boot, sent through a virtual keyboard to a probe window and timed until the frame was presented. At 75 Hz, a frame is 13.3 ms.

The numbers
framesNotes
Aizome0.537.0 ms at the median, 13.5 at the 99th percentile (1.02 frames)
GNOME0.9713.0 ms, 23.6 at the 99th (1.77 frames); one press took 55 ms
KDE Plasma1.0113.5 ms, 26.2 at the 99th (1.97 frames); 11.3 ms after each run's first seconds, against Aizome's 7.4
Boot to a ready login screen, s (lower is better)
Aizome: 6.4 s (to its own login screen, settled; the bare system reaches its console in 5.1)Aizome6.4GNOME: 7.6 s (to GDM, settled)GNOME7.6KDE Plasma: 8.6 s (to Plasma Login, settled)KDE Plasma8.6

From the moment the VM starts until the screen has stopped changing for three seconds.

The numbers
sNotes
Aizome6.4to its own login screen, settled; the bare system reaches its console in 5.1
GNOME7.6to GDM, settled
KDE Plasma8.6to Plasma Login, settled
Login, from pressing Enter to a settled desktop, s (lower is better)
Aizome: 1.2 s (Enter to the desktop settled)Aizome1.2GNOME: 2.0 s (Enter to the overview settled)GNOME2.0KDE Plasma: 5.2 s (Enter to the desktop settled)KDE Plasma5.2

A returning user's password login. First-run windows were dismissed once, in a setup boot before the measured ones.

The numbers
sNotes
Aizome1.2Enter to the desktop settled
GNOME2.0Enter to the overview settled
KDE Plasma5.2Enter to the desktop settled

Part of the memory gap is services that come with how each desktop is set up rather than with the desktop itself. In Plasma, NixOS's module turns on Akonadi, KDE's mail and calendar store, with its MariaDB database, and the session also starts Baloo, KDE's file indexer: about 230 MiB together. GNOME starts calendar and search services and an input method that a distribution could leave out. Without those, the desktops still need about 255 MiB (GNOME) and 410 MiB (Plasma) more than Aizome, and the largest part of that is the compositor and shell. GNOME's figure also includes about 79 MiB for Sekka's large 4928 × 3264 wallpaper, which GNOME Shell keeps at full size, in RAM here since the VM has no GPU.

A keystroke reached the screen sooner in Aizome because its compositor draws a window's update as soon as it arrives. Mutter, GNOME's compositor, holds each update until a few milliseconds before the next refresh, so under load almost half of the key presses waited a whole refresh longer. Plasma's median includes the first 6 to 15 seconds of every run, when each key press was a refresh late; after that, under load, it took 11.3 ms against Aizome's 7.4.

Each desktop's own apps, medians of three boots, timed from launch until the window stops changing. Cold is the first launch after boot and warm the next one. About 0.11 s is the fastest this harness can time, and most of Aizome's apps are at that floor. GNOME's photo viewer shows the photo at about 1.4 s, and its time runs to 3.19 s because its on-screen controls fade out then. Memory is PSS on the warm launch.
AizomeGNOMEKDE Plasma
Terminal, files, settings, editor, PDF and calculator (Plasma has none here), cold, s0.11–0.170.47–0.820.27–1.27
The same, warm, s0.11–0.170.47–0.790.27–1.22
Photo viewer, a 6000 × 3375 JPEG, cold and warm, s0.323.19 (photo at 1.4)0.58
Those apps' memory, MiB15–57143–25334–177
The photo viewer's memory, MiB326436166

Under load, a window drawing on every frame lost 0.84% of its frames in GNOME and 0.09% in one of Plasma's three runs. Aizome didn't lose any.

Not everything went Aizome's way. In this VM its shell woke about 47 times a second while idle (53 in the headless session measured further down), more than all of GNOME put together, though its CPU time at idle was as low as the others'. Hotaru, Aizome's terminal, took more memory than Konsole, KDE's terminal (57 MiB with its fish shell, against 37 MiB with bash). Shashin, Aizome's image viewer, held twice as much memory as Gwenview, KDE's image viewer, and Aizome's installed system (8.5 GB) is no smaller than GNOME's. With only 2 GiB of RAM, all three still boot and log in fine, and each desktop uses about as much memory as it did with 4 GiB. These numbers come from a VM rendering on the CPU, and on real graphics hardware all three desktops would behave differently. Full results, the VM setup and how it was measured. Where each desktop's memory and time go.

Apps

Aizome's apps put their window on screen in about 19 ms, whatever they're opening. The content follows.

We put Aizome's apps up against the GNOME and KDE apps that do the same jobs, six runs each, all outside their own desktops in the same neutral compositor (sway) on the processor's built-in Radeon graphics. The document apps all opened the same files, a 6000 × 4000 photo, the 756-page PDF specification and a folder of 2,000 files. GNOME's apps took 145–190 ms to show a window, and KDE's took 66–201 ms. Every Aizome app took about 19 ms, because the kit puts the window up first and does the decoding, parsing and reading on other threads. That's the time until the window appears, not until what's in it is ready. Shashin, Aizome's image viewer, is still decoding the photo when its window comes up, and Shiori, Aizome's PDF reader, draws its first page after its window is already showing. For time to a finished window, see the VM results above, where most of Aizome's apps had stopped changing by about 0.11 s and the photo viewer by 0.32 s.

Time from launch until the window appears, ms (lower is better), all on the same scale

Calculator
Soroban: 19.0 msSoroban19.0GNOME Calculator: 153 msGNOME Calculator153KCalc: 65.8 msKCalc65.8
Clock
Tokei: 19.2 msTokei19.2GNOME Clocks: 145 msGNOME Clocks145
Text editor, 2,514 lines
Sumi: 19.0 msSumi19.0GNOME Text Editor: 158 msGNOME Text Editor158KWrite: 107 msKWrite107
Images, a 6000 × 4000 JPEG
Shashin: 19.0 msShashin19.0Loupe: 153 msLoupe153Gwenview: 109 msGwenview109
PDF, 756 pages
Shiori: 19.2 msShiori19.2Papers: 149 msPapers149Okular: 186 msOkular186
Files, a folder of 2,000
Hako: 19.4 msHako19.4Files (Nautilus): 171 msFiles (Nautilus)171Dolphin: 114 msDolphin114
System monitor
Myaku: 18.9 msMyaku18.9GNOME System Monitor: 190 msGNOME System Monitor190Plasma System Monitor: 201 msPlasma System Monitor201
Disk usage
Kura: 19.2 msKura19.2Disk Usage Analyzer: 159 msDisk Usage Analyzer159Filelight: 164 msFilelight164
Medians of six runs. PSS counts shared memory once and splits it between the processes using it. Private memory is the part no other process shares. Wakeups are context switches per second over 15 seconds with nothing happening.
JobAppWindow appears, msPSS, MiBPrivate, MiBWakeups a second at rest
CalculatorSoroban19.014.351
GNOME Calculator15361.025.10
KCalc65.856.014.80.07
ClockTokei19.216.25.55
GNOME Clocks14559.324.20
Text editor, 2,514 linesSumi19.016.35.68.5
GNOME Text Editor15867.526.50
KWrite10777.921.312.0
Images, a 6000 × 4000 JPEGShashin19.01171051
Loupe15313628.00
Gwenview1091921330.07
PDF, 756 pagesShiori19.269.555.05.6
Papers14912987.70
Okular18615086.10.56
Files, a folder of 2,000Hako19.436.822.48.6
Files (Nautilus)17197.560.90
Dolphin11470.724.20.07
System monitorMyaku18.943.730.112.9
GNOME System Monitor19068.132.647.7
Plasma System Monitor20118789.9105
Disk usageKura19.215.55.30.98
Disk Usage Analyzer15944.322.75.7
Filelight16412950.50

The biggest single difference is that GTK 4 and Qt Quick start a GPU API before they draw anything, and Aizome's apps never do. After that come each toolkit's own set-up, such as parsing its theme's CSS, and loading and linking 100–200 shared libraries. Two things about this machine and Sekka's setup make the others slower than they'd be elsewhere. GTK's Vulkan loader loads every Vulkan driver installed here (14 of them, NVIDIA's among them) to ask what it offers, about 50 ms of GTK's time. And Sekka's session has every Qt app, KDE's included, load Qt's GTK 3 platform theme, which costs about 23–29 ms and 4.7 MiB at startup. Neither changes the order, but on another machine or setup the gaps would be smaller. Aizome's apps have room to get faster too, since 12 of the kit's 19 ms go to asking about every installed font at startup.

Memory mostly follows the same pattern. The one exception comes down to where the document is kept rather than the toolkit. Shashin holds the decoded photo (92 MiB of pixels) in its own memory, while Loupe, GNOME's image viewer, shares it with its sandboxed decoders and hands it off to the GPU. Counted by PSS, which splits shared memory between the processes using it, Shashin still uses the least. Where Aizome's apps fall behind is waking up while idle. Tokei, the clock, and Sumi, the text editor, are supposed to, since one shows seconds and the other blinks its cursor. But the wakeups in Hako, the file manager, and in Shiori are housekeeping timers, and six of GNOME's eight apps didn't wake at all. System monitors are always reading the system, and Myaku, Aizome's system monitor, checks every process every second. It used the most CPU doing it, about 23 ms per second compared with 18 for GNOME's monitor and 13 for Plasma's. Full results and how they were measured. Where each toolkit's startup time and memory go.

An idle desktop

Left alone, the whole desktop drew one frame a minute, and that was the clock turning over.

We started a headless Aizome session the way a login would (the compositor, its shell and xwayland-satellite, with a fresh user and default settings), let it settle, and then left it alone for a minute. We did that three times at 1920 × 1080 and three times at 3840 × 2160. According to the compositor's own statistics, in five of the six runs the only thing it drew was the menu bar clock changing. The sixth, at 1080p, drew four frames.

  • 1frame drawn in a minute at idle, the median at both 1080p and 4K
  • 0.19 msof compositor CPU time per second at idle
  • 172 MiBfor the whole session (PSS) at 1920 × 1080, and 193 MiB at 4K

We also looked at the test machine's own desktop while it was in use, driving a 3840 × 2160 display at 240 Hz, with our test tools writing into a terminal window the whole time. In the 4.8 hours after login it drew 146,990 frames, 8.5 a second out of a possible 240, because it only draws when something changes. Each frame took about half a millisecond of CPU time, and 99% took under 1.3 ms.

The shell still isn't completely quiet. It only does about a millisecond of work per second, but it wakes up around 53 times a second here (47 in the VM above, a different setup), mostly because its system-service watchers check for a stop request every 250 ms. That, and the way its memory grew over that long session, are covered under what it costs. The idle runs and how they were measured. The working session.

The compositor's frames

At 3840 × 2160, no frame took the compositor more than 3.2 ms of CPU time, and a still screen didn't need any frames at all.

The compositor comes with its own benchmark. It starts a headless compositor at 3840 × 2160 with 2× scaling, opens some test windows and runs through a set of scenarios, recording how much CPU time each frame takes from gathering the scene to submitting it. We ran it three times on each renderer, GLES on the Radeon, GLES on the RTX 5090, and pixman, the software fallback.

CPU time per frame in milliseconds, as median / 99th percentile, taking the median of three rounds. The single slowest frame in any run was 3.2 ms, the overview opening on the RTX 5090.
ScenarioGLES, RadeonGLES, RTX 5090pixman (software)
Idle, two seconds, three windowsno framesno framesno frames
Moving a window0.37 / 0.440.48 / 2.060.24 / 0.29
A client drawing every frame0.30 / 0.390.35 / 0.420.18 / 0.21
Switching Desks, sliding0.33 / 1.460.44 / 0.620.18 / 0.37
The overview opening and closing0.52 / 1.830.96 / 2.921.19 / 2.79
A window moving under a frosted menu0.54 / 0.660.75 / 2.330.38 / 0.45
A full-screen client drawing every frame0.25 / 0.340.13 / 0.391.33 / 1.46

Because only damaged areas get redrawn, moving a window just repaints the strips it leaves and the strips it moves into, and two seconds with nothing changing produced no frames at all. Software compositing actually uses less CPU than GLES until the whole screen changes. A full-screen client that redraws every frame costs pixman 1.3 ms per frame, compared with 0.1–0.3 ms for GLES, which is why Aizome composites on the GPU and keeps pixman as the fallback. Full results and how they were measured.

The 4 ms budget

Everything we timed fits within the 4 ms budget, at the median and at the 95th percentile.

Each app has its own tests that run it headlessly and time a frame all the way from the input event through updating, layout and drawing whatever changed, at 2× scale. That's the CPU time the 4 ms budget is meant to cover. We used release builds and ran each test alone on the machine.

CPU time per frame in milliseconds: the median, the 95th percentile and the slowest frame of each test.
InteractionMedian95thSlowest
Toggle a switch0.030.040.06
Type a character in a 2,000-line editor0.220.371.75
Scroll a 10,000-row list a notch0.120.160.30
The menu bar's clock ticking0.070.120.18
A window opening and closing (the shell)0.240.381.38
A key typed in the palette0.400.810.83
Typing in Sumi, the text editor0.380.470.81
Hako, the file manager: ↓ in a column of 10,000 files1.201.321.37
Hako: scrolling that column0.280.290.41
Myaku, the system monitor: a new reading of 600 processes2.262.582.69
Myaku: clicking a row0.190.254.36

The slowest regular case is Myaku, Aizome's system monitor, reading 600 processes, at 2.3 ms (2.6 ms at the 95th percentile). The single slowest frame was one of 30 clicks on Myaku's process list, which took 4.4 ms. The budget is judged at the 95th percentile, and these test timings are upper bounds. Full results and how they were measured.

Terminals

Hotaru, Aizome's terminal, starts faster than any of them. The latest Ghostty, a GPU-rendered terminal, reads output faster, and Hotaru shows keystrokes a frame later than the quickest terminals.

We compared Hotaru, Aizome's terminal emulator, with Ghostty, a fast GPU-rendered terminal, GNOME's two terminals (the older gnome-terminal and the newer Console), KDE's terminal Konsole, and foot, a minimal Wayland terminal. Each one ran in its own headless sway session on the Radeon at 60 Hz, using the same font and size, a 120 × 40 grid and a cursor that doesn't blink. The program running inside each terminal draws numbered marker rows, and a frame only counts once the captured screen shows the complete update. Every trial started on an idle machine, with the terminals taking turns.

Launch to first frame, ms (lower is better)
Hotaru: 49.6 ms (range 49.2–66.1 ms)Hotaru49.6Ghostty: 178 ms (range 177.7–193.9 ms)Ghostty178gnome-terminal: 130 ms (range 129.7–131.0 ms; includes the bus starting its server)gnome-terminal130Konsole: 130 ms (range 129.6–130.2 ms)Konsole130Console: 130 ms (range 130.0–146.3 ms)Console130foot: 65.7 ms (range 49.9–66.3 ms)foot65.7

Ten fresh launches each, with warm caches, timed until the first captured frame that shows the whole first screen.

The numbers
msNotes
Hotaru49.6range 49.2–66.1 ms
Ghostty178range 177.7–193.9 ms
gnome-terminal130range 129.7–131.0 ms; includes the bus starting its server
Konsole130range 129.6–130.2 ms
Console130range 130.0–146.3 ms
foot65.7range 49.9–66.3 ms
Keystroke to screen, median, ms (lower is better)
Hotaru: 26.8 ms (1.61 frames at 60 Hz; p99 35.6 ms)Hotaru26.8Ghostty: 30.0 ms (1.80 frames; p99 38.0 ms)Ghostty30.0gnome-terminal: 11.6 ms (0.70 frames; p99 20.2 ms)gnome-terminal11.6Konsole: 21.2 ms (1.27 frames; p99 29.9 ms)Konsole21.2Console: 11.6 ms (0.70 frames; p99 20.3 ms)Console11.6foot: 11.8 ms (0.71 frames; p99 20.1 ms)foot11.8

1,000 presses each. A virtual keyboard presses a key, the program responds by updating one cell, and the clock stops at the captured frame that shows the change.

The numbers
msNotes
Hotaru26.81.61 frames at 60 Hz; p99 35.6 ms
Ghostty30.01.80 frames; p99 38.0 ms
gnome-terminal11.60.70 frames; p99 20.2 ms
Konsole21.21.27 frames; p99 29.9 ms
Console11.60.70 frames; p99 20.3 ms
foot11.80.71 frames; p99 20.1 ms

Hotaru gets on screen one frame ahead of foot, the minimal terminal, and 80–128 ms ahead of everything else. It loses on typing latency. It shows each keystroke about a frame later than foot or GNOME's two terminals, which are both built on GNOME's VTE terminal widget. Input reaches the program in every terminal within a third of a millisecond, so Hotaru's extra frame is spent between the program's response and the frame on screen. Shorter follow-up runs put it in Hotaru's own path from the program's output to its frame, not in the toolkit: a plain text view built on the same toolkit shows a keystroke at the next frame, as GTK and Qt do.

For throughput, we first ran every terminal with no scrollback, as an earlier comparison of Hotaru's core with libghostty-vt, Ghostty's terminal library, had. Mitchell Hashimoto, Ghostty's author, reran that comparison and pointed out that with no scrollback libghostty-vt loses a lot of its optimizations, which is fair for the alternate screen that full-screen programs use but not for ordinary terminal use. He also found that Hotaru gets slower as its history grows, which a run without history hides. So that run favoured Hotaru twice over, and we measured everything again with history turned on. Ghostty kept its default of 50 MB and Hotaru got the same 50 MB. The other four only let you set history in lines, so each got 1,000,000 lines, the same as Hotaru's row limit and at least as much as Ghostty's 50 MB holds. We included both the Ghostty release Sekka ships (1.4.0) and Ghostty's main branch as of 2 November (0b1729e). These numbers are for each terminal app as a whole, running on screen, so reading the output, parsing it, keeping history and drawing frames all count. They aren't the speed of a VT parser on its own, and can't be compared directly with benchmarks of a terminal library such as libghostty-vt.

Plain text with history, MiB/s (higher is better)
Hotaru: 705 MiB/s (64 MiB in 91 ms; 2.8 J over idle)Hotaru705Ghostty 1.4.0: 720 MiB/s (89 ms; 3.4 J)Ghostty 1.4.0720Ghostty main: 794 MiB/s (81 ms; 2.9 J; built from 0b1729e)Ghostty main794gnome-terminal: 230 MiB/s (279 ms; 4.3 J)gnome-terminal230Konsole: 3.3 MiB/s (19.5 s; 376 J)Konsole3.3Console: 232 MiB/s (276 ms; 4.2 J)Console232foot: 146 MiB/s (439 ms; 5.4 J)foot146

64 MiB of ASCII text written into the terminal as fast as it can read it, six rounds each. History is 50 MB for Hotaru and Ghostty and 1,000,000 lines for the others. Energy is measured at the CPU socket, above idle.

The numbers
MiB/sNotes
Hotaru70564 MiB in 91 ms; 2.8 J over idle
Ghostty 1.4.072089 ms; 3.4 J
Ghostty main79481 ms; 2.9 J; built from 0b1729e
gnome-terminal230279 ms; 4.3 J
Konsole3.319.5 s; 376 J
Console232276 ms; 4.2 J
foot146439 ms; 5.4 J
Styled text with history, MiB/s (higher is better)
Hotaru: 301 MiB/s (213 ms; 4.8 J over idle)Hotaru301Ghostty 1.4.0: 271 MiB/s (236 ms; 5.6 J)Ghostty 1.4.0271Ghostty main: 346 MiB/s (185 ms; 5.6 J)Ghostty main346gnome-terminal: 156 MiB/s (411 ms; 6.2 J)gnome-terminal156Konsole: 0.7 MiB/s (95 s; 2,000 J)Konsole0.7Console: 163 MiB/s (393 ms; 6.2 J)Console163foot: 334 MiB/s (191 ms; 3.7 J)foot334

64 MiB of coloured, bold and underlined log lines.

The numbers
MiB/sNotes
Hotaru301213 ms; 4.8 J over idle
Ghostty 1.4.0271236 ms; 5.6 J
Ghostty main346185 ms; 5.6 J
gnome-terminal156411 ms; 6.2 J
Konsole0.795 s; 2,000 J
Console163393 ms; 6.2 J
foot334191 ms; 3.7 J
Unicode text with history, MiB/s (higher is better)
Hotaru: 165 MiB/s (389 ms; 7.4 J over idle)Hotaru165Ghostty 1.4.0: 72.0 MiB/s (893 ms; 16.8 J)Ghostty 1.4.072.0Ghostty main: 251 MiB/s (255 ms; 7.0 J)Ghostty main251gnome-terminal: 88.0 MiB/s (728 ms; 11.1 J)gnome-terminal88.0Konsole: 0.6 MiB/s (115 s; 2,112 J)Konsole0.6Console: 88.0 MiB/s (725 ms; 10.0 J)Console88.0foot: 151 MiB/s (423 ms; 6.2 J)foot151

64 MiB of CJK, accented letters and emoji.

The numbers
MiB/sNotes
Hotaru165389 ms; 7.4 J over idle
Ghostty 1.4.072.0893 ms; 16.8 J
Ghostty main251255 ms; 7.0 J
gnome-terminal88.0728 ms; 11.1 J
Konsole0.6115 s; 2,112 J
Console88.0725 ms; 10.0 J
foot151423 ms; 6.2 J
Cursor-heavy output with history, MiB/s (higher is better)
Hotaru: 126 MiB/s (507 ms; 9.6 J over idle)Hotaru126Ghostty 1.4.0: 22.0 MiB/s (2,886 ms; 36.7 J)Ghostty 1.4.022.0Ghostty main: 181 MiB/s (353 ms; 8.9 J)Ghostty main181gnome-terminal: 25.0 MiB/s (2,538 ms; 30.7 J)gnome-terminal25.0Konsole: 90.0 MiB/s (708 ms; 10.3 J)Konsole90.0Console: 24.0 MiB/s (2,620 ms; 27.0 J)Console24.0foot: 104 MiB/s (618 ms; 8.9 J)foot104

64 MiB of cursor movement, erasing and short writes, like what a full-screen program sends.

The numbers
MiB/sNotes
Hotaru126507 ms; 9.6 J over idle
Ghostty 1.4.022.02,886 ms; 36.7 J
Ghostty main181353 ms; 8.9 J
gnome-terminal25.02,538 ms; 30.7 J
Konsole90.0708 ms; 10.3 J
Console24.02,620 ms; 27.0 J
foot104618 ms; 8.9 J

With history, Ghostty's main branch is the fastest on all four kinds of output, and Hotaru manages 66–89% of its speed. Hotaru comes next on Unicode and cursor-heavy output, and third on plain and styled text, behind the two Ghostty builds and behind main and foot respectively. Against the 1.4.0 release, Hotaru is about even on plain text, a little ahead on styled text, and well ahead on Unicode and cursor-heavy output, both of which Ghostty has sped up since that release. History hit the others harder. GNOME's gnome-terminal and Console fell to about 230 MiB/s on plain text and 25 on cursor-heavy output, and foot to 146 on plain text. Konsole, KDE's terminal, keeps its 1,000,000 lines in a fixed-size history. It spent the whole flood busy on the CPU and managed 3.3 MiB/s or less on everything but cursor-heavy output. A million lines is far more history than most people keep (Konsole's default is 1,000), so the table below also has the first run, where no terminal kept any history.

How much memory a full history takes depends on where each terminal keeps it. The VTE-based terminals write theirs to compressed files on disk and held 38 and 69 MiB. Hotaru (94 MiB) and Ghostty (109 and 120 MiB) keep their 50 MB in memory, partly compressed, and Konsole and foot held 942 MiB and 1.5 GiB for their million uncompressed lines. Hotaru's own biggest drop was on plain text, from 1,047 MiB/s with no scrollback to 705 MiB/s with history.

The first run, with no scrollback in any terminal: MiB/s, medians of four rounds. Ghostty main wasn't in this run. Ghostty's author counts a run without scrollback fair for the alternate screen, which keeps no history, but for ordinary output it favours Hotaru over Ghostty. It's also here for the other terminals, whose million lines of history above are far more than they keep by default.
No scrollback, MiB/sHotaruGhostty 1.4.0gnome-terminalKonsoleConsolefoot
Plain text1,0471,01840774418441
Styled text34825821686256431
Unicode text18821519893193171
Cursor-heavy output1272289909599

The graphs in Ghostty's author's post show different gaps, and on plain text the opposite order. Two things account for most of it. He timed the terminal libraries alone, fed bytes with nothing drawn, where these runs time each app on screen. And Hotaru's feed-only mode keeps no history, so in his runs only Ghostty kept any, while here both kept 50 MB. Plain text is the output history slows Hotaru most, so with history on both sides Ghostty main is ahead on it. The builds are close: our Ghostty main is three commits after his, with one more fix for erasing blank rows, and our Hotaru includes a later change to how it reads from the program. Why Ghostty's lead on styled text is smaller here and on Unicode larger, we haven't measured. Drawing is the likeliest difference.

Ghostty main's speed as a multiple of Hotaru's. His run timed the VT libraries alone, with 50 MB of history for Ghostty and none for Hotaru. These runs timed whole terminals on screen, both with 50 MB.
Ghostty main ÷ HotaruHis library-level runThese app runs
Plain text0.78×1.13×
Styled text1.35×1.15×
Unicode text1.35×1.52×
Cursor-heavy output1.67×1.44×
Hyperlinks1.17×not measured

Sitting idle with a steady cursor, Hotaru wakes once a second. foot, gnome-terminal and Konsole don't wake at all, while Ghostty wakes 28 times a second and keeps the GPU busy for 4.3 ms of every second even though nothing changes. With default settings, Hotaru's cursor blinks forever, whereas GNOME's terminals stop blinking after ten seconds. At startup Hotaru uses 47 MiB of memory, about the same as Console and two thirds of what Konsole uses here, where Konsole runs outside Plasma and its libraries count in full. foot needs just 7. Hotaru's CPU-drawn buffers also cost the compositor more. Scrolling a row at 60 Hz cost sway 0.76 ms of CPU time per update with Hotaru, against 0.36 ms with Ghostty. Full results, the exact settings and how they were measured.

Media

Utsushi, Aizome's media player, is among the lowest-power players we tried, the lowest at 4K, and does the least work around each frame.

Utsushi decodes video on the GPU and hands each frame straight to the compositor, without copying it or drawing it a second time. We played the same clips for a minute at a time in Aizome's Utsushi, in mpv, a popular open-source player, and in VLC, the cross-platform media player, under Aizome's compositor on the Radeon. Each player ran at least three times, and we compared the CPU socket's power draw with idle readings taken in between. Every player ran full screen except mpv with its dmabuf output, whose full-screen option didn't take under Aizome, so it played in a window the size of the picture. A later run put it full screen, and its work was the same.

Extra power while playing a 1080p H.264 film, W (lower is better)
Utsushi: 0.20 W (VA-API decode, frames to the compositor as dmabufs)Utsushi0.20mpv → dmabuf: 0.42 W (--hwdec=vaapi --vo=dmabuf-wayland: set up as Utsushi works)mpv → dmabuf0.42mpv → gpu-next: 0.51 W (--hwdec=vaapi, its GPU renderer)mpv → gpu-next0.51VLC 3: 0.46 W (its defaults)VLC 30.46mpv defaults: 1.36 W (decodes in software)mpv defaults1.36

Power above idle for the CPU socket, median of three or more one-minute runs. Differences under about 0.2 W are within the noise.

The numbers
WNotes
Utsushi0.20VA-API decode, frames to the compositor as dmabufs
mpv → dmabuf0.42--hwdec=vaapi --vo=dmabuf-wayland: set up as Utsushi works
mpv → gpu-next0.51--hwdec=vaapi, its GPU renderer
VLC 30.46its defaults
mpv defaults1.36decodes in software
Extra power while playing 4K60 AV1, W (lower is better)
Utsushi: 0.89 W (no frames dropped)Utsushi0.89mpv → dmabuf: 1.06 W (no frames dropped)mpv → dmabuf1.06mpv → gpu-next: 7.62 W (557 frames dropped)mpv → gpu-next7.62VLC 3: 7.60 W (decodes AV1 in software; 315 dropped)VLC 37.60mpv defaults: 13.32 W (software; 145 dropped)mpv defaults13.32

The same measurement for a 3840 × 2160 AV1 clip at 60 frames per second.

The numbers
WNotes
Utsushi0.89no frames dropped
mpv → dmabuf1.06no frames dropped
mpv → gpu-next7.62557 frames dropped
VLC 37.60decodes AV1 in software; 315 dropped
mpv defaults13.32software; 145 dropped

At 1080p, every player that decodes on the GPU sits just a few tenths of a watt above idle, close enough that differences under about 0.2 W are within the noise. The mpv player, set up to work the way Utsushi does, stays within about 0.2 W of it on every clip, and came in lower on a 1080p AV1 clip. At 4K, Utsushi used the least. The big differences come from decoding in software, which mpv does by default (as does the mpv.conf Sekka ships), and from players that redraw every 4K frame on the GPU. Utsushi also does the least work around each frame. At 1080p it uses 0.7–0.9% of a core and wakes about 147 times a second, compared with 1.1–2.0% and 260–450 wakeups for mpv and the VLC player when they decode on the GPU. It uses the least memory too, gets its first frame on screen in 58 ms (the others took 76–172 ms), and wakes just four times a second while paused. Every clip, player and result, and how they were measured.

PDF

Shiori's renderer draws the pages of a test corpus in about half the time PDFium, the PDF engine in Chrome, takes, and the pages of real documents in about three quarters of it.

Shiori, Aizome's PDF reader, renders pages with hayro, an open-source PDF renderer written in Rust, using Aizome's own fork of it, tuned for speed. We compared that renderer with the engines most Linux PDF readers use, which are PDFium (the engine in Chrome, here as Nixpkgs builds it), MuPDF (the library behind readers such as Zathura) and Poppler (the library behind GNOME's Papers and Evince and KDE's Okular). The test set was the 1,012 files in the test corpus of pdf.js, Firefox's built-in PDF renderer, many of them bug reports and deliberately broken files. Each engine drew the first five pages of every file at 2× size, with one process per file and a single thread, over three timed runs.

Time to draw the same 1,179 pages of the pdf.js corpus, s (lower is better)
Shiori (hayro fork): 4.17 s (0.48 of PDFium's time; faster on 1,045 of 1,179 pages)Shiori (hayro fork)4.17PDFium: 8.70 s (nixpkgs' build, 8110, AGG; the engine in Chrome)PDFium8.70hayro upstream: 9.36 s (1.08 of PDFium's time)hayro upstream9.36MuPDF: 10.98 s (1.26 of PDFium's time)MuPDF10.98Poppler, Cairo: 11.37 s (1.31; as Papers and Evince draw)Poppler, Cairo11.37Poppler, Splash: 21.35 s (2.46; as Okular and pdftoppm draw)Poppler, Splash21.35

Only pages every engine managed to draw, using each page's median time over three runs, added up.

The numbers
sNotes
Shiori (hayro fork)4.170.48 of PDFium's time; faster on 1,045 of 1,179 pages
PDFium8.70nixpkgs' build, 8110, AGG; the engine in Chrome
hayro upstream9.361.08 of PDFium's time
MuPDF10.981.26 of PDFium's time
Poppler, Cairo11.371.31; as Papers and Evince draw
Poppler, Splash21.352.46; as Okular and pdftoppm draw
Energy to draw 5,895 pages, J (lower is better)
Shiori (hayro fork): 386 J (0.46 of PDFium's energy)Shiori (hayro fork)386PDFium: 833 JPDFium833hayro upstream: 745 J (0.89)hayro upstream745MuPDF: 976 J (1.17)MuPDF976Poppler, Cairo: 1,273 J (1.53)Poppler, Cairo1,273Poppler, Splash: 1,998 J (2.40)Poppler, Splash1,998

The 969 files every engine handled the same way, five times over, measured at the CPU socket. Median of three rounds. Just starting a process for each file accounts for 67 J of this.

The numbers
JNotes
Shiori (hayro fork)3860.46 of PDFium's energy
PDFium833
hayro upstream7450.89
MuPDF9761.17
Poppler, Cairo1,2731.53
Poppler, Splash1,9982.40

The pdf.js corpus is mostly small and broken files, so we also timed seven real documents, public domain or CC-BY: US government publications such as the Constitution, IRS tax documents and the federal budget, and a scientific paper. Each engine drew the first 20 pages of each (all of the two shorter ones), five times. On those, the fork's lead is smaller. It took 0.37 s for the 113 pages against PDFium's 0.48 and was the faster on 102 of them. It was the fastest of the six engines on four of the seven documents, MuPDF on two, and PDFium on the scientific paper, by under a millisecond.

Each engine's drawing time as a multiple of Shiori's renderer's, over the pages every engine drew. Higher means slower than Shiori's renderer.
Enginepdf.js corpus, 1,179 pagesReal documents, 113 pages
PDFium2.1×1.3×
hayro upstream2.2×1.2×
MuPDF2.6×1.4×
Poppler, Cairo2.7×2.1×
Poppler, Splash5.1×5.9×

On the 1,179 corpus pages, the fork's median page took 1.10 ms and its 99th percentile 37.7 ms, against 1.45 and 79.6 ms for PDFium. Neither hayro build, Aizome's fork or upstream, crashed or timed out on any file, while PDFium, MuPDF and Poppler each crashed on one or two files and timed out on as many as three. The fork's output is about as close to PDFium's as MuPDF's and Poppler's are. Of the 1,189 pages the fork and PDFium both drew at the same size (a slightly different set from the 1,179 that every engine drew), only 61 differ from PDFium on more than 5% of their pixels, compared with 86 for MuPDF and 124 for Poppler. It's still slower than PDFium on some kinds of page, such as meshes, soft masks over images, nested transparency groups and some shadings, taking 1.3 to 2.4 times as long on those.

There's no official answer key for how a PDF should render, only each engine's own regression tests. hayro's test suite has about 1,560 rendering tests, including 101 files taken from PDFium's bug tracker, and those are checked against hayro's own reference images. Upstream hayro passes all 101. The fork passes 58 within the suite's tolerance of three colour levels, and its speed optimisations leave the other 43 differing only by anti-aliasing. hayro doesn't run PDFium's own pixel tests, so we ran those too. The fork renders 132 of the 182 tests that apply (73%) within 1% of PDFium's expected images, and PDFium itself matches 180 exactly and all 182 within 1%. We judged each of the fork's 50 misses against the PDF specification. PDFium is the more correct in 19 and the fork in 6. In 24 both are acceptable, mostly damaged files the specification gives no answer for, and in 1 both are wrong. Where the fork is wrong, it's mostly in recovering damaged files, plus a few missing features such as generating an appearance for annotations and form fields that don't include one. Full results, the conformance runs and how they were measured. Each miss, judged against the specification.

What it costs

What the design costs, and what isn't finished yet.

  • Not quiet enough at idle. In these tests, six of GNOME's eight apps didn't wake up at all while idle. Aizome's woke between about one and nine times a second (its system monitor more often), and the shell about 53 times. Every app checks its settings file once a second (about 0.02 ms of CPU each time), the system-service watchers each check for a stop request four times a second, Shiori's watchdog keeps ticking even when no page is being drawn, and the blinking cursors in Sumi, the text editor, and Hotaru, the terminal, never stop. None of these costs much on its own, but together they keep CPU cores from reaching their deepest sleep states. Simple fixes would take most of them to zero.
  • No shared libraries. Each app is a single Rust program with the toolkit compiled in, 13–24 MB on disk. Two Aizome apps running side by side each load their own copy of the toolkit code (10–13 MiB each), where two GTK apps would share one.
  • Pictures stay in RAM. Because the shell draws on the CPU, its bar, Deskbar and desktop are pictures in system memory, so a bigger screen costs RAM: at 3840 × 2160 the shell held 16 MiB more private memory than at 1920 × 1080. Its wallpaper is an 8 MiB picture, but it costs the shell about 24 MiB.
  • The shell grew over a long session. Over four unattended hours, the live shell's private memory went from 372 MiB to 693 MiB, and it kept growing more slowly, to about 785 MiB nine hours later. The growth is in its worker threads' allocator arenas, and a freshly started shell uses 55 MiB. We haven't tracked down the cause yet.
  • Copying to the GPU. For CPU-drawn windows, the compositor has to upload whatever changed to the GPU, while a GL client's buffer is already there. Damage tracking keeps those uploads small, but a terminal scrolling every frame still costs the compositor about twice as much as Ghostty does.
  • Terminal latency and throughput. Hotaru shows a keystroke about a frame later than foot or GNOME's terminals, and the latest Ghostty reads output faster (terminals).

The measurements behind each of these.

How it was measured

Everything was measured on one machine, an AMD Ryzen 7 9800X3D (8 cores, 16 threads) with 62 GiB of RAM, its built-in Radeon graphics, and an NVIDIA RTX 5090 driving a 3840 × 2160 display, running Sekka on Linux 7.3. Every program we compared came from Sekka's own Nixpkgs, at the same versions a Sekka install would get, except Ghostty's main branch, which we built. Each ran with Sekka's default settings unless a section says otherwise.

Only one measurement ran at a time, and each one held a lock that kept other tests and builds off the machine. Programs took turns rather than running all of one and then all of the next, each started with an unmeasured warm-up run, and the figures shown are medians. A desktop has no battery to measure, so power came from the CPU socket's own sensor (PPT, which covers the cores, the Radeon graphics and the I/O die), cross-checked against its RAPL energy counter.

These are measurements of headless compositors and virtual machines rather than of light coming off a real screen, and they all come from a single machine. The dataset's README explains how each one was taken, and the data and test harnesses sit next to it in the repository.

Versions of everything measured
SoftwareVersion
Aizome (compositor, shell and apps, including Hotaru, Utsushi and Shiori)0.1.0, Sekka d7ecbac
Shiori's renderer, hayro (Aizome's fork), and upstream hayroa2e9e62b, 04a801de
Sekka's Nixpkgs, where everything else comes from26.11 (1c89083)
Linux, systemd7.3.0, 262
Mesa (Radeon), NVIDIA driver26.2.6, 615.78.08
GNOME Shell, Mutter, GDM50.4, 50.5, 50.2
GTK 4, libadwaita, GTK 3 (gnome-terminal), VTE4.22.4, 1.9.3, 3.24, 0.84
GNOME's apps (Calculator, Clocks, Loupe, Papers, Files, System Monitor, Disk Usage Analyzer, Console)50.0–50.2.2
GNOME Text Editor, gnome-terminal50.1, 3.60.0
KDE Plasma (KWin, Plasma Login), Plasma System Monitor6.8.2
KDE Frameworks, Qt6.31.0, 6.12.0
KDE's apps (Konsole, Dolphin, KCalc, KWrite, Gwenview, Okular, Filelight)26.08.2
Ghostty (release, main)1.4.0, 1.4.1-dev 0b1729e
foot1.28.0
sway (the neutral compositor), wlroots1.12, 0.20.2
mpv, libplacebo0.41.0, 7.360.1
VLC3.0.24
FFmpeg (Utsushi and mpv; VLC)9.0.2; 8.1.3
PDFium (GCC build, AGG renderer)8110
MuPDF1.28.5
Poppler, Cairo26.10.0, 1.18.4
QEMU (the VMs)11.1.2