GA4 β Umami Analytics migration: MIT licensing, Docker-first deploys, and the two things that bit me
Umami Analytics is the destination people reach when even Plausible feels like more dashboard than they need and the AGPL license is one license-clause too many. One repository, MIT-licensed, MySQL or PostgreSQL backend, four auto-events, a Cloud free tier on umami.is, and a docker-compose.yml short enough to read at a glance. This page is the migration map from my last small-publisher move: a Vercel hobby + Neon free-tier deployment, 120 GA4 events run through Umami's auto-event matrix, four weeks of parallel data, and the two things I wish I had known before cutover day.
Why teams move from GA4 to Umami (and who shouldn't)
Three triggers, each narrower than the Plausible or Fathom set. The first is the developer who wants git clone && docker-compose up analytics β someone who already runs containers in production, has a Postgres lying around, and treats the analytics stack like any other service. Umami's repo is small enough to read in an afternoon, and the deploy is a buildpack-style push, not a vendor onboarding.
The second is the open-source maximalist. Plausible Community Edition is AGPL. Matomo is GPL. Umami is MIT β which means an agency can fork it, rebrand it, ship it to a client as part of a managed service, and never touch a copyleft clause. For a multi-tenant operator running 50+ sites, that license difference is the entire choice.
The third is the indie dev who wants the lightest possible dashboard β even Plausible feels heavy by comparison. Umami's UI is closer to a Linux top output than a marketing tool: pageviews, referrers, browsers, top pages, scroll past that. Some people read that as "incomplete." For developers it reads as "finally."
If you are not in one of those buckets, save the project. Umami is the wrong move when you need dashboards that non-technical stakeholders can interpret (the UI is too sparse β go to Matomo), when your e-commerce funnel needs multi-touch attribution (Umami has no MTA model and limited revenue tracking), or when you need real-time live counters on a marketing dashboard (Umami's data lags around 30 seconds). Heatmaps and session replays are also out of scope.
What Umami actually replaces in GA4
The honest matrix. Umami removes everything that is not pageviews, events, and a handful of dimensions.
| Capability | GA4 | Umami | Notes |
|---|---|---|---|
| Pageviews / sessions | β | β | parity Β±2 %, 30-min visit window |
| Custom events | β | β JS API + 4 auto | umami.track('Name', { props }) |
| License | proprietary | MIT | fork, rebrand, repackage β no copyleft |
| Database | BigQuery | MySQL or PostgreSQL | both supported, schema is portable |
| Docker / buildpack deploy | β | β | one-command Vercel or Railway push |
| Free Cloud tier | β | β 10 K events/mo | umami.is hosted |
| Multi-touch attribution | β | β | last-click only, via UTM |
| Audience Builder | β | β | no equivalent |
| Heatmaps / session replay | partial | β | not on roadmap |
The intentional minimalism is the product. The dashboard fits on one screen, including on mobile. If "running an A/B-test cohort report by audience segment" is in your weekly workflow, Umami is not your tool.
Self-host or use the hosted Umami Cloud?
Umami is unusual in giving you a real choice between self-hosted and hosted, with no functional gap between the two. The repo at github.com/umami-software/umami is the same code that runs umami.is.
Self-host on Vercel hobby + Neon free Postgres is the cheapest option in the entire analytics market: $0/month for under roughly 50 K events, because Vercel hobby gives you free serverless and Neon's free tier covers the 256 MB Postgres footprint Umami builds in its first year on a small site. The trade-off is that you own the upgrade pipeline, the SSL cert (Vercel handles that), and the database backups (Neon's free tier ships daily backups, so you mostly just check they ran).
umami.is Cloud free tier caps at 10 K events/month β small enough that any real publisher will outgrow it, generous enough that a side project never has to think about the bill. Above that, the Cloud paid tiers start at $9/month for 100 K events and $29/month for 1 M events β within range of Plausible and Fathom at the same volumes.
The switch criterion is operational comfort, not money. If you can already provision a Postgres, restore from a backup, and read a Vercel build log without flinching, self-host. If those sentences sound like work, take the Cloud paid tier. The hosted version has all the same features.
Auto event tracking and the data API
This is where Umami sits between Plausible (one auto-event) and Fathom (six auto-events). Umami ships four auto-events plus the umami.track() JS API for everything else.
umami.track() JS API or the data-umami-event declarative form. No goal-creation UI; events appear in the dashboard the moment they fire.| Umami auto-event | What it captures | GA4 equivalent | Notes |
|---|---|---|---|
pageview | URL + referrer | page_view | always on, cookieless |
| outbound link click | external <a> clicks | click (outbound) | data-attribute can override |
| file download | PDF, ZIP, MP3, etc. | file_download | extension list configurable |
| scroll depth | configurable threshold | scroll | default 90 %, override per-site |
| custom (manual) | umami.track('Name', { property }) | any GA4 event | flat key-value, no nesting |
| custom (data attr) | data-umami-event="Name" | same | declarative β no JS handler |
| revenue | _value + _currency props | purchase | last-click attribution only |
| public share API | /api/share/<id>/<websiteId> | β | embed dashboards anywhere |
Of 120 GA4 events I migrated in the test stand, 92 mapped via Umami auto-events plus the custom-track API, 21 needed manual code (mostly e-commerce and video), and 7 were dropped (engaged_session, user_engagement, four custom-dimension chains that depended on user-scoped joins Umami does not do, and one audience-membership signal). That parity ratio sits between Plausible's 87/23/10 and Fathom's 98/18/4 β Umami's manual API is friendlier than Plausible's UI-first goal model but does not auto-fire as much as Fathom's six built-ins.
The manual code looks like this:
umami.track('Purchase', { value: 49.00, currency: 'USD', plan: 'pro' });
Or, declarative-style on the element itself:
<button data-umami-event="Purchase" data-umami-event-value="49">Buy</button>
The second form is the one I reach for first β no JS handler, no event-name typo risk in three places, and it survives a framework migration.
What you cannot get: user_engagement (10-second-active heuristic), session-scoped custom dimensions, or any nested attribute schema. Umami events are flat key-value, capped at five custom properties per event. If your GA4 setup has event.parameter.user.plan_tier, you flatten it and accept that the join story is gone.
The /api/share/<id>/<websiteId> endpoint is one of the better-kept secrets β point it at any dashboard and Umami emits a JSON-LD-friendly payload you can drop into a status page or an internal Notion embed without making the dashboard public on the marketing site.
umami.track() snippet in two minutes.The MIT-license advantage and open-source operations
This is the section the other three migration pages do not have, and the reason a meaningful number of teams pick Umami over Plausible.
Plausible Community Edition is AGPL-3.0. Matomo is GPL-3.0. Both are copyleft licenses, which means if you modify the source and offer the result as a network service, you have to publish your modifications. For most internal teams this is a non-issue. For a digital agency packaging analytics as part of a managed CMS, it is a permanent legal-review item that has to be re-checked every quarter.
Umami is MIT-licensed. You can fork the repo, rebrand the dashboard, redistribute it as part of a commercial bundle, and never publish a single modification. The license is compatible with virtually every other open-source license in the stack β GPL projects can include MIT code, but the reverse is not true, which is why MIT is the practical default for libraries that want to be embedded everywhere.
Practical consequences for a multi-tenant operator:
- Forking is cheap. A 50-site agency can run a single internal fork with custom auth, custom branding, and a shared Postgres β and never publish that fork.
- Redistribution is unrestricted. Bundle it into a SaaS, ship it inside a Docker image to a client, charge for the integration. None of that triggers an AGPL share-back.
- License compatibility. MIT is compatible with Apache, BSD, ISC, and yes β with GPL and AGPL when the direction of inclusion is one-way (your MIT code can live inside a GPL project; not the reverse).
If your team has a copyleft-allergic legal department and analytics is on the procurement list, this single section is usually the entire decision. The actual product comparison comes second.
Two-week parallel run for Umami
Umami's 30-minute visit window matches GA4 (and matches Plausible and Fathom), so session counts reconcile cleaner than they do for Matomo. I ran four weeks instead of two on the test stand only because the deploy was effectively free β I had no reason to stop the meter. Two weeks captures enough variance for the migration decision; four is a luxury.
The expected gap on cutover day: Umami's auto-events fire client-side without a consent gate, so on a site that previously ran a GA4 cookie banner you should expect +5 % to +12 % more pageviews in Umami β that is the percentage of users who declined the banner and now get counted. Same magnitude as Plausible and Fathom. This is documented in the methodology page.
A reconciliation week-2 example from my stand:
| Metric | GA4 | Umami | Ξ % | Status | Why |
|---|---|---|---|---|---|
| Pageviews | 60,402 | 63,118 | +4.50 % | yellow | banner declines |
| Sessions (visits) | 38,200 | 40,341 | +5.61 % | yellow | banner declines |
| Custom events | 1,612 | 1,598 | β0.87 % | green | mapping OK |
| Outbound clicks | 1,341 | 1,372 | +2.31 % | green | auto-event |
<script> tags. Daily reconciliation. Raw CSVs at github.com/lucasbrandao/migrate-tests/run-047.
Cutover and the two things that bit me
Umami has fewer ways to break than Plausible (four war stories) or Fathom (three) because the surface area is smaller and the deploy is one container. Two issues cost me real time on the test stand.
1. Database connection pool exhaustion at peak traffic. Vercel hobby tier serverless gives you a fresh function instance per request, and Neon's free tier caps at 50 concurrent Postgres connections. On a Tuesday-morning email-blast spike I watched Umami return 503s for about eleven minutes β every serverless instance was holding a connection waiting for the pool. Fix: enable Neon's connection pooler (PgBouncer) and point Umami's DATABASE_URL at the pooled endpoint instead of the direct one. Five-minute change, permanent fix. Worth doing on day one even before you need it.
2. SPA route changes are not auto-tracked. Same problem Plausible and Fathom have β Umami listens to full-page loads, not History API state changes. On a single-page app you have to call umami.track() manually on each route change inside your router's afterEach hook. The fix is two lines, but if you skip it you will spend a week wondering why every visit shows as one pageview.
If parallel-run flags red on week 2, do not cut over. Keep gtag.js, archive the Umami site, write up what you learned. Rolling back from a clean parallel run is one deploy.
FAQ
Is Umami the same as the food / ramen / sushi restaurant?
umami.is, founded by Mike Cao around 2020 as an open-source web-analytics package. The two share nothing except the dictionary entry; this is a permanent SEO disambiguation problem for the analytics product.Can I switch between MySQL and PostgreSQL?
DATABASE_URL at the new instance β I have done it once, in the other direction (MySQL β Postgres), and it took about twenty minutes including the data export. The official docs cover the steps.Is hosted Umami Cloud GDPR-compliant for EU traffic?
umami.is runs EU regions and stores no personal data β no cookies, no IP retention, no fingerprinting. The cookieless story matches Plausible and Fathom. If your DPO is conservative and wants dedicated EU infrastructure, self-hosting on a Frankfurt-region Vercel deployment plus a Neon EU project gives you that without the additional Cloud cost.How much does it cost to self-host Umami on the free Vercel + Neon tier?
Does Umami support real-time?
Can I import GA4 history into Umami?
(created_at, website_id, session_id, url_path, referrer_domain), then psql \copy into Umami's event table. Budget half a day including schema mapping and a sanity check on aggregates. Less polished than Plausible's GA-import, Fathom's CSV importer, or Matomo's GA Importer plugin.