Self-Hosted Monitoring Showdown: Uptime Kuma vs Beszel vs Grafana vs Netdata (2026)

Self-Hosted Monitoring Showdown: Uptime Kuma vs Beszel vs Grafana vs Netdata (2026)

I ran all four monitoring tools side by side for two months. Here's which one you should actually self-host — and when you need more than one.

💡 Disclosure: This article contains affiliate links. If you make a purchase through these links, we may earn a small commission at no extra cost to you. This helps support the site and keeps the content free.

I ran four monitoring tools side by side for two months. Uptime Kuma, Beszel, Grafana + Prometheus, and Netdata. All on the same server, watching the same containers.

Why? Because I got tired of guessing. Every self-hosting thread recommends a different monitoring stack, and nobody explains when to pick what. So I tested them all.

Here’s what I learned.

The Monitoring Trap

When you start self-hosting, monitoring seems optional. Then your Jellyfin server dies at 2 AM and you don’t notice until you sit down for movie night. So you install Uptime Kuma — 5 minutes, done.

Then you wonder why your server’s being slow. CPU is pegged, but you have no idea what’s causing it. So you install Netdata.

Then you want historical data, trends, and alerting rules. So you set up Prometheus and Grafana.

Before you know it, you’re running four monitoring tools to do what one or two could do. I’ve been there. Let me save you the detour.

The Four Contenders

Uptime Kuma — The “Is It Up?” Tool

I covered Uptime Kuma in detail before, but here’s the short version: it’s a dead-simple uptime checker. Ping a URL, TCP port, or Docker container every N seconds. If it doesn’t respond, yell at you via Discord, Telegram, or email.

Setup time: 5 minutes. One docker-compose up -d and you’re done.

What it’s good at: Telling you something is currently broken. The status page feature is a nice bonus — I use it at status.selfhostable.dev so users can check without asking me.

What it’s terrible at: Why something broke. Uptime Kuma tells you “Jellyfin is down.” It doesn’t tell you Jellyfin ate 4GB of RAM and the OOM killer stepped in.

Best for: Anyone running services they care about. Seriously, this should be your first monitoring tool.

Beszel — The “What’s Eating My Resources?” Tool

Beszel is the new kid. It’s a lightweight Docker metrics dashboard that shows CPU, RAM, disk, and network per container. Think of it as a focused docker stats that doesn’t disappear when you close the terminal.

Setup time: 10 minutes. Agent + hub, both Docker containers.

What it’s good at: Giving you a real-time overview of resource usage across all your servers. The UI is clean, the data updates fast, and it barely uses any resources itself (~30MB RAM).

What it’s terrible at: Historical data and complex alerting. Beszel shows you what’s happening now, but it’s not designed for trend analysis or sophisticated rules.

Best for: The “I think something’s wrong, let me check” moments. I open Beszel before anything else when a service feels slow.

Netdata — The Firehose

Netdata is obsessive. It collects metrics every second — CPU per core, disk I/O per device, network per interface, database queries per second, even the temperature of your CPU. It’s like having a microscope on your server.

Setup time: 15 minutes. The Docker image works out of the box, but you’ll want to tune it for low-resource environments.

What it’s good at: Deep debugging. When a metric is off, Netdata has the data to tell you exactly when and why it changed. The anomaly detection is surprisingly good for a free tool.

What it’s terrible at: Being lightweight. Netdata uses ~100-200MB RAM and noticeable CPU if you enable all collectors. On a 1GB VPS, that hurts. Also, the UI is information-dense to the point of being overwhelming.

Best for: Debugging performance issues. I don’t keep Netdata running 24/7 — I spin it up when something’s acting weird and shut it down after.

Grafana + Prometheus — The “I Need Dashboards” Stack

This is the enterprise choice. Prometheus scrapes metrics from exporters (node_exporter for system, cAdvisor for Docker, etc.), stores them in a time-series database, and Grafana visualizes everything in custom dashboards.

Setup time: 45 minutes minimum. You need Prometheus, Grafana, at least one exporter, and configuration for each. Then you build or import dashboards.

What it’s good at: Everything, if you have the time. Custom dashboards, alerting rules with complex conditions, long-term historical data (months or years), multi-server aggregation.

