← Back to Blog

Uptime Kuma vs Prometheus and Grafana: Which Monitoring Do You Need?

Published · by RS Computers

Monitoring Prometheus Self-hosting

Uptime Kuma vs Prometheus and Grafana is not really a contest, because the two answer different questions. Uptime Kuma checks your sites and ports from the outside and tells you within a minute or two that something stopped answering. Prometheus collects numbers from inside your servers every few seconds, Alertmanager turns them into alerts and Grafana draws them, so you can see why a server is slow or which disk is filling. If you run one or two websites, start with Uptime Kuma. If you run several servers and need to know what is happening inside them, add Prometheus and Grafana. Most teams end up with both. Below: how to connect them, what each cost us in RAM and disk in our lab, and what hosted alternatives charge.

Key facts, checked on 9 October 2026:

Pick this if: the short decision table

Your situationPickWhy
One to ten websites, and you want to know fast when one goes downUptime KumaOne container, a web form per check, alerts to Telegram, email and 90+ other services
Customers ask "is it down or is it me?"Uptime KumaPublic status pages are built in; Prometheus has none
A server is slow and you don't know whyPrometheus + node_exporter + GrafanaCPU, memory, disk and network every 15 seconds, with weeks of history to compare
You want a warning hours before a disk is fullPrometheus + AlertmanagerAlert rules can do maths on trends, such as "free space reaches zero in 4 hours"
Five or more servers, or more than one person on callBothKuma says what users see, Prometheus says why; Alertmanager groups and routes alerts
You don't want to run another server at allA hosted free tierUptimeRobot, Better Stack or Grafana Cloud, within the limits in the cost section below

One rule applies to every row: the monitor must not live on the server it watches. Our step-by-step guide to self-hosted monitoring on a VPS explains why and walks through the full installation with HTTPS and Telegram alerts. This article is the comparison; that one is the install manual.

What each tool actually does

Uptime Kuma: checks from the outside

Uptime Kuma is a free, open-source uptime monitor you host yourself. It does black-box monitoring, which means it tests a service the way a visitor would, without knowing anything about its insides. It opens your web page and checks the status code or a keyword on it, connects to a TCP port, pings a host, resolves a DNS record or waits for a "push" from a cron job. Each check gets an interval (60 seconds by default), retries and notifications, all set in a web interface.

What it cannot tell you is why. A red monitor says the shop timed out. It doesn't say the database ran out of memory a minute earlier.

Prometheus, Alertmanager and Grafana: numbers from the inside

Prometheus is a time-series database: it stores numbers tracked over time, such as "free bytes on / of server 2". Every 15 seconds Prometheus "scrapes" (downloads) a page of these numbers from small programs called exporters. The standard one for Linux is node_exporter, which reports CPU, memory, disk, network and about a thousand other values. Prometheus evaluates alert rules on those numbers and hands firing alerts to Alertmanager, which groups them, silences duplicates and sends them on. Grafana is the dashboard: it asks Prometheus questions in PromQL, Prometheus's query language, and draws the answers as graphs. This is white-box monitoring: you look inside the machine.

The price is effort. You write YAML files, learn some PromQL and install an exporter on every server. Outside checks need the separate blackbox_exporter, configured in a file, and there is still no status page.

Same failure, two views

We tested this in our lab. At 15:24:21 we stopped node_exporter on one of the three watched servers. Prometheus noticed at its next scrape and marked our InstanceDown alert as pending at 15:24:39. After the rule's two-minute wait it fired at 15:26:39, and Alertmanager received it the same second. Uptime Kuma had a TCP check on the same port. It logged "Connection failed" at 15:24:53 and again at 15:25:53, but kept the monitor in the "pending" state, because we had set two retries. We started the exporter again before the third check, so Kuma never sent a "down" alert. Both tools wait before they shout, and how long you let them wait decides how many false alarms wake you at night.

What we measured in our lab

We ran both setups on a test server in our Amsterdam network: Debian 13 containers with 2 vCPU and 3 GB of RAM each, Docker 29.9.0 from Docker's own repository, and everything started by a normal user called mon that is in the docker group. The targets were two small Debian 13 containers running nginx and the Debian package of node_exporter (1.9.0).

