Back to Blog
Tutorial9 min read2026-07-04

How to Self-Host Umami Web Analytics

Umami is a simple, fast, privacy-focused analytics tool that runs on a single PostgreSQL database. Here's how to self-host it end to end with auto-wired database credentials.

Ajay Kumar
Ajay Kumar
Founder & DevOps, PandaStack

Umami is a lovely piece of software: a privacy-focused, cookie-free web analytics platform that — unlike Plausible — runs on a *single* database. No ClickHouse, no separate event store. That simplicity makes it one of the easiest self-hosted analytics tools to deploy. This guide gets you from zero to tracking in a few minutes.

Why Umami is easy

Umami is a Next.js application backed by either PostgreSQL or MySQL. That's the entire architecture: one app, one database. Everything — users, websites, and the analytics events themselves — lives in that single relational database. For most sites this scales perfectly well, and it removes the operational burden of running a columnar event store.

AspectUmami
AppNext.js (single container)
DatabasePostgreSQL or MySQL (one DB)
CookiesNone
Tracking script~2 KB, served from your domain

Step 1: Provision the database

Create a single PostgreSQL database. Umami supports PostgreSQL and MySQL; PostgreSQL is the common choice. On PandaStack, provision a managed PostgreSQL instance (14.x or 16.x).

Step 2: Configure Umami

Umami is configured almost entirely through two environment variables:

# the connection string for your database
DATABASE_URL=postgresql://user:pass@host:5432/umami

# a random secret used to sign tokens — pin it!
APP_SECRET=<openssl rand -base64 32>

That's genuinely most of it. APP_SECRET must stay constant across restarts, or login sessions break.

Step 3: Deploy on PandaStack

This is where Umami's simplicity shines, and where auto-wired databases save you a step:

  1. 1Provision the managed PostgreSQL database.
  2. 2Create a container app using the official ghcr.io/umami-software/umami:postgresql-latest image.
  3. 3Link the database to the app. PandaStack injects a DATABASE_URL automatically — the exact variable Umami reads. No copy-pasting connection strings.
  4. 4Set APP_SECRET.
  5. 5Bind to the injected port (Umami listens on 3000 by default).

On first boot, the official image runs Prisma migrations to create the schema automatically. Watch the live logs for the migration to complete, then the app comes up.

Step 4: First login and adding a site

Umami ships with a default admin account (admin / umami). Change this password immediately after first login — it's a well-known default. Then:

  1. 1Go to Settings → Websites → Add website.
  2. 2Enter your domain.
  3. 3Copy the generated tracking snippet.

Step 5: Add the tracking script

<script defer
  src="https://analytics.yourdomain.com/script.js"
  data-website-id="<your-website-id>"></script>

Because it's first-party (served from your own domain), the script dodges most ad-blocker lists that target Google Analytics. With automatic SSL on your custom domain, it loads over HTTPS with no extra config.

Step 6: Useful features

  • Custom events — call umami.track('event-name') in your JS to record conversions, button clicks, etc.
  • Shareable dashboards — generate a public, read-only URL for a website's stats.
  • Multiple sites — track many domains from one Umami instance.
  • API — Umami exposes a REST API if you want to pull stats into your own tools.

Resource notes

Umami is genuinely lightweight. The Next.js app sips memory, and since events go into PostgreSQL, your main scaling lever is database size and indexing. For high-traffic sites, keep an eye on the events table growth and use Umami's data-retention settings. For typical projects, the smallest compute tiers handle it comfortably — making Umami a great fit for a free-tier deployment.

Umami vs. Plausible (quick take)

UmamiPlausible
DatabasesOne (Postgres/MySQL)Two (Postgres + ClickHouse)
Ops complexityLowMedium (ClickHouse)
Best forSimple, self-owned analyticsHigher volume, ClickHouse speed

Neither is "better" — Umami trades the columnar speed of ClickHouse for radically simpler operations. For most indie and small-team sites, that's the right trade.

Honest caveats

Because Umami stores events in a relational database, extremely high-traffic sites (tens of millions of events) will eventually feel query latency that a columnar store like ClickHouse would handle better — that's exactly when Plausible's architecture pays off. For the vast majority of sites, you'll never hit that wall. Also remember to change the default admin password; leaving it is the most common Umami security mistake.

Wrapping up

Umami is the easiest privacy-friendly analytics platform to self-host: one app, one database, two environment variables. With auto-wired database credentials it's nearly turnkey — link a database, set a secret, push.

PandaStack injects DATABASE_URL for you and runs the container with automatic SSL, so Umami fits neatly in the free tier. Deploy yours at https://dashboard.pandastack.io.

References

  • Umami documentation: https://umami.is/docs
  • Umami installation guide: https://umami.is/docs/install
  • Umami environment variables: https://umami.is/docs/environment-variables
  • Umami repository: https://github.com/umami-software/umami
  • Umami tracker / custom events: https://umami.is/docs/track-events

Ready to deploy?

Start free on PandaStack.

Start free on PandaStack

More in Tutorial

Browse all Tutorial articles →

See also