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.