HomeLab Monitor
v…
MCPconnecting…One small container for your home lab — GPU & local-AI, Docker containers, systemd services and host health, all on one page. Everything is discovered automatically; nothing is hardcoded.
Fleet
—Burn Rate
›hubThe Lab's Engine
›ShowingCompute history
›hubEvent & Insight Feed
What's Costing You
›hubAI workload · MCP · setup & requirements
🧠 AI workload
AI agent (MCP)
claude mcp add --transport http homelab …
🩺 Setup & requirements
| Requirement | Status | Detail |
|---|
🎮 GPU right now
📋 Services on the GPU (selected range)
| Service | Peak | Avg | % time |
|---|
🎮 Per-GPU
Live per-card utilisation, VRAM, power and temperature. The cards above pool VRAM and power across all GPUs.
📊 VRAM by service over time
Stacked = VRAM each service holds. Dashed = capacity. Red bands = VRAM pressure; ▼ markers = out-of-memory events.
⚡ GPU utilization, power & temperature
💰 Power & cost
GPU power is measured (nvidia-smi); CPU/DRAM are measured via RAPL when readable. "Other" appears only if you set a baseline in Settings — wall power is never guessed.
🗓️ Busy hours — when your lab burns power
Each cell is the average total draw (GPU + CPU + DRAM) for that local day-of-week and hour, over the chosen window. Colour scales by cost-rate when a tariff is set, otherwise by power. Sparse cells are dimmed — hover for the exact figures.
🧾 Breakdown by process / container / model
| Name | Kind | Avg W | Energy | Cost |
|---|
Click a row to drill into its power & cost over time. GPU split by VRAM share; CPU split by CPU-time share of the measured package power.
Drilldown
📦 Installed models
Every model this host's recognised AI servers report — ollama's on-disk inventory (size, params, quant) plus what every other server (vLLM, llama.cpp, …) is currently serving, grouped by provider. A Loaded badge marks models resident in VRAM this moment. Read-only.
One panel per model server: its VRAM timeline (shared by the models it hosts) plus each model's own peak & average. A server is shown even while Idle (model unloaded / between requests), so nothing vanishes when VRAM is released. Recognised: Ollama, vLLM, SGLang, llama.cpp, LocalAI, HF TGI/TEI, LoRAX, mistral.rs, Aphrodite, koboldcpp, tabbyAPI, text-generation-webui, LM Studio, xinference, OpenLLM, LiteLLM, GPUStack, Cortex/Jan, Ramalama, Nexa, Triton, Infinity, faster-whisper/Speaches, Whisper ASR webservice/WhisperX, Wyoming (HA voice), OpenedAI-Speech, Stable Diffusion (A1111/Forge/SD.Next), InvokeAI, ComfyUI.
🧪 Runs — pushed from your notebooks & MLflow, priced with real GPU energy
| Run | Source | Status | Started | Duration | Metrics | Energy | Cost |
|---|
Run
⚡ GPU power & utilisation during this run
🔬 Auto-detected on the hub — training processes running now (no push needed)
🧰 Notebooks & tools
Auto-discovered DS/AI web tools running on the hub. A 🟡 VRAM tag means a kernel/process is holding GPU memory — often a forgotten notebook squatting on VRAM.
📈 GPU activity sessions
| Started | Duration | Peak util | Peak VRAM | Avg power | Energy | Cost |
|---|
Contiguous GPU-busy periods reconstructed from power & utilisation history — each is a training run, batch job or inference burst. Energy is integrated from GPU power; cost uses your kWh price.
📦 Docker containers
| Container | State | Image | Ports | Uptime | RAM | VRAM | Disk | Status | Controls |
|---|
🧩 systemd services
Push notifications when something noteworthy happens. Configured here — no env vars, no config files. Any channel (Discord, ntfy, or Telegram) can be used; all are optional. Alerts are edge-triggered (one ping per state change) so they don't spam.
https://ntfy.sh. Self-hosted ntfy works too.chat.id from getUpdates.{level, title, detail, host} — works with Teams, Gotify, n8n…Triggers: container unhealthy/exited non-zero/dead, systemd unit failed,
GPU VRAM pressure (free < PRESSURE_FREE_MB), GPU OOM events, and disks crossing the threshold above.
📋 Routing rules
Per-service rules control which channels receive which alerts.
If no rule matches, the default (all configured channels) applies.
Wildcards (*, ?) work in the pattern column.
| Kind | Pattern | Channel | Min level | On |
|---|
📰 Daily brief
A scheduled “is the lab OK?” digest — the calm counterpart to alerts. Sent once a day to one channel: email gets the full HTML report, chat channels get a compact summary with the things that need attention.
Only channels you've configured above appear here — configure one and it shows up automatically.
Settings here save automatically when you leave a field. Preview and Send test use your saved settings.
Set your electricity price so the dashboard can turn power into money on the 💰 Costs page. Don't know your rates? Pick your country for a typical, editable estimate.
Powers the 💰 Costs page and the Power & cost cards from power history. Day & Night bills each sample at the night rate inside the window (it may cross midnight) and the day rate otherwise — leave the night price blank to use the single average. Leave the price blank to hide the cost cards.
Push run/session data from Jupyter, Colab or Kaggle (or mirror MLflow) — each run comes back priced with the real GPU energy it used. Writes need the API key; the dashboard reads are open on your LAN.
| Name | Key | Created | Expires | Last used | Runs |
|---|
import homelab_run as homelab
homelab.configure(url="http://THIS-HOST:9800", key="hlm_…")
with homelab.run("my-finetune", params={"lr":2e-4}) as r:
for step, loss in enumerate(train()):
r.log_metric("loss", loss, step=step)
r.log_metric("tokens_per_sec", batch_tokens / step_seconds, step=step)
url at a Tailscale/ngrok address that reaches this hub.💾 Backup & Restore
Export your SQLite history, events, alert settings, and host registry — or restore a snapshot after a container recreate or disk move.
SSH keys under /data/.ssh are not included; back those up separately if needed.
Restore replaces all current database contents with the uploaded file.
A safety copy of the previous database is kept alongside it as *.pre-restore-*.bak.
🌐 Hosts
Monitor your other machines from this hub — agentless, read-only, over SSH. Three quick steps: authorize the hub's key on a machine, add it here, then Test.
loading…
🖥️ System
🧠 Top processes
🧠 Memory map — containers & services
🖥️ CPU, RAM & load
💾 Disk I/O Throughput
Live per-device throughput, utilisation and average op-latency, with a 6h trend sparkline per device. Read-only — nothing here touches your disks.
📶 Throughput
📊 Top talkers — containers
| Container | In | Out | Total |
|---|
Total bytes each container moved over the selected range (its own network namespace).
🌐 Network
🛡️ Security
Read-only, agentless — no changes are made to any host. Items shown in grey (⚪) couldn't be read without elevated privileges on that machine.
🛰️ Uptime checks
Monitor any HTTP endpoint or TCP port from inside this container — your own services, a NAS, a remote site. No extra uptime service to self-host — it's already here. Down/recovery alerts reuse your configured channels. Targets stay private to this dashboard — they never reach the public status page.
Self-hosted & open source • single container • no Prometheus/Grafana required • history downsampled on read.
GPU services attributed via /proc/<pid>/cgroup + the Docker API.
Ideas welcome — see CONTRIBUTING.md · issues & PRs always open.