Measured in our labUptime KumaPrometheus stack
RAM at the start (Kuma with no monitors, the stack in its first minute)148 MB582 MB (Prometheus 52, Grafana 505, Alertmanager 14, node_exporter 11)
RAM with 50 monitors / 3 scraped servers, after about 35 minutes168 MB641 MB (Prometheus 53, Grafana 554, Alertmanager 18, node_exporter 16)
Same, with Grafana's preinstalled plugins switched off-355 MB (Prometheus 47, Grafana 278, Alertmanager 15, node_exporter 15)
Image size as Docker lists it2.49 GB2.46 GB (Grafana alone 1.94 GB)
Data after about 35 minutes4.6 MB (1,809 check results)3.5 MB of metrics plus 497 MB of Grafana data, almost all of it plugins
Disk used by Docker's folders in total4.2 GB4.1 GB (with the lean Grafana)
First docker compose up -d25 seconds, image download included16 seconds (the Prometheus image was already pulled for promtool)

RAM figures come from docker stats. Three things surprised us.

  1. Uptime Kuma 2 is a heavy image. It ships Chromium (for browser-based checks) and an embedded MariaDB server, so Docker lists the image at 2.49 GB even if you use neither. In memory it stays light: adding 50 monitors moved it from 148 MB to 168 MB.
  2. Grafana 13 turned out to be the biggest part of the stack. On first start it downloaded 17 plugins (476 MB) and ran most of them as separate processes of 20 to 35 MB each. Setting GF_PLUGINS_PREINSTALL_DISABLED=true, which the Grafana configuration docs describe as disabling "all preinstalled plugins", cut Grafana from 554 MB to 278 MB and its plugin folder from 476 MB to nothing. The built-in Prometheus data source still worked: Grafana's health check answered "Successfully queried the Prometheus API." You lose the extra apps such as the Drilldown views until you install them yourself.
  3. Prometheus itself is small at this scale. Each Debian server exposed 1,173 series through node_exporter. With five targets, Prometheus took in about 290 samples per second, which by the 1 to 2 bytes per sample rule is 25 to 50 MB of disk per day, or 0.4 to 0.75 GB for the default 15 days.

A minimal Prometheus setup, checked with promtool

You don't need much configuration to start. Install Docker first (our Docker on a VPS guide covers it), then create a folder with four files. This is the compose.yaml we ran; it publishes Prometheus, Alertmanager and Grafana only on 127.0.0.1, so they are not open to the internet:

# as the mon user, in ~/metrics/compose.yaml
services:
  prometheus:
    image: prom/prometheus:v3.13.4
    restart: unless-stopped
    command:
      - --config.file=/etc/prometheus/prometheus.yml
      - --storage.tsdb.retention.time=15d
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - ./rules.yml:/etc/prometheus/rules.yml:ro
      - prom-data:/prometheus
    ports:
      - "127.0.0.1:9090:9090"
  alertmanager:
    image: prom/alertmanager:v0.34.1
    restart: unless-stopped
    volumes:
      - ./alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
    ports:
      - "127.0.0.1:9093:9093"
  node-exporter:
    image: prom/node-exporter:v1.12.1
    restart: unless-stopped
    command: --path.rootfs=/host
    pid: host
    volumes:
      - /:/host:ro,rslave
  grafana:
    image: grafana/grafana:13.2.3
    restart: unless-stopped
    environment:
      - GF_PLUGINS_PREINSTALL_DISABLED=true
    volumes:
      - grafana-data:/var/lib/grafana
    ports:
      - "127.0.0.1:3000:3000"
volumes:
  prom-data:
  grafana-data:

The scrape configuration. Replace the two private addresses with your own servers, each running node_exporter on port 9100 and reachable only from the monitor, for example over WireGuard:

# as the mon user, in ~/metrics/prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s

alerting:
  alertmanagers:
    - static_configs:
        - targets: ["alertmanager:9093"]

rule_files:
  - /etc/prometheus/rules.yml

scrape_configs:
  - job_name: prometheus
    static_configs:
      - targets: ["localhost:9090"]
  - job_name: node
    static_configs:
      - targets:
          - node-exporter:9100
          - 10.141.188.196:9100
          - 10.141.188.228:9100

Two alert rules: one for a server that stops answering, one that looks at the last hour of disk use and fires if free space will reach zero within four hours:

