Skip to content

veilDocsReference

Performance

CPU, memory and frame rate measured per kind of wallpaper.

Copied from README.md in veil’s repositoryView on GitHub (opens in a new tab)

Measured with scripts/bench/ (opens in a new tab) on the build of 2026-10-19, in a headless sway 1.12 that renders on the CPU, one 1920x1080 output in fill, 60 seconds after a 5-second warm-up, with MALLOC_ARENA_MAX=1 as the package and the unit start it. The clips are ffmpeg test patterns in which every frame differs. The machine: Intel Core i5-11400F, NVIDIA GeForce RTX 3060 Ti (driver 595.91.07, so GStreamer picks the nvcodec decoders), 32 GB, NixOS with Linux 7.2 and GStreamer 1.28.7. CPU is in percent of one core, for the daemon's whole process.

WallpaperDecoderCPUFrames shown per secondMemory (RSS)Threads
A 1920x1080 PNGnone0.02 % (one tick of 10 ms in 60 s)20 MiB1
H.264, 1080p, 30 fpsnvh264dec (GPU)19.5 %30.0 of 30203 MiB15
H.264, 1080p, 60 fpsnvh264dec (GPU)39.7 %59.8 of 60203 MiB15
VP9, 1080p, 60 fpsnvvp9dec (GPU)37.9 %59.9 of 60251 MiB15
H.264, 2160p, 60 fpsnvh264dec (GPU)136 %60.2 of 60297 MiB15
H.264, 1080p, 30 fpsavdec_h264 (software)24.5 %30.0 of 30161 MiB22
H.264, 2160p, 60 fpsavdec_h264 (software)174 %60.1 of 60458 MiB22
  • A still picture costs next to nothing after it is drawn: one thread, and one tick of CPU time in a minute, while the bench asked veil status every second.
  • A video costs CPU in proportion to its pixels per second, whatever the codec. The decoder on the GPU costs about 1 %; the rest is the conversion of every frame from NV12 to RGB, which the compositor needs and which happens on the CPU with NVIDIA's decoders. veil's design goal of under 1 % for a video is not met on this hardware. On Intel and AMD, VA-API could hand the frames to the compositor without that conversion; that has not been measured (known issue 7).
  • Memory, threads and file descriptors stay flat: a video that looped once a second for ten minutes kept nothing (with the hardware decoder; the software decoder kept about 500 KiB over its first minutes, then nothing), and 500 wallpaper switches (250 of them videos) left nothing behind. Memory stays flat over switches only with one allocator arena (MALLOC_ARENA_MAX=1), which the Nix package and the systemd unit set; known issue 3 has the numbers without it. Runs of hours and days are still to be done.
  • A paused or stopped video uses next to no CPU: behind a fullscreen window it keeps its frame on screen and decodes nothing (measured: at most one tick in 5 seconds); while the screen is locked its pipeline is released.

How each number was measured, and what was measured before, is in docs/measurements.md. Nothing has been measured in a real session yet.