comparing self-hosted
Uptime Kuma vs Gatus: clicks or YAML?
The two most-loved self-hosted monitors answer one question differently: should monitoring be clicked together in a dashboard, or declared in a file and reviewed in a pull request? Everything else follows from that split.
The table below is the whole comparison, unedited. Read it first if you like, it is the same one we would send you.
AGPL-3.0 · one binary · free tier · no card required
cat gatus.yaml
- endpoints:
- - name: api
- url: "https://api.acme.dev/health"
- interval: 60s
- conditions:
- - "[STATUS] == 200"
- - "[RESPONSE_TIME] < 300"
- # redeploy the config to apply
YAML ONLYgatus has no editing UI, so every change is a redeploy
cat uptimepage.tf
- resource "uptimepage_target" "api" {
- name = "api"
- interval = 60
- check = {
- type = "http"
- http = { url = "https://api.acme.dev/health" }
- }
- }
CONFIG AS CODEthe same monitor, declared, or clicked together in the UI
history | tail -1
- curl -X POST https://app.uptimepage.dev/api/v1/targets \
- -H "Authorization: Bearer $UPTIMEPAGE_TOKEN" \
- -d '{"name":"api","interval":60,
- "check":{"type":"http",
- "http":{"url":"https://api.acme.dev/health"}}}'
201 CREATEDmonitor live, and its first check runs straight away
pick uptime kuma if
It is your homelab, you want the widest check list and one-second intervals, and one shared login is fine.
pick gatus if
Every check belongs in Git, the dashboard is for you and your team, and nobody outside needs to see it.
pick uptimepage if
Customers need a status page they can subscribe to, teammates need their own accounts, and you still want the config in Git.
Start free →The facts, side by side
| Uptime Kuma | Gatus | Uptimepage | |
|---|---|---|---|
| license | MIT | Apache-2.0 | AGPL-3.0 |
| configuration | UI only | YAML only, read-only UI | UI + Terraform + REST + MCP |
| run it yourself | one container (Node) | tiny static binary | one binary + compose |
| hosted option | no | gatus.io, paid | yes, free tier |
| check types | 31 incl. DBs · MQTT · browser | 11 protocols incl. gRPC · SSH · WebSocket | HTTP · TCP · DNS · TLS · domain · ping · heartbeat · flow |
| fastest interval | 1s | no documented floor, default 60s | 60s free · 30s Pro · 10s self-hosted |
| status page | yes, custom domains | dashboard doubles as page | branded, own subdomain |
| page subscribers | RSS only | none | email · webhook |
| incidents | posted by hand | none | auto-opened from checks |
| teams & roles | single login | one basic-auth or OIDC gate | orgs + roles |
| alert channels | 94 services | 41 providers | Slack · Telegram · PagerDuty · SMS + more |
| community (GitHub stars) | ~89k | ~11.4k | young |
Kuma counts include the Apprise meta-provider and types implemented outside its monitor-types module; Gatus provider count from its README.
Star counts rounded from GitHub, July 2026.
Verified July 2026 against both repositories. Refresh when a project releases a new version.
The split that decides it
Uptime Kuma is a dashboard you click: add a monitor, pick a type, wire a notification, all stored in its database. Gatus has no editing UI: every endpoint is YAML in version control, the web UI is read-only, and a change means a config redeploy. Neither is wrong. One fits a homelab and a person who thinks in browsers; the other fits an engineer who thinks in Git and wants monitoring reviewed like code.
What each does well
Kuma wins on reach: 31 monitor types including databases, MQTT, SNMP and a real browser check, 94 notification services, one-second intervals since the 2.x line, and the biggest community in the category. Gatus wins on discipline: eleven endpoint protocols including gRPC, SSH, WebSocket and UDP, a condition language that asserts on status, response time, JSON body paths, certificate expiry and domain expiry, and a tiny static Go binary that can even run without a database.
What neither gives you
A customer-facing status page with subscribers, and a team. Kuma's status pages are real but nobody can subscribe to them, and the whole app is one shared login. Gatus's dashboard doubles as its status page: fine for an internal dashboard, not something you show customers, and its access control is one basic-auth or OIDC gate. Both check from wherever you run them, unless you set up more instances yourself or use Kuma's Globalping monitor type.
Where Uptimepage fits
If the YAML-versus-clicks debate ends with 'actually we need customers to see a status page and teammates to have accounts', that is the gap Uptimepage fills. Checks over HTTP, TCP, DNS, TLS, domain, ping, heartbeat and flow, configured in the UI or declared with the Terraform provider and REST API, organizations with roles, multi-region probes you can run yourself, and a branded status page with email and webhook subscribers where incidents open automatically. One binary, hosted free or AGPL self-hosted.
- 01Sign in with GitHub or Google. No card, no sales call.
- 02Paste a URL. The first check runs before you have finished reading this.
- 03Publish the status page, or export it to Terraform and keep it in Git.
api99.98%
p95 142ms · one incident in 45 days
dashboard99.91%
p95 318ms · two degraded days
webhooks99.99%
p95 88ms · no incidents
RESOLVED14 min
Elevated latency on the dashboard API
14:22 resolved, latency back under 300ms
14:08 opened automatically by the dashboard check
up degraded down 45 days · email & webhook subscribers