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 in order and runs the first backend that answers. 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.
backends
One trait, one impl per vendor. Probed in order.
Probe order: nvml → amdgpu → intel → ioaccel → pdh. The AMD Linux path is battle-tested on real hardware; the macOS IOKit backend returns live data; Intel and Windows backends are implemented, CI-exercised, and awaiting real-GPU reports.
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