Model or dataset
psalias2006/gpu-hot avatar
psalias2006/gpu-hot

GPU Hot: a self-hosted NVIDIA dashboard that polls NVML only when a browser is watching

🔥 Real-time NVIDIA GPU dashboard

1,633 stars83 forksJavaScriptMIT

At a glance

What is it?
GPU Hot is a Python and JavaScript dashboard that reads GPU counters through NVML and pushes them to a browser over Socket.IO. It is small enough to read in an afternoon, and it is built for people who want a private view of their own cards rather than a hosted service.
Who is it for?
Adopt GPU Hot if you run one to a few NVIDIA boxes and want a private dashboard you can start with a single docker run, and if you are comfortable reading core/monitor.py when something looks wrong. Do not adopt it if you need long-term metric storage, alerting, or historical retention beyond what the in-process charts hold; nothing in the README describes a database or a notification path.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 22 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The gap GPU Hot fills: a private view of your own cards

Most GPU telemetry ends up in a platform. You install an agent, the agent ships numbers to a vendor, and the vendor gives you a chart. GPU Hot takes the opposite position. It runs on the machine that owns the GPUs, reads the counters locally, and serves a dashboard on port 1312. Nothing leaves the host unless you configure hub mode, which is described as a way to point one dashboard at several node URLs you control.

The audience is narrow and identifiable. It is the person who has one or two workstations with an RTX card and wants to know whether a training run is actually using the GPU. It is the small team with three inference servers that wants a single page rather than three SSH sessions. It is not aimed at a fleet operator who needs retention, alert routing, or per-tenant access control; the README does not describe any of those.

NVML as the primary source, nvidia-smi as the escape hatch

The repository layout is the clearest statement of how this works. core/monitor.py handles NVML GPU monitoring, core/metrics/collector.py handles metrics collection, and core/nvidia_smi_fallback.py exists for older GPUs. That third file is the interesting one. NVML does not expose every counter on every driver and card generation, so the project keeps a second path that shells out to nvidia-smi. The README says to add -e NVIDIA_SMI=true if metrics do not appear.

The two paths run at different cadences. UPDATE_INTERVAL defaults to 0.5 seconds and is described as the NVML polling interval. NVIDIA_SMI_INTERVAL defaults to 2.0 seconds and applies to the fallback. That asymmetry is deliberate: parsing nvidia-smi text output is more expensive than an NVML call, so the fallback is throttled. If you force NVIDIA_SMI=true on a modern card, you accept a slower refresh for no benefit.

Data leaves the process over two transports. GET /api/gpu-data returns a JSON snapshot for anything that wants to poll. The Socket.IO endpoint at /socket.io/ pushes the same shape, and the README's example shows three top-level keys: data.gpus for per-GPU metrics, data.processes for active GPU processes, and data.system for host CPU, RAM, swap, disk and network. Metrics listed in the README include utilization, temperature, memory, power draw, fan speed, clock speeds, PCIe info, P-State, throttle status, and encoder/decoder sessions.

Idle cost, and the pause that keeps it near zero

A monitoring tool that burns GPU host CPU while nobody is looking is a bad trade. The README states that polling is paused automatically when no clients are connected, so idle CPU usage stays near zero. This is the single most defensible design decision in the project. The collector does not run on a timer independent of demand; the WebSocket connection is effectively the on switch.

The consequence is worth stating plainly. If you close the browser tab, you get no data for that window. There is no described mechanism for backfilling a gap, because there is no described storage layer at all. Historical charts exist in the UI, but the README does not say where that history lives or how much of it is kept. If you need a record of what happened at 03:00 while nobody had the dashboard open, this architecture does not give it to you.

Getting it running: one container, or a hub plus nodes

The single-machine path is one command: docker run -d --gpus all -p 1312:1312 ghcr.io/psalias2006/gpu-hot:latest, then open http://localhost:1312. Requirements are Docker and the NVIDIA Container Toolkit.

Multi-node uses the same image in two roles. On each GPU server you add a name: -e NODE_NAME=$(hostname). On a hub machine, which the README says does not need a GPU, you set -e GPU_HOT_MODE=hub and pass -e NODE_URLS=http://server1:1312,http://server2:1312,http://server3:1312. The hub then aggregates. core/hub.py and core/hub_handlers.py are the files behind that mode.

Other knobs from the README: NVIDIA_VISIBLE_DEVICES=0,1 restricts which cards are exposed (default is all); NODE_NAME sets the display name (default is the hostname); UPDATE_INTERVAL and NVIDIA_SMI_INTERVAL control polling cadence. The server port is not an environment variable. It lives in core/config.py as PORT = 1312, so changing it means editing the file or remapping the published port.

