A light, fast terminal dashboard for AMD GPUs on Linux.

Install
$ cargo install gpuflo --locked
$ curl -fsSL https://raw.githubusercontent.com/mikeroySoft/gpuflo/main/install.sh | sh

No ROCm. No root. No daemon. Just Linux and the in-kernel amdgpu driver. Current release: v0.2.0 with checksums.

gpuflo — 96×32
▶ AMD Radeon AI PRO R9700  6%
GPU activity  6% →peak: 37%
Memory occupancy  24.9 / 32 GiB · 78%VRAM
hotspot 54 / 110°C  ·  power 47 / 300 W  ·  GFX 1113 MHz
←/→ · h GPU · l logo · t buffalo · m mode · p processes · d detail · ? help · q quit

Three questions, one second

GPUFlo reads Linux amdgpu kernel interfaces directly — sysfs, hwmon, versioned gpu_metrics, DRM fdinfo — and answers immediately:

What is the selected physical GPU doing?
How much of its applicable memory pool is occupied?
Is a source-backed fault, throttle, limit, pressure, sleep, permission, or telemetry problem active?

Light, fast, accurate

Light

One small static binary, strictly read-only. No ROCm userspace, no root, no daemon, no database, no network. Optional sources only ever add information.

Fast

First reading in under a second. Telemetry samples on a dedicated 250 ms kernel lane that rendering, overlays, and process scans can never block.

Accurate

Socket-scoped temperature and power kept separate from partition-scoped activity, memory, and clocks. Missing telemetry is an explicit state — stale, asleep, permission_denied — never a made-up zero.

Extensible & embeddable

Stream --json / --json-stream NDJSON (optionally --for <duration>) into scripts. Every GPU carries additive gpus[].platform within schema_version 1. Or embed the semver-supported Rust Monitor API — the same canonical model that drives the TUI.

Responsive views

Full mode, compact, mini, and one-line tiny views auto-select by terminal size. Works as a floating desktop widget.

Process attribution

Press p: PID, name, GPU/XCP, VRAM, GTT, KFD memory, and container identity — permission failures shown explicitly rather than hidden.

Honest daily summary

Optional local daily.json keeps peaks, energy when available, and source-reported throttle episodes — never raw samples, never uploaded. Pin machine output on schema_version, not the binary version.

Extend it

The same canonical telemetry model drives the TUI, a stable JSON/NDJSON contract (schema_version 1 — pin on it; additive fields like gpus[].platform stay compatible), and a semver-supported Rust library for embedding.

Stream NDJSON into anything

# one snapshot, a stream, or a bounded capture
gpuflo --json | jq '.gpus[].platform'
gpuflo --json-stream | jq .gpus[0].activity
gpuflo --json-stream --for 30s > capture.ndjson

# schema_version 1 · each gpus[] has platform · never null/NaN/fake zero
{ "schema_version": 1, "gpuflo_version": "0.2.0", ... }
# gpus[].platform (additive within schema 1):
{ "id": "generic_discrete", "memory_pool": "vram" }
{ "value": 97.0, "observed_at": "2026-08-21T23:45:12Z" }
{ "state": "permission_denied" }

Embed the Monitor in Rust

use gpuflo::{Monitor, MonitorEvent, MonitorOptions};

let monitor = Monitor::start(MonitorOptions::new())?;
match monitor.receive()? {
    MonitorEvent::Snapshot(s) =>
        println!("{} GPU(s)", s.gpus.len()),
    MonitorEvent::Fatal(e) => return Err(e.into()),
    _ => {}
}

Under the hood

Codebase Atlas →

An interactive isometric map of the whole codebase: every module as a building sized by real line counts, every control and data path cited to the file that implements it. Three styles, zoom + pan, click to inspect.

AI Agent Factory →

How gpuflo maintains itself: a label-driven pipeline that triages GitHub issues, dispatches coding agents into git worktrees, gates their work with six deterministic checks, and publishes reviewed PRs. Humans keep the merge button.