What it’s terrible at: Quick setup. This is not a Saturday afternoon project if you want it done right. You’ll fight with PromQL syntax, dashboard JSON, and alert manager routing.

Best for: Serious setups — multiple servers, production services, or anyone who genuinely needs 6 months of historical data.

The Verdict: Which Should You Use?

Here’s the decision tree I’ve settled on:

Start with Uptime Kuma. Every single person running self-hosted services needs this. It takes 5 minutes, requires zero config, and covers the most common question: “Is my thing working?”

Add Beszel when you notice slowdowns. If you’re asking “why is my server slow” more than once a month, Beszel’s lightweight dashboard is the fastest path to an answer.

Use Netdata when you’re debugging. Don’t run it permanently unless you have spare resources. Spin it up, fix your issue, spin it down.

Commit to Grafana + Prometheus when you outgrow the others. When you need SLA tracking, multi-server dashboards, or alerting that understands context (e.g., “alert if CPU > 80% for 10 minutes, but not during backup hours”), that’s when the heavy stack earns its keep.

My personal setup after two months of testing: Uptime Kuma + Beszel running permanently. Netdata on standby. Grafana + Prometheus only on my production VPS that serves paying users.

Setup Quick-Start

Each of these tools runs beautifully in Docker. Here are the minimal compose files to get started:

Uptime Kuma

services:
  uptime-kuma:
    image: louislam/uptime-kuma:1
    container_name: uptime-kuma
    volumes:
      - ./data:/app/data
    ports:
      - "3001:3001"
    restart: unless-stopped

Beszel

services:
  beszel:
    image: henrygd/beszel
    container_name: beszel
    volumes:
      - ./data:/beszel/data
    ports:
      - "8090:8090"
    restart: unless-stopped

Then install the agent on each server you want to monitor.

Netdata

services:
  netdata:
    image: netdata/netdata
    container_name: netdata
    hostname: homelab
    cap_add:
      - SYS_PTRACE
    security_opt:
      - apparmor:unconfined
    volumes:
      - /etc/passwd:/host/etc/passwd:ro
      - /etc/group:/host/etc/group:ro
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
    ports:
      - "19999:19999"
    restart: unless-stopped

Grafana + Prometheus (minimal)

services:
  prometheus:
    image: prom/prometheus
    container_name: prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - ./prometheus-data:/prometheus
    ports:
      - "9090:9090"
    restart: unless-stopped

  grafana:
    image: grafana/grafana
    container_name: grafana
    volumes:
      - ./grafana-data:/var/lib/grafana
    ports:
      - "3000:3000"
    restart: unless-stopped

You’ll need a prometheus.yml config file for Prometheus to know what to scrape. The official docs have the template.

The One Thing Nobody Tells You

All four tools measure your server. None of them measure themselves. If your monitoring stack goes down, you’re blind.

Run a lightweight external uptime check — either UptimeRobot’s free tier or a simple cron job that pings a healthcheck endpoint. I use Uptime Kuma on a separate $5 VPS to monitor the monitoring tools on my main server. It sounds recursive because it is. It also works.

What I Use Now

After two months of running all four in parallel:

  • Uptime Kuma — Always on. Status page and critical uptime alerts.
  • Beszel — Always on. Quick resource check when things feel off.
  • Netdata — Docker compose file ready, spun up on demand for deep dives.
  • Grafana + Prometheus — Only on my production VPS. Overkill for my homelab.

This setup uses about 150MB RAM total (Uptime Kuma ~80MB, Beszel ~30MB, Prometheus ~40MB when running). Compare that to running all four at once which was eating nearly 500MB.

Pick the right tool for the job, not every tool for every job.

🚀NordVPN

Secure your monitoring server with a reliable VPN.

Get NordVPN →

Affiliate link — we may earn a commission at no extra cost to you.


Tested on a Hetzner CX22 (2 vCPU, 4GB RAM) running Debian 12 with Docker 27.x. Results may vary on lower-spec hardware — Uptime Kuma and Beszel both ran fine on a $5 VPS with 1GB RAM.

Stay in the loop 📬

Get self-hosting tutorials, tool reviews, and infrastructure tips delivered to your inbox. No spam, unsubscribe anytime.

Join 0 self-hosters. Free forever.