DEV Community

Cover image for A Better Umami Dashboard with Grafana
Pavel
Pavel

Posted on • Originally published at hostim.dev

A Better Umami Dashboard with Grafana

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:
Enter fullscreen mode Exit fullscreen mode

Start everything:

docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Then:

In Grafana, configure a PostgreSQL data source:

Host: postgres
Port: 5432
User: umami
Password: umami_pass
Database: umami
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)