Uptime Monitoring for Home Labs: Uptime Kuma, Gatus, and Statping-ng
Knowing when a service goes down is just as important as keeping it running. Without uptime monitoring, you find out something's broken when you try to use it — which might be hours or days after the actual failure. A monitoring tool checks your services continuously and alerts you the moment something goes wrong.
The home lab community has several self-hosted options, but three stand out: Uptime Kuma (the most popular), Gatus (configuration-as-code), and Statping-ng (status pages). Each takes a different approach to the same problem.
Uptime Kuma
Uptime Kuma is the most popular self-hosted monitoring tool, and it deserves the title. It has a beautiful web interface, supports dozens of monitor types, and integrates with nearly every notification platform. Setup takes about two minutes.
Deployment
services:
uptime-kuma:
image: louislam/uptime-kuma:latest
container_name: uptime-kuma
restart: unless-stopped
ports:
- "3001:3001"
volumes:
- ./uptime-kuma:/app/data
Open port 3001, create an admin account, and start adding monitors.
Monitor Types
Uptime Kuma supports a wide range of check types:
- HTTP(S): Check a URL, verify status code, match response body content.
- TCP Port: Verify a port is open and accepting connections.
- Ping: ICMP ping to check if a host is reachable.
- DNS: Verify DNS resolution returns the expected result.
- Docker Container: Check if a container is running (via Docker socket).
- Steam Game Server: Monitor game server availability.
- MQTT: Verify MQTT broker connectivity.
- gRPC: Check gRPC service health.
- Database: PostgreSQL, MySQL, MariaDB, Redis connection checks.
Setting Up Monitors
For a typical home lab, set up monitors for:
Infrastructure:
- Proxmox web UI (HTTPS, check for 200 response)
- Router admin page (HTTP)
- NAS web interface (HTTPS)
- Pi-hole admin (HTTP)
Services:
- Jellyfin (HTTP, check
/healthendpoint) - Portainer (HTTPS)
- Gitea (HTTP)
- Home Assistant (HTTP)
Network:
- Internet connectivity (ping
1.1.1.1or8.8.8.8) - Gateway/router (ping)
- Important devices (ping)
Check Intervals
Don't check everything every 30 seconds. Adjust intervals based on importance:
- Critical services (internet, DNS, NAS): Every 60 seconds
- Important services (Jellyfin, Home Assistant): Every 2-3 minutes
- Nice-to-have services (dashboards, dev tools): Every 5 minutes
More frequent checks mean faster alerting but more traffic and slightly higher resource usage.
Notifications
Uptime Kuma integrates with 90+ notification services:
- ntfy: Self-hosted push notifications (the best pairing for a home lab)
- Discord/Slack webhooks: If you use them
- Email (SMTP): Classic but slower
- Telegram: Popular for quick mobile alerts
- Gotify: Another self-hosted option
- Pushover: Reliable mobile notifications
Configure at least two notification channels for critical alerts. If your ntfy server goes down (because it's running on the same machine that crashed), you need a backup alerting path.
Status Pages
Uptime Kuma can generate public status pages — useful if you share services with family or friends:
- Go to Status Pages in the sidebar.
- Create a new page and add your monitors to groups.
- Assign a slug (e.g.,
/status). - Share the URL with anyone who needs to check service status.
Gatus
Gatus takes a different approach: configuration as code. Instead of clicking through a web UI, you define all monitors in a YAML file. This makes Gatus ideal for version-controlled, reproducible monitoring setups.
Deployment
services:
gatus:
image: twinproduction/gatus:latest
container_name: gatus
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- ./gatus/config.yaml:/config/config.yaml
Configuration
endpoints:
- name: Jellyfin
group: Media
url: "http://jellyfin.home.lab:8096/health"
interval: 2m
conditions:
- "[STATUS] == 200"
- "[RESPONSE_TIME] < 500"
- name: Proxmox
group: Infrastructure
url: "https://proxmox.home.lab:8006"
interval: 1m
client:
insecure: true
conditions:
- "[STATUS] == 200"
- name: Pi-hole DNS
group: Network
url: "1.1.1.1"
dns:
query-name: "google.com"
query-type: "A"
interval: 30s
conditions:
- "[DNS_RCODE] == NOERROR"
- name: Internet
group: Network
url: "icmp://1.1.1.1"
interval: 30s
conditions:
- "[CONNECTED] == true"
- "[RESPONSE_TIME] < 100"
alerting:
ntfy:
url: "https://ntfy.home.lab"
topic: "homelab-alerts"
default-alert:
enabled: true
failure-threshold: 3
success-threshold: 2
Why Choose Gatus
- GitOps-friendly: Your entire monitoring config is a YAML file you can version-control.
- Conditions-based: Define complex health checks with multiple conditions (status code AND response time AND body content).
- Lightweight: Uses less RAM than Uptime Kuma (~30MB vs ~100MB).
- No database: All state is in memory. Simple to deploy, nothing to back up (except the config file).
Gatus Limitations
- No web-based editing — all changes require editing the YAML file and restarting.
- Fewer monitor types than Uptime Kuma.
- Smaller community and fewer integrations.
- The status page UI is functional but less polished.
Statping-ng
Statping-ng focuses on public-facing status pages. While it monitors services, its primary value is presenting status information beautifully — think of it as a self-hosted StatusPage.io.
services:
statping:
image: adamboutcher/statping-ng:latest
container_name: statping
restart: unless-stopped
ports:
- "8085:8080"
volumes:
- ./statping:/app
Statping-ng is the best choice if your primary goal is a status page that family or users see, with monitoring as the secondary concern. For pure monitoring and alerting, Uptime Kuma or Gatus are stronger choices.
Comparison
| Feature | Uptime Kuma | Gatus | Statping-ng |
|---|---|---|---|
| Configuration | Web GUI | YAML file | Web GUI |
| Monitor types | 15+ | 8+ | 5+ |
| Notification services | 90+ | 10+ | 10+ |
| Status pages | Yes | Yes (basic) | Yes (beautiful) |
| Resource usage | ~100MB | ~30MB | ~80MB |
| Version-controllable | No (SQLite DB) | Yes (YAML) | No (SQLite DB) |
| Community size | Very large | Medium | Small |
| Active development | Very active | Active | Moderate |
Best Practices
Monitor the Monitor
Your monitoring tool is useless if it goes down silently. Solutions:
- Run it on a separate machine from what it monitors. If your Docker host crashes, the monitoring tool on that host crashes too.
- Set up an external ping using a free service like UptimeRobot or Healthchecks.io to verify your self-hosted monitor is alive.
- Run two instances on different machines, each monitoring the other.
Don't Alert on Transient Failures
A single failed check doesn't mean a service is down. Network blips, momentary high load, and garbage collection pauses all cause brief unavailability. Configure your monitors to alert only after consecutive failures:
- 2-3 consecutive failures for critical services
- 3-5 consecutive failures for less critical ones
This eliminates false positives while still catching real outages quickly.
Track Response Times
Monitoring isn't just about up/down status. Tracking response times over time reveals degradation trends. If your NAS response time has been creeping up from 50ms to 500ms over two weeks, something is slowly failing — maybe a disk, maybe a network issue. You won't notice this in daily use, but monitoring makes it visible.
Keep It Simple
Monitor what matters. You don't need 100 monitors checking every endpoint of every service. Focus on:
- Can I reach the service at all? (HTTP/TCP check)
- Is it responding within acceptable time? (Response time threshold)
- Is the underlying infrastructure healthy? (Ping checks on hosts)
Start with 10-15 monitors covering your critical services and expand only when you have a specific reason.
Uptime monitoring is the first thing you should set up after deploying services in your home lab. It takes 10 minutes and saves hours of troubleshooting by catching problems early and keeping a history of when and why things went wrong.