DEV Community

Cyborgmachine
Cyborgmachine

Posted on Edited on Originally published at cyborgmachine.dev

Why I Use Umami Instead of Google Analytics (And Don't Have a Cookie Banner)

When I was setting up analytics for my blog, Google Analytics seemed like the obvious choice. But once I looked at what it actually requires — a tracking script, a cookie consent banner, a cookie policy page, conditional script loading — it felt like way too much for a personal site that doesn't run ads or retargeting.

So I went with Umami instead. It's open-source, self-hosted, and doesn't use cookies by default. For my setup, that means I don't need a consent banner, and my data stays on my own server.

What's Actually Wrong With Google Analytics

Cookies and consent overhead. GA sets first-party tracking cookies (_ga, _ga_<container-id>). Under GDPR, that means you need a proper cookie consent banner with category-by-category opt-in. And users who reject cookies simply won't be tracked — so your data is incomplete from day one.

Your data lives on Google's servers. They process it for their own purposes too. You get a "free" analytics tool, and Google gets visibility into your traffic patterns.

It's heavy and overcomplicated. The GA4 snippet loads around 90–135KB of JavaScript. The dashboard is built for enterprise use cases — overkill if you just want pageviews, referrers, and device stats.

Why Umami

Umami is an open-source, self-hosted analytics platform that gives you the metrics you need without the privacy baggage.

  • No cookies — sessions are identified using a hash of IP + user agent + website ID and no raw personal data is stored. That's why I don't show a consent banner on my site.
  • Your data, your server — self-hosting on a VPS means no third party ever sees your analytics
  • Lightweight — the tracking script is under 2KB (vs GA's 90KB+)
  • Clean dashboard — one page with pageviews, unique visitors, bounce rate, session duration, referrers, browsers, OS, devices, and geo data
  • Easy to deploy — Docker + PostgreSQL, that's it

How I Set It Up

Here's the Docker Compose config I use:

umami:
  image: ghcr.io/umami-software/umami:latest
  container_name: umami
  environment:
    DATABASE_URL: postgresql://umami:${UMAMI_DB_PASSWORD}@umami-db:5432/umami
    APP_SECRET: ${UMAMI_APP_SECRET}
    TWO_FACTOR_ENCRYPTION_KEY: ${UMAMI_2FA_KEY}
  depends_on:
    umami-db:
      condition: service_healthy
  init: true
  restart: always
  healthcheck:
    test: ["CMD-SHELL", "curl -f http://localhost:3000/api/heartbeat"]
    interval: 5s
    timeout: 5s
    retries: 5

umami-db:
  image: postgres:16-alpine
  container_name: umami-db
  environment:
    POSTGRES_DB: umami
    POSTGRES_USER: umami
    POSTGRES_PASSWORD: ${UMAMI_DB_PASSWORD}
  volumes:
    - umami-db-data:/var/lib/postgresql/data
  healthcheck:
    test: ["CMD-SHELL", "pg_isready -U umami"]
    interval: 5s
    timeout: 5s
    retries: 5
  restart: always
Enter fullscreen mode Exit fullscreen mode

After docker compose up -d:

  1. Log in at port 3000 with admin / umami, change the password immediately
  2. Go to Settings → Websites → Add website
  3. Copy the tracking script into your site's <head>

In Next.js I use the Script component:

import Script from 'next/script';

<Script
  defer
  src="https://your-umami-instance.com/script.js"
  data-website-id="your-website-id"
  strategy="afterInteractive"
/>
Enter fullscreen mode Exit fullscreen mode

No Cookie Banner, By Design

With Google Analytics I would have needed to build consent UI that loads before tracking, implement granular consent categories, write a cookie policy, and add conditional script loading. All of that for a personal blog.

With Umami in its default configuration, the script just loads, and I don't show a banner. Nobody has to click through a consent popup, so the UX is cleaner and the data is more complete. (This is my own assessment, not legal advice. Rules vary by country, so check what applies to you.)

What You Give Up

To be fair, there are trade-offs:

  • No cross-site tracking — you can't follow users across domains or build retargeting audiences
  • No Google Ads integration — if you run paid campaigns, you'll need GA for conversion attribution
  • Simpler event tracking — Umami's custom events don't have GA4-level granularity for complex funnels
  • Self-hosting maintenance — you're responsible for updates and database backups (minimal, but it's there)

For a blog or portfolio, none of these matter. You're not retargeting visitors or running ad funnels.

GA vs Umami at a Glance

Feature Google Analytics Umami
Cookies Yes (_ga, _ga_<id>) None
Cookie banner required Yes (GDPR) No
Data location Google's servers Your server
Script size ~90KB+ <2KB
Self-hostable No Yes
Price Free (data as payment) Free (open source)
Setup complexity Moderate Low (Docker)
Dashboard Complex, enterprise-focused Simple, one-page
Cross-site tracking Yes No
Ad integration Yes No

Bottom Line

If you're running a personal site, blog, or small project — think about whether you actually need Google Analytics. Umami gives you everything that matters (who visits, where they come from, what they read) without the privacy infrastructure overhead. Setup takes about fifteen minutes if you already have Docker running. If you enable extra features or add other scripts, re-check whether you need consent.

Umami on GitHub →

Top comments (3)

Collapse
 
omyvnss profile image
Om Yaduvanshi •

the self-hosting maintenance point is the one people underestimate. running postgres for analytics is easy until it isn't: backups, updates, the odd disk-full at 3am. i self-host a few things and that trade-off is exactly why i didn't self-host analytics for my own site either.

the trade-off list is honest though, especially the events one. umami's custom events feel basic if you're used to ga4 funnels, and it's good that you said it instead of pretending nothing was lost.

Collapse
 
cyborgmachine profile image
Cyborgmachine •

Totally agree. Most of us who self-host have been through this already. Regular backups and log/file rotation save a lot of disk space and a lot of headaches. And it's much better to test the whole setup, including restoring from a backup, before it goes to production.

Collapse
 
omyvnss profile image
Om Yaduvanshi •

the restore test is the part everyone skips. i've met plenty of people with pristine backup schedules and zero successful restores, which means the backup exists but the recovery doesn't.