# as the mon user, in ~/metrics/rules.yml
groups:
  - name: basics
    rules:
      - alert: InstanceDown
        expr: up == 0
        for: 2m
        labels:
          severity: page
        annotations:
          summary: "{{ $labels.instance }} has not answered for 2 minutes"
      - alert: DiskFullIn4Hours
        expr: predict_linear(node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"}[1h], 4 * 3600) < 0
        for: 15m
        labels:
          severity: page
        annotations:
          summary: "{{ $labels.instance }} {{ $labels.mountpoint }} will be full within 4 hours"

And the smallest valid Alertmanager file. It accepts alerts and sends them nowhere yet; the full guide adds Telegram:

# as the mon user, in ~/metrics/alertmanager.yml
route:
  receiver: default
  group_wait: 30s
  repeat_interval: 4h
receivers:
  - name: default

Before you start anything, let Prometheus's own tool check the files. promtool is inside the Prometheus image, so nothing extra is installed:

# as the mon user, in ~/metrics
docker run --rm -v ./:/etc/prometheus:ro --entrypoint promtool prom/prometheus:v3.13.4 check config /etc/prometheus/prometheus.yml
docker run --rm -v ./alertmanager.yml:/am.yml:ro --entrypoint amtool prom/alertmanager:v0.34.1 check-config /am.yml

What we saw (the first command also checks the rule file it finds in the config):

Checking /etc/prometheus/prometheus.yml
  SUCCESS: 1 rule files found
 SUCCESS: /etc/prometheus/prometheus.yml is valid prometheus config file syntax

Checking /etc/prometheus/rules.yml
  SUCCESS: 2 rules found

Checking '/am.yml'  SUCCESS

A typo, such as a missing space after a dash, makes promtool print the line number instead of SUCCESS. Now start the stack and list the targets:

# as the mon user, in ~/metrics
docker compose up -d
curl -s localhost:9090/api/v1/targets | grep -o '"health":"[a-z]*"' | sort | uniq -c

With the two servers above plus the local node_exporter and Prometheus, you should see 4 "health":"up". When you change a rule later, check it with promtool check rules the same way and reload Prometheus without a restart:

# as the mon user, in ~/metrics
docker compose kill -s SIGHUP prometheus

Compose prints "Killing" and "Killed", which sounds worse than it is: it only delivered the signal. Prometheus kept running and logged "Completed loading of configuration file".

Using both: let Prometheus read Uptime Kuma

Uptime Kuma publishes its results at /metrics, so Grafana can show "the shop was down" on the same graph as "the database ran out of memory". In our 2.5.5 install the endpoint exposed four metric names: monitor_status, monitor_response_time, monitor_response_time_seconds and monitor_uptime_ratio.

The endpoint is protected. Create an API key in Uptime Kuma under Settings, then API Keys. The Uptime Kuma wiki warns that once the first key exists, basic authentication with your login password is permanently disabled for this endpoint, so it accepts only API keys from then on. Save the key in a file and test it, with an empty user name and the key as the password:

# as the mon user, on the Uptime Kuma server, after saving the key in ~/kuma/kuma_api_key
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:3001/metrics
curl -s -u ":$(cat ~/kuma/kuma_api_key)" http://127.0.0.1:3001/metrics | grep -c '^monitor_'

We got 401 without the key and 400 lines with it, for our 50 monitors. Copy the key file next to prometheus.yml, give it mode 644 because the Prometheus container runs as the user nobody, mount it in compose.yaml with - ./kuma_api_key:/etc/prometheus/kuma_api_key:ro under the Prometheus volumes, and add one more job at the end of prometheus.yml:

# as the mon user, appended to ~/metrics/prometheus.yml
  - job_name: uptime-kuma
    basic_auth:
      password_file: /etc/prometheus/kuma_api_key
    static_configs:
      - targets: ["10.141.188.6:3001"]

In our lab Kuma ran on another machine, so we also published its port on the private address 10.141.188.6. Use your monitor's private or WireGuard address, never a public one. After docker compose up -d, the query count(monitor_status == 1) in Prometheus returned 50: all fifty Kuma checks green, now stored for 15 days and ready for a Grafana panel.

Self-hosted or hosted: what the free tiers give you

If you'd rather not run a monitor yourself, three well-known services have free tiers. The figures below come from each vendor's own pricing page on 9 October 2026; they change often, so check before you sign up.

ServiceFree tierFirst paid stepGood for
UptimeRobot50 monitors, checked every 5 minutes, 1 basic status page, 3 months of data; the page pitches it at hobby and non-profit projectsSolo from $9 a month billed yearly, checks every 60 secondsOutside checks without a server
Better Stack10 monitors and heartbeats together, 1 status page, checks every 3 minutes (docs)$29 a month billed yearly ($34 monthly) per responder, 10 monitors included, then $21 a month billed yearly ($25 monthly) for each 50 more; paid checks can run every 30 secondsOn-call rotas and incident handling
Grafana Cloud10,000 active metric series, 14 days of retention, 3 Grafana users, 100,000 synthetic API test runs a monthPro: $19 a month platform fee with 10,000 series, then from $6.50 per 1,000 series; 13 months of metric retentionHosted Prometheus and Grafana

Our lab numbers next to those limits:

A sensible mix for many small companies: Uptime Kuma and Prometheus on your own monitoring VPS, plus one free hosted check that watches the monitor itself.

Which server size you need

Size the monitor for what it runs, and keep it in a different city from the servers it watches. RS Computers runs KVM servers in Amsterdam (Netherlands), Dublin (Ireland) and Prishtina (Kosovo), all on NVMe with unmetered traffic and their own IPv4 and IPv6 addresses, so the watched servers and the monitor can sit in different countries. Availability by city is on the plans page.

What you runPlanWhy, based on our lab
Uptime Kuma alone, from a handful of checks to a hundred or soVPS Nano (1 vCPU, 1 GB RAM, 20 GB NVMe)Kuma used under 200 MB of RAM with 50 checks, and Docker's folders took 4.2 GB of the 20 GB disk
Prometheus, Alertmanager and lean Grafana for up to about ten serversVPS Micro (2 vCPU, 2 GB RAM, 40 GB NVMe)The lean stack used about 355 MB; leaves room for Docker, the system and queries
Both tools on one server, or Grafana with all pluginsVPS Mini (4 vCPU, 4 GB RAM, 80 GB NVMe)Kuma plus the default stack used about 810 MB of RAM before the operating system, and about 8 to 9 GB of disk for Docker
Dozens of servers, months of retention, or logs as wellVDS Small (4 vCPU, 8 GB RAM, 240 GB NVMe, 10 Gb/s)Disk and RAM grow with the number of series and the retention you keep

vCPUs on all plans are shared, which is fine for monitoring: in our lab none of these containers used more than a few percent of a core. If the monitor outgrows its plan, upgrade it from the client area; it stays the same server after a short reboot. Then put HTTPS in front of the web interfaces with our Caddy, Nginx or Traefik guide instead of opening ports 3000 and 3001.

Frequently asked questions

Is Uptime Kuma a replacement for Prometheus?

No. Uptime Kuma checks whether a site, port or host answers from the outside and alerts you when it doesn't. Prometheus collects metrics such as CPU, memory and disk from inside your servers and keeps their history. Kuma tells you that something is down; Prometheus helps you find out why.

Can Prometheus do uptime checks like Uptime Kuma?

Yes, with the separate blackbox_exporter, which probes HTTP, TCP, ICMP and DNS targets that you list in a configuration file. It has no web form and no status page, so for simple website checks Uptime Kuma is quicker to set up and easier to hand to non-technical colleagues.

How much RAM does Uptime Kuma need?

In our lab, Uptime Kuma 2.5.5 used 148 MB of RAM with no monitors and 168 MB with 50 monitors checked every 60 seconds, measured with docker stats. A 1 GB VPS is enough for it on its own. Its Docker image is large, 2.49 GB, because it includes Chromium and MariaDB.

Do I need Grafana if I have Prometheus?

Prometheus has a basic built-in page for running queries and simple graphs, which is enough for testing. For dashboards you keep open or share with a team, Grafana is the usual choice.

Can Grafana show Uptime Kuma data?

Yes, through Prometheus. Uptime Kuma exposes its check results at /metrics, protected by an API key. Prometheus scrapes that endpoint like any exporter, and Grafana then charts monitor_status and response times next to your server metrics.

Is the Grafana Cloud free tier enough for a small company?

For a few servers, often yes. The free tier includes 10,000 active metric series and 14 days of retention (checked 9 October 2026). In our lab one Debian server with default node_exporter produced 1,173 series, so about eight servers fit before you trim collectors or move to the paid Pro tier.

Start with the question you can't answer today

If you don't know when your site goes down, set up Uptime Kuma this week; it takes an evening. If you know it went down but not why, add Prometheus, node_exporter and Grafana, using the files above and the full installation guide. Pick a monitoring server on the VPS and VDS plans page, in a different city from the servers it watches. If you'd like us to set it up for you, the work is quoted per job: message us on Telegram.

← All articles

Chat on Telegram