DEV Community

Cal Merritt
Cal Merritt

Posted on

I ran GA and Umami side by side for a month. GA was missing half my visitors.

I didn't switch off Google Analytics because of privacy principles. I switched because the numbers stopped making sense.

A post I wrote got popular, and a friend texted me saying it was getting passed around. I opened GA and saw a modest uptick. Nothing dramatic. But comments kept coming in, people kept mentioning it. Something felt off. So I did something I should have done a long time ago: I installed a second analytics tool and ran them both simultaneously.

For a month, Umami and Google Analytics ran on the same site, tracking the same pages. At the end I compared them.

GA showed about 40% fewer visitors.

Not a rounding error. Not a misconfiguration. Just... gone. The gap was biggest on posts that did well on Hacker News or got shared in developer circles. Which makes sense once you think about it — that audience runs uBlock Origin the way most people run antivirus. It's just on. Always. And GA is one of the first things it kills.

That was the moment I stopped treating this as a privacy debate and started treating it as an accuracy problem.


What self-hosting actually looks like

I know "self hosted" sounds like it implies a homelab and a weekend of suffering. It doesn't. The short version: you rent a small Linux server, point a subdomain at it, and run a Docker Compose file. The whole thing took me one afternoon including the time I spent reading documentation.

Here's the Umami setup I use. This is the entire docker-compose.yml:

services:
  umami:
    image: ghcr.io/umami-software/umami:postgresql-latest
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgresql://umami:yourpassword@db:5432/umami
      DATABASE_TYPE: postgresql
      APP_SECRET: generate-this-with-openssl-rand-hex-32
    depends_on:
      - db
    restart: always

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: umami
      POSTGRES_USER: umami
      POSTGRES_PASSWORD: yourpassword
    volumes:
      - umami-db-data:/var/lib/postgresql/data
    restart: always

volumes:
  umami-db-data:
Enter fullscreen mode Exit fullscreen mode

Run docker compose up -d, wait 30 seconds, open a browser. That's most of it. You still need Caddy or nginx in front of it for HTTPS, but that's trivial.

The tracking snippet you drop into your site:

<script async src="https://your-umami.yourdomain.com/script.js"
  data-website-id="the-id-from-your-dashboard"></script>
Enter fullscreen mode Exit fullscreen mode

No cookies. No consent banner needed. The script is about 2KB. Your visitors who run blockers will mostly still be counted because the request comes from your domain, not a known tracking domain.

What I actually look at

The Umami dashboard is one page. Visitors, pageviews, referrers, top pages, countries, devices. Everything at once. I check it the same way I check the weather: quickly, without much thought, when I'm curious. I don't have goals set up, I don't have funnels, I don't have conversion tracking. I just want to know if people are reading what I write and where they came from.

If that's also what you want, Umami is probably all you need. It runs on the same server as three other things I self host and uses barely any resources.

If you want something more, maybe proper funnels, session recordings, heatmaps: Matomo does all of that. It's heavier to run and the interface is busier, but it's been around since 2007 under its old name Piwik and it's genuinely good software.

The stuff that actually matters

You own the data. When Google shut down Universal Analytics in 2023, everyone scrambled to export their history before the window closed. That doesn't happen when the database is on your server.

It's cheaper than you think. $6/month for a server that runs analytics for every site you have, forever, with no per-site fees or pageview caps. I have four sites pointed at the same Umami instance.

The GDPR situation. Multiple EU data protection authorities have ruled that standard Google Analytics implementations are non-compliant because of data transfers to US servers. I'm not a lawyer, I'm not going to tell you what to do. But if any of your users are in Europe, and they probably are, this is a real thing worth knowing about.

The accuracy is real. On a general audience site the difference might be 10-15%. On a developer-focused site or anything that gets traction on HN or Reddit, it can easily be 50%. The Plausible team published a study comparing their stats against GA on a site that went viral on HN and found GA was missing 58% of visitors. That's not a small rounding error, that's a completely different picture of your traffic.

Which tool

I've run Umami for a couple of years now and it's been completely uneventful, which is exactly what I want from infrastructure. Plausible Community Edition is what I'd reach for if I wanted something with more polish. The dashboard is genuinely beautiful and the single-page layout is exactly right. GoatCounter is worth knowing about if you want the absolute minimum: single binary, SQLite database, runs on a $3 server.

If you want a more thorough breakdown of what each tool actually feels like to use, resource requirements, who each one is for, and step by step installs, I put all of that in a guide: Your Data, Actually. Nine tools covered. Three full installs. Written for people who aren't sysadmins.

But honestly, even without the guide, pick Umami, follow the Docker Compose setup above, spend an afternoon on it. Your traffic numbers will be more accurate, you won't owe anyone a cookie banner, and you'll stop subsidizing Google's ad business with your visitors' data.

Top comments (0)