Uptime Kuma running on a box that isn't the one being watched, plus push notifications, delivers 90% of homelab monitoring value in thirty minutes. Prometheus and Grafana are tier two, for when you need to know why something broke rather than whether it's up. Log aggregation is tier three and most homelabs never need it. The design rule that matters more than any tool: alert only on things a human must act on — service down, disk filling, backups silent — and put everything else on a dashboard you look at when curious.

Tier 1: Uptime Kuma, but off the infrastructure

Uptime Kuma gives you HTTP, TCP, ping, DNS, and Docker-container monitors with a notification fan-out to nearly everything (ntfy, Telegram, email, webhooks) in a single container that idles at ~100MB. The mistake in most setups is topological: run it on the server it monitors and a power failure takes the witness down with the victims. Put it on a different device at minimum — a Pi, the NAS, anything — and ideally off-site entirely: a $4/month VPS, or a Pi at a relative's house joined to your tailnet. Off-site placement also means you're testing the path your actual users take, DNS and reverse proxy included, not just whether a process answers on localhost. Point one HTTP monitor at each user-facing service (the login page, not just port 443), one ping at the router, and wire notifications to ntfy for phone push without an account. If family or friends use your services, the same instance doubles as a status page.

The dead-man switch: monitoring for things that go quiet

Up/down monitors catch loud failures. The dangerous failures are silent — the backup cron job that stopped running in March, discovered in September. Invert the logic with push monitors: the job pings a URL on success, and Uptime Kuma alerts when the ping doesn't arrive within a window (24 hours plus slack, so 26 hours for a nightly job). Append to the end of any script:

restic backup /srv/data && curl -fsS http://kuma.lan:3001/api/push/AbCdEf1234

Give every scheduled job that matters — backups, certificate renewal, database dumps, sync tasks — its own push monitor. This single pattern prevents the most expensive failure class in self-hosting, and it's ten minutes of work.

Tier 2: Prometheus and Grafana answer the why

When "Jellyfin was down at 3am" needs a cause, you want metrics history. The standard homelab trio: node_exporter on each host (CPU, RAM, disk, temperatures), cAdvisor for per-container stats, and Prometheus scraping both into its time-series store.

# prometheus.yml
scrape_configs:
  - job_name: node
    static_configs:
      - targets: ["server1:9100", "nas:9100"]
  - job_name: cadvisor
    static_configs:
      - targets: ["server1:8080"]

A 30-second scrape interval and the default 15-day retention cost a few hundred megabytes of disk per node — trivial. On top, Grafana for dashboards: import dashboard 1860 ("Node Exporter Full") and you have professional-grade host visibility before writing a single query. The whole tier is three containers and an evening, and the payoff is diagnostic: the 3am outage becomes "RAM exhausted at 02:47, the culprit's memory graph is right there." Resist tier two until you've wanted that answer at least twice; dashboards you don't consult are decoration.

Alerts that don't cry wolf

Alert fatigue kills homelab monitoring more surely than any outage — mute one noisy alert and you've muted them all, psychologically. A ruleset that has survived years of contact with reality:

AlertThresholdWhy it pages
User-facing service down3 failed checks (~3 min)Someone will notice soon
Root or data disk usage>85%, and >92% againFull disks corrupt things
Backup dead-man switchNo ping in 26hSilent failure, huge blast radius
Certificate expiry<14 daysRenewal automation has failed
SMART failure predictedAnyDays of warning before data loss

Everything else — CPU spikes, load average, memory pressure, a container restarting once — is dashboard material, not a notification. High CPU at 2am is Jellyfin generating trickplay images; a notification teaches you to ignore notifications. The three-failures rule on the down alert matters too: single-check alerting turns every 10-second network blip into a buzz, and the wolf-crying starts there.

Tier 3: logs, probably not

Loki plus Promtail gives you grep-able history across every container, and it's the right call the third time you're debugging a recurring 4am crash. Until then, docker logs --since 1h on demand covers a homelab, with a lightweight live viewer like Dozzle if you want a browser tab. Log pipelines are the piece of this stack with real ongoing maintenance cost (parsing, retention, disk); skip them guilt-free until a specific problem demands one.

One adjacent tool earns a mention because it watches the thing metrics miss: Scrutiny reads SMART data from your disks and charts it against Backblaze's failure statistics, turning "the drive will die soon" from a surprise into a two-week warning. Disks are the component whose failure actually destroys data, which makes this the highest-value single-purpose monitor in the whole stack. More options across every tier sit in the monitoring category.

What I'd do

Tonight: Uptime Kuma somewhere off the main server, HTTP monitors on every user-facing service, ntfy on your phone, push monitors on the backup and cert-renewal jobs. That configuration catches the failures that actually hurt. Add node_exporter, Prometheus, and Grafana the week you first wish you knew why something died, and adopt the alert table above wholesale — the homelab that pages you five times a year gets fixed five times a year; the one that pages you daily gets ignored by June.