Every GPU.
One terminal.
btop-style GPU monitor. An nvtop replacement that runs
everywhere.
NVIDIA, AMD, Intel, and Apple GPUs on Linux, macOS, and Windows. Mirrored braille waveforms, gradient meters, an nvtop-style process table with per-process GPU attribution, mouse support, foldable GPU cards, and theming via the hjkl stack. Single binary, no daemons.
┌─ 0 · GeForce RTX 4080 · PCIe 4.0@16x ─────────────────────────────┐ │ util 64% [■■■■■■■■■■■■■·······] ⣀⣠⣤⣴⣶⣷⣿⣷⣶⣤⣤⣶⣾⣿⣶⣄⣀⣀⣠⣤⣶⣷⣿ │ │ vram 6.3G/16G [■■■■■■■■············] ⠉⠛⠿⣿⣿⠿⠛⠋⠉⠉⠛⠿⣿⠿⠟⠛⠋⠉⠑⠒⠚⠛ │ │ temp 64°C fan 42% pwr 212W/320W clk 2505MHz enc 12% dec 0% │ └──────────────────────────────────────────────────────────────────┘ ┌─ 1 · GeForce RTX 3060 · PCIe 3.0@8x (max 4.0@16x) · THERMAL ──────┐ │ util 98% [■■■■■■■■■■■■■■■■■■■■] ⣶⣷⣿⣿⣿⣾⣷⣿⣿⣿⣿⣷⣶⣾⣿⣿⣿⣿⣷⣾⣿⣿ │ │ temp 91°C fan 100% pwr 169W/170W clk 1327MHz │ └──────────────────────────────────────────────────────────────────┘ PID USER DEV TYPE GPU% GPU MEM CPU% MEM COMMAND 41273 mx 0 Graphic 61% 5.1 GiB 12.4% 2.1G ▶ game.exe 40911 mx 1 Compute 97% 9.8 GiB 84.0% 6.3G python3 train.py 39882 mx 0 Graphic 2% 312 MiB 1.1% 890M Hyprland
why
nvtop's depth, btop's polish, every vendor's GPU.
NVIDIA · AMD · Intel · Apple
One binary probes NVML, amdgpu sysfs, i915/xe fdinfo, IOAccelerator, and
Windows PDH — and every backend that finds devices runs, not
just the first. An NVIDIA dGPU beside an AMD APU lists both cards in one
list and one process table; the header reads [multi] and
names each driver. No per-vendor builds.
The full panel
Utilization, VRAM, temperature (core / junction / memory), power + limit, fan, core and memory clocks, PCIe gen/width/throughput, GTT, voltage — whatever the backend exposes, rendered.
Braille waveforms
Mirrored braille history graphs and gradient meters, live in ratatui.
Fonts without braille coverage fall back to
--graphs block or ascii.
Per-process attribution
nvtop-style table: PID, user, device, type, GPU%, GPU memory, CPU%, host
memory, command. Containerized processes get a CONTAINER column (docker
/ podman / k8s from cgroups). Filter with /, sort with
s, SIGTERM/SIGKILL with x/X.
Survives driver resets
Backend poll failures degrade gracefully: the last snapshot stays on screen with a header warning until polling recovers. A driver reset won't kill the monitor.
Throttle + PCIe flags
A red throttle badge appears when the GPU is thermal- or power-limited,
and the PCIe caption flags a link running below its maximum —
PCIe 3.0@8x (max 4.0@16x) — the classic bad-riser symptom.
Cards show session peaks and averages when tall enough.
Record & replay
gpur --log run.jsonl records one JSON record per poll;
gpur --replay run.jsonl plays it back anywhere — including
machines with no GPU — process attribution intact. Ideal for bug
reports.
Scriptable snapshots
--once prints one text snapshot with no TUI;
--json emits a machine-readable snapshot for waybar /
polybar / monitoring; --mock demos the UI on any machine,
up to a 16-GPU rig.
hjkl-theme theming
Point config.toml at any
hjkl-theme file — meters, waveform
gradients, and highlights all derive from its palette. Mouse support and
foldable GPU cards included.
Unknown is not zero
A reading the backend could not take renders n/a in the
table and null in --json / --log,
never a confident 0 — NVML reports no per-process memory
under WDDM, and an unprivileged fdinfo sweep cannot see another user's
processes. Unmeasured rows sink below measured ones in both sort
directions, and a graph sample that was never taken draws its own dimmed
glyph instead of a flat floor.
backends
One trait, one impl per vendor. All of them at once.
Probe order: nvml → amdgpu → intel → ioaccel, then pdh as a filtered peer. Each vendor backend claims only its own PCI vendor's devices, so every one that answers contributes cards no other reports and nothing is counted twice. The AMD Linux path is the one exercised on real hardware; the NVIDIA, Intel, macOS and Windows backends are implemented and their parsers are tested against recorded fixtures, but no CI runner has a usable GPU — so real-GPU reports are very welcome.
install
crates.io, AUR, Homebrew tap, Scoop, Alpine .apk — or a prebuilt binary.
Each tagged release ships x86_64 + aarch64 Linux (glibc 2.28 and musl) tarballs, .deb and .rpm packages, an Alpine .apk, a Windows x64 .zip, and macOS (Apple Silicon + Intel) tarballs — SHA-256 sidecars on every artifact.
$ cargo install gpur $ gpur
$ yay -S gpur-bin $ paru -S gpur-bin
$ brew install kryptic-sh/tap/gpur $ gpur
$ scoop bucket add kryptic https://github.com/kryptic-sh/scoop-bucket $ scoop install kryptic/gpur
# download .apk from releases page, then: $ apk add --allow-untrusted gpur-*.apk $ gpur
$ git clone https://github.com/kryptic-sh/gpur $ cd gpur $ cargo build --release # no GPU handy? demo the UI anyway: $ gpur --mock 6