Google Analytics has been the default for so long that most of us never questioned it. But after getting a GDPR consent banner request from a client last year, I ended up going down the rabbit hole of privacy-focused alternatives. I've now migrated four projects off GA4 — two to Plausible, one to Fathom, and one to self-hosted Umami.
Here's what I learned about each, with honest tradeoffs.
Why bother switching?
GA4 isn't bad at what it does. The problem is what it does. Cookie banners, consent management, IP anonymization toggles, data retention policies — the compliance overhead adds up fast, especially if you have EU visitors.
The privacy-focused alternatives share a common philosophy:
- No cookies (or only first-party, non-identifying ones)
- No personal data collection
- GDPR/CCPA/PECR compliant out of the box
- Lightweight scripts (usually under 2KB)
- Simpler dashboards focused on what you actually need
The tradeoff? You lose the deep funnel analysis, ad-targeting integrations, and the audience-building features. For a content site or SaaS dashboard, I haven't missed any of it.
Side-by-side comparison
Here's the breakdown after running all three in production:
Plausible
Hosted at plausible.io, open source on GitHub. Self-hostable but most folks use the cloud version.
- Script size: ~1KB
- Pricing: Starts at $9/mo for 10k pageviews
- Hosting: EU-based servers
- Self-host: Yes (Community Edition)
The install is dead simple:
<!-- Drop in <head>, that's it -->
<script defer data-domain="yoursite.com" src="https://plausible.io/js/script.js"></script>Custom events are clean too:
// Track a signup conversion
window.plausible('Signup', {
props: { plan: 'pro' } // optional custom properties
});Fathom
Not open source — fully hosted SaaS at usefathom.com. Founded by two indie devs who wanted a Google Analytics replacement without the ethical baggage.
- Script size: ~2KB
- Pricing: Starts at $15/mo for 100k pageviews
- Hosting: Multi-region (Canada, EU, US)
- Self-host: No (they had Fathom Lite open source but it's deprecated)
Install is similar:
<!-- Replace YOUR-SITE-ID with the one from your dashboard -->
<script src="https://cdn.usefathom.com/script.js" data-site="YOUR-SITE-ID" defer></script>Event tracking uses a different API:
// Goals are pre-defined in dashboard, you trigger by ID
fathom.trackEvent('signup_completed');Umami
This is the one I'm running self-hosted. MIT-licensed, runs on Node.js with Postgres or MySQL.
- Script size: ~2KB
- Pricing: Free if self-hosted, or Umami Cloud has a free tier
- Hosting: Self-host anywhere, or use Umami Cloud
- Self-host: Yes, this is the primary use case
Docker compose setup is genuinely a 5-minute job:
# docker-compose.yml
services:
umami:
image: ghcr.io/umami-software/umami:postgresql-latest
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://umami:pass@db:5432/umami
DATABASE_TYPE: postgresql
APP_SECRET: replace-this-with-a-random-string
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_DB: umami
POSTGRES_USER: umami
POSTGRES_PASSWORD: pass
volumes:
- umami-db:/var/lib/postgresql/data
volumes:
umami-db:Client install:
<script defer src="https://your-umami-domain.com/script.js" data-website-id="YOUR-ID"></script>Event tracking:
// Simple event with optional data
umami.track('signup', { plan: 'pro' });
// Or a custom event with full control over name
umami.track(props => ({
...props,
name: 'video_play',
data: { video_id: 'abc123' }
}));Migration: GA4 to Umami
This is the migration I've done most recently, so I'll walk through it.
Step 1: Remove GA4 tags
Strip out the gtag snippet. If you're using Google Tag Manager, you can leave the container in place and just disable the GA4 tag — useful if you have other tags running through GTM.
<!-- Remove this -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXX');
</script>Step 2: Map your events
Most GA4 setups have a handful of custom events. Make a list before you migrate or you'll forget half of them. Here's the mental mapping:
// Before (GA4)
gtag('event', 'purchase', {
transaction_id: 'T_12345',
value: 49.99,
currency: 'USD'
});
// After (Umami)
umami.track('purchase', {
transaction_id: 'T_12345',
value: 49.99,
currency: 'USD'
});Umami's event data is simpler — no enhanced ecommerce schema, no parameter limits enforced by Google. You define what matters.
Step 3: Update your CSP
If you have a strict Content Security Policy, add your Umami domain:
# Old
script-src 'self' https://www.googletagmanager.com;
connect-src 'self' https://www.google-analytics.com;
# New
script-src 'self' https://analytics.yoursite.com;
connect-src 'self' https://analytics.yoursite.com;Step 4: Drop the cookie banner (maybe)
This is the underrated win. If GA4 was your only reason for needing consent management, you can remove the banner entirely. Check with your legal/compliance person — there are edge cases — but for most marketing sites, it's gone.
Which one should you pick?
After running all three, here's my honest take:
- Pick Plausible if: you want hosted, polished, and don't mind paying monthly. Best dashboard UX of the three, in my opinion.
- Pick Fathom if: you specifically need uptime monitoring or email reports, or you're already in their ecosystem. The product is solid but pricier per pageview.
- Pick Umami if: you want zero ongoing cost, full data ownership, and you're comfortable running a Docker container. The dashboard isn't as pretty as Plausible's, but it's improved a lot in the last year.
For most indie projects and side hustles, I now reach for Umami first. The self-hosted model means I'm not paying $9/mo per project, and the Postgres data is mine — I can query it directly, back it up, do whatever I want with it.
For client work where they don't want to manage infrastructure, Plausible wins. The product just works and the support is responsive.
Links if you want to dig deeper: Plausible docs, Fathom docs, Umami docs.