Process names need two extra flags: --init --pid=host. The README flags the trade-off in the same sentence, noting that this allows the container to access host process information. From source, the path is git clone, cd gpu-hot, docker-compose up --build.

Where the design runs out of room

The hub is a fan-in point, not a cluster manager. NODE_URLS is a static comma-separated list. Adding a fourth machine means editing the hub container's environment and restarting it. There is no described discovery, no registration endpoint, and no health-based eviction of a dead node. If a node goes away, the hub's behaviour is not documented in the README; you would need to read core/hub.py to know whether it retries, drops the node, or shows stale values.

Scaling claims deserve a caveat. The README lists "Scale from 1 to 100+ GPUs" as a feature. What the material actually supports is that the hub aggregates multiple node URLs and that the front end renders cards. Whether a single hub process keeps up with a hundred cards at a 0.5 second interval is a question the README does not answer, and the troubleshooting section offers only one lever for load: increase UPDATE_INTERVAL, for example -e UPDATE_INTERVAL=2.0. That is a reasonable answer, but it is a manual one, and it changes the resolution for every card at once.

The security posture is also understated. The dashboard has no described authentication. Anyone who can reach port 1312 sees your GPU inventory, your process list, and your host CPU and memory counters. In hub mode the node endpoints are plain http:// URLs in the examples, and the troubleshooting section's own diagnostic is curl http://node-ip:1312/api/gpu-data. That is fine on a trusted network and a bad idea on a shared one. The README does not mention TLS, tokens, or a reverse proxy, so treating those as your responsibility is the correct reading.

The alternative: nvidia-smi in a loop, or a full metrics stack

The honest comparison for the low end is the tool already on the machine. nvidia-smi --query-gpu=... --format=csv -l 1 gives you a scrolling table with no install, no container, and no port. It is scriptable and it works over SSH. What it does not give you is a chart, a shared URL for a teammate, or process attribution in a browser. GPU Hot is essentially a presentation layer over the same counters, with the polling pause and the hub as the parts a shell loop cannot easily replicate.

The comparison at the high end is a time-series stack. Prometheus with the NVIDIA DCGM exporter scrapes on a fixed schedule, stores samples in a database, and lets you alert on them. That approach keeps data even when nobody is watching, which is precisely the gap the pause-on-idle design creates. The cost is a much larger footprint: a scraper, a store, a query layer, and a dashboard tool. GPU Hot fits in one container and one Python process. If your question is "is this run using the GPU right now", GPU Hot answers it with less machinery. If your question is "what did utilization look like last Tuesday at 14:00", it does not answer it at all.

Maintenance, versioning and the MIT licence

The project is active rather than archived, with a last push in August 2026 and releases clustered in July 2026 (v1.9.2, v1.9.1) after v1.9.0 in May 2026. The version is exposed at GET /api/version, and static/js/app.js is described as handling init plus a version check, so the UI can tell you when the running container is behind. That matters for a tool you deploy once and forget: pulling a new image is a restart, not a migration, as long as the environment variables you rely on keep their names.

Upgrade risk concentrates in the parts that touch the driver. NVML behaviour varies across driver versions and card generations, and the nvidia-smi fallback exists because of that variation. A container that works against one driver may need NVIDIA_SMI=true after a host upgrade. Pin your image tag rather than tracking :latest if you want a known-good combination.

The licence is MIT, stated in the README and in the repository metadata. That permits commercial use and modification, and it requires that the copyright notice and permission notice be included in copies or substantial portions. It also means no warranty. None of this is legal advice; read LICENSE and your own obligations before redistributing a modified build.

Editorial conclusion

Adopt GPU Hot if you run one to a few NVIDIA boxes and want a private dashboard you can start with a single docker run, and if you are comfortable reading core/monitor.py when something looks wrong. Do not adopt it if you need long-term metric storage, alerting, or historical retention beyond what the in-process charts hold; nothing in the README describes a database or a notification path. Before rolling it out, verify that the container can see the cards (docker run --rm --gpus all nvidia/cuda:12.1.0-base-ubuntu22.04 nvidia-smi), then check whether your process names appear, since that requires --init --pid=host and grants the container access to host process information.

Official sources

  1. License: MIT
  2. Project website
  3. psalias2006/gpu-hot on GitHub
  4. README
  5. Releases
Community notes

Community notes