
Should I self-host Umami Cloud?
Same software as the $20/mo cloud, two containers, no event caps. The rare analytics verdict where capability is 100% by construction.
The math (nothing hidden, including your time)
| Umami Cloud (Pro) | $20.00/mo |
| VPS share + storage | −$1.20/mo |
| Your maintenance: 15 min/mo at $20/h | −$5.00/mo |
| Net saving | $13.80/mo |
| Setup: 40 min measured (one-time) | $13.33 |
| Break-even | 1.0 months |
| Markup Index (price ÷ real self-host cost) | 3.2× |
Price: source, checked 2026-08-06. Inputs are stored in git; every number above is derived, never hand-written.
What you lose
- Their infrastructure eating your traffic spikes
- Managed uptime on the tracker script origin
What you're paying Umami Cloud for
- privacy-friendly web analytics
- events & goals
- multi-site
- shareable dashboards

Ranked alternatives
Pageviews, referrers and custom events on a hostname you own, from one container and a PostgreSQL, with no monthly event meter.
The same privacy-first analytics dashboard the vendor sells, on your own domain, with no pageview meter counting against you.
Hardware
Runs comfortably on Raspberry Pi.
The tested compose file (our evidence, CI-booted)
# Umami — privacy-friendly web analytics, same software as Umami Cloud.
# Image is ghcr.io-hosted: boot-verified by the CI runner (Docker-Hub-only mirrors can't pull).
services:
umami:
image: ghcr.io/umami-software/umami:postgresql-latest
container_name: umami
restart: unless-stopped
depends_on:
umami-db:
condition: service_healthy
environment:
DATABASE_URL: postgresql://umami:umami@umami-db:5432/umami
DATABASE_TYPE: postgresql
APP_SECRET: 4c8e2b6f0a9d3c7e1b5f8a2d6c0e4b8f # throwaway test value
ports:
- "3004:3000"
healthcheck:
test: ["CMD-SHELL", "node -e \"fetch('http://localhost:3000/api/heartbeat').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))\""]
interval: 5s
timeout: 5s
retries: 36
start_period: 30s
umami-db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: umami
POSTGRES_PASSWORD: umami
POSTGRES_DB: umami
volumes:
- umami-pg:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U umami"]
interval: 5s
timeout: 5s
retries: 12
volumes:
umami-pg:
Want a guided install instead? caniselfhostit.com/umami-cloud has AI-agent prompts that assume a bare machine — that's their half of the stool, and it's good.
Verification
Protocol v1 · verified by zernonia on 2026-08-10 · setup measured at 40 min · AI assistant: claude-code (allowed & stated)
What broke
- Image is ghcr.io-hosted — Docker-Hub-only mirrors (ours, during verification) can't pull it; this pair's compose boot is verified by the CI runner
Full timed log
# Timed setup log: Umami Cloud → umami **Protocol:** v1 · **Verified by:** zernonia · **Date:** 2026-08-10 **Assistant:** claude-code · **Environment:** containerized runner, 2 vCPU class, Docker 29.3 / Compose v5.1 ## Timeline | Step | Time | |---|---| | Read upstream docs, draft compose with healthcheck | ~13 min | | Boot in our verification environment blocked (ghcr.io-only images, model download, or the microVM's ipv6.disable=1 kernel) — **compose boot is certified by the CI runner** (`compose-check` gate, per-PR + weekly) | — | | Endpoint-level workflow check (login/health/API serve) + re-run from clean volumes | ~13 min | | **Total: ~40 min** | | Boot and endpoint checks are machine-verified; `setup_min` is the wall-clock total for this session including authoring, diagnosis and re-runs. Endpoint-level ≠ full human UI workflow — dispute anything that doesn't reproduce (CONTRIBUTING.md). ## What broke - Image is ghcr.io-hosted — Docker-Hub-only mirrors (ours, during verification) can't pull it; this pair's compose boot is verified by the CI runner ## Verdict-relevant notes - Default login admin/umami — change it before the container meets the internet.
Verdict history
- 2026-08-10: unscored → YES — Initial verdict: Same software as the $20/mo cloud, two containers, no event caps. The rare analytics verdict where capability is 100% by construction.
