Skip to main content

A Better Umami Dashboard with Grafana

· 3 min read

Umami + Grafana dashboard overview

Umami is great. Lightweight, privacy-friendly, no cookies, no tracking drama. We use it ourselves on Hostim.dev, and we ship a one-click Umami template for anyone who wants simple, privacy-focused analytics.

But once you start relying on analytics to make actual decisions, you hit the limits pretty quickly.


Why the default Umami dashboard wasn't enough

Umami intentionally keeps things minimal, but some gaps become obvious:

  • No clear view of when visitors peak during the day
  • Hard to isolate bots from real traffic
  • No moving averages or trend smoothing
  • No grouped referrers (e.g. "search", "LLM", "other")
  • Limited visibility into relationships between sessions and custom events

None of this is criticism — Umami is intentionally simple. But sometimes you want more resolution.

So I took the quickest path:

Deploy Grafana → connect it to Umami's PostgreSQL → build a custom dashboard.

This took maybe ten minutes and unlocked:

  • Daily heatmap showing real traffic peaks
  • 7-day moving averages for referrers
  • Qualified sessions (≥2 pageviews) to filter out most bots
  • Selectable custom events
  • Raw stats for the selected period

Suddenly Umami became "actionable" instead of just "nice".


How to connect Grafana to Umami's PostgreSQL

Inside Grafana:

Configuration → Data sources → Add data source → PostgreSQL

Fill in the credentials from your Umami database and save.

You can now import our dashboard:

👉 Grafana.com Dashboard


Try it yourself

If you prefer to self-host on your own VPS, here is a complete Docker Compose stack for Umami, PostgreSQL, and Grafana.

Full Docker Compose stack

services:
postgres:
image: postgres:15
restart: always
environment:
POSTGRES_USER: umami
POSTGRES_PASSWORD: umami_pass
POSTGRES_DB: umami
volumes:
- postgres_data:/var/lib/postgresql/data

umami:
image: ghcr.io/umami-software/umami:postgres-latest
restart: always
depends_on:
- postgres
environment:
DATABASE_URL: postgres://umami:umami_pass@postgres:5432/umami
DATABASE_TYPE: postgresql
APP_SECRET: "replace_this_with_a_random_secret"
ports:
- "127.0.0.1:3000:3000"

grafana:
image: grafana/grafana:latest
restart: always
depends_on:
- postgres
environment: GF_SERVER_DOMAIN=grafana.example.com
GF_SERVER_ROOT_URL=https://grafana.example.com
ports:
- "127.0.0.1:3001:3000"
volumes:
- grafana_data:/var/lib/grafana

volumes:
postgres_data:
grafana_data:

Start everything:

docker compose up -d

Then:

In Grafana, configure a PostgreSQL data source:

Host: postgres
Port: 5432
User: umami
Password: umami_pass
Database: umami

Import the dashboard using the ID from Grafana.com.


Don't want to run a server?

If you don't want to manage Docker, OS maintenance, or networking, you can deploy the same stack on Hostim.dev by simply pasting the Compose file above when creating a new project.

  • Choose Paste Docker Compose
  • Use the YAML from this section

Hostim.dev will handle HTTPS, internal networking, logs, metrics, and persistence for all three services.

👉 Try Hostim.dev — deploy the full stack without touching SSH


Already running Umami on Hostim.dev?

If you deployed Umami using the one-click template, you don't need a new project. Just:

  1. Create a separate Grafana App in the same project
  2. Use the grafana/grafana:latest image
  3. Add the existing Umami PostgreSQL as a Grafana data source
  4. Import the dashboard JSON

Both apps run on the same private project network, so they can communicate without exposing ports or adjusting firewall rules.