I Replaced Google Analytics with Umami. I'm Not Going Back.

By , Senior Full-Stack Engineer12 min read

I ran Google Analytics on every project I shipped for over a decade. GA4 was the breaking point.

The interface is slow. The data model forces you into dimensions and metrics that don't map to how I think about traffic. Every site needs a cookie consent banner, and the banners suppress opt-in rates so you're only seeing a fraction of your actual visitors. Google is using your visitor data to improve their own advertising products. And if you're serving EU customers, you're carrying GDPR liability for a third-party service you don't control.

I replaced Google Analytics with Umami across all my production sites: AccessHawk, SereneReader, and this portfolio. Self-hosted on Railway. Then I built UmamiDash, an open-source real-time dashboard that connects to any Umami instance via its API.

I'm not going back. Here's why, and why enterprise teams should take this seriously.

Umami never collects personal information from your visitors. No cookies, no sessions, no fingerprinting, no IP addresses stored. The tracking script is under 2KB and identifies unique visitors using a hash of the hostname, user agent, and a rotating salt that resets daily.

GDPR and CCPA compliance, out of the box. You don't need cookie consent banners, opt-in flows, or a Cookiebot/OneTrust subscription. And you stop losing 40% of your visitor data to people who clicked "reject all."

For enterprise clients, this wipes out a whole category of compliance work. Legal doesn't need to evaluate a data processor agreement with Google. Marketing gets accurate visitor counts because nobody is filtered out by consent preferences. Dev doesn't have to build and maintain consent management logic. That's three teams with fewer headaches from a single architectural change.

Self-hosted: your data never leaves your infrastructure

I run Umami on Railway alongside my other production services. The data sits in a PostgreSQL database I own. No third-party vendor sees my traffic data. No data processing agreements to negotiate. No risk of a vendor changing terms, sunsetting a product, or getting acquired.

Google Analytics has been through this cycle already. Universal Analytics was deprecated in favor of GA4, and the migration broke dashboards, custom reports, and integrations across millions of sites. Historical data from UA is gone unless you exported it before the cutoff. That's a vendor lock-in tax.

Umami is open source under the MIT license. If the project were abandoned tomorrow, I'd still have my running instance, my database, and the source code to maintain it. The deployment is a single Docker container with a PostgreSQL connection string. I had mine running on Railway in about 15 minutes.

Umami also offers Umami Cloud if you don't want to self-host. Even on their hosted tier, you can export all your data at any time. No lock-in either way.

The API is the real product

This is the thing that got me excited enough to build a whole dashboard around Umami. The REST API is well-documented and clearly designed for developers to build on. Everything you see in the Umami dashboard has a corresponding API endpoint.

Active visitors, pageviews, sessions, events, referrers, browsers, operating systems, devices, countries, regions, cities. All queryable by date range with composable filters. The response format is clean JSON that you can throw at a chart library without much transformation.

I used this API to build UmamiDash, an open-source real-time dashboard that monitors all my sites in a single view. It connects to any self-hosted Umami v2 instance and streams live data to the browser.

The architecture is simple: an Express server authenticates with the Umami API, polls active visitors and pageview history, and pushes updates to the browser via Server-Sent Events.

Browser  <--SSE-->  Express (:3000)  --polls-->  Umami API

Each website gets a card showing live active visitors, the top 5 countries with visitor counts, the top 5 active URLs, and a 24-hour sparkline bar chart. Click a country and you get a full Leaflet world map with sessions geocoded to city level. The whole thing runs on Vue 3 with shadcn-vue components. If it looks useful, give it a star on GitHub.

Try building something like this on GA4. The Google Analytics Data API requires OAuth 2.0 service accounts, has quota limits that make real-time polling impractical, and returns data in a property/dimension/metric structure you have to wrestle into shape before it's usable. Umami? Clean JSON from REST endpoints. I had UmamiDash streaming live data within a few hours of starting.

Features that compete with enterprise analytics platforms

People assume Umami is a lightweight alternative that trades features for simplicity. It's not. The feature set covers everything I actually used in GA4, plus some things GA4 made unnecessarily hard.

Core analytics

Page views, visitors, bounce rate, traffic sources, location (down to city level), devices, browsers, OS, and languages. All the standard metrics are there. Data is available in seconds, not the hours you sometimes wait with GA4 for standard reports to populate.

Real-time data

Active visitors, current pages, referrers, and geographic location. Updates are actually real-time, not the "real-time" you get from GA4's Realtime report where data lags by several minutes. Both the dashboard and the API reflect what's happening right now.

Custom events and custom data

Track any user interaction with a single function call. I track contact form submissions, blog post reads, dark mode toggles, and scroll depth across my portfolio. You can also attach custom data properties to events for deeper analysis. Here's the composable I use:

// useUmami.ts - thin wrapper around window.umami.track()
export const useUmami = () => {
  const trackEvent = (
    name: string,
    data?: Record<string, string | number>,
  ): void => {
    if (!isUmamiAvailable()) return
    try {
      window.umami!.track(name, data)
    } catch {
      // silent fail - analytics should never break your app
    }
  }

  return { trackEvent, trackPageView, isUmamiAvailable }
}

Compare this to GA4's event tracking, which requires gtag('event', ...) calls with specific parameter schemas, enhanced measurement configuration, and custom dimension registration in the GA4 admin panel before your data shows up in reports.

Insights: funnels, retention, goals, journeys, revenue, and attribution

This is where Umami surprised me. The Insights section goes well beyond basic metrics. Funnels show conversion and drop-off rates at each step, so you can see exactly where people bail. Retention tracks how often users come back. Goals let you set targets for pageviews and events. Journey maps show how users navigate through your site. Revenue tracking ties user behavior to spend. Attribution shows which marketing channels actually drive conversions.

You also get date-range comparison out of the box, so you can see how this week's metrics stack up against last week without exporting to a spreadsheet. Segments let you save commonly used filters so you can reapply them with a click instead of rebuilding them every time.

UTM parameters are collected automatically. Umami also provides trackable links for monitoring click-throughs and tracking pixels you can embed anywhere (emails, external content) to collect data. You get campaign attribution without relying on cookies.

Teams and sharing

Teams let you share website access with different members securely. You can also generate unique shareable URLs for any dashboard, so stakeholders can view stats without needing an account. Umami Cloud adds scheduled email reports that send website summaries on a cadence you set.

Filtering and segments

Filter any report by URL, referrer, browser, OS, device, country, region, city, language, or custom event data. Filters compose, so you can stack them to drill into a specific segment. Save those filters as segments to reuse later. GA4 can do similar things, but the interface for building filtered views is harder to navigate.

The tracking script: 2KB that does the job

Adding Umami to a site is a single script tag:

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

Under 2KB gzipped. It tracks page views automatically and handles single-page application routing out of the box. For context: as of early 2026, gtag.js is around 28KB, Google Tag Manager containers vary but often land at 50KB+, and consent management scripts (Cookiebot, OneTrust) add another 30-100KB on top. Exact byte counts drift release-to-release, but the order-of-magnitude gap is the durable point. Dropping all of that made a noticeable difference in my Lighthouse scores.

The script also respects Do Not Track browser settings by default. If a visitor has DNT enabled, Umami won't track them. You can configure this behavior, but the default is privacy-first.

Ad blockers won't catch it either. Since it's self-hosted, tracking requests go to your own domain, not a third-party domain that blockers target. Umami also supports proxying the script through a custom path if you want to be thorough. And there's no ethical gray area here, because you're not collecting personal information regardless of whether the blocker fires or not.

What Google Analytics is actually doing with your data

Google Analytics is free because you're the product. Google monetizes aggregate behavioral data across millions of websites to train their ad targeting algorithms. Your visitor data feeds their audience modeling and conversion optimization tools.

When you install GA on your site, you're handing Google a feed of your customers' behavior: which pages they visit, how long they stay, what they click, where they came from, what device they're on. Google cross-references this with data from Gmail, Chrome, Android, YouTube, and Search to build user profiles.

For enterprise companies, think about what that means. Your analytics vendor is using behavioral data from your traffic to help your competitors buy better-targeted ads. The data you generate makes Google's ad platform more effective for everyone, including the company bidding against you on the same keywords.

With Umami self-hosted, your analytics data stays on your infrastructure. Period. No third party sees it. No advertising network benefits from it. The data exists to serve your business, not someone else's.

My migration: GA4 to Umami across three sites

I migrated AccessHawk, SereneReader, and this portfolio to Umami over a single weekend. Same process for each site:

  1. Deploy Umami to Railway (Docker image + PostgreSQL, 15 minutes for the initial setup)
  2. Add each website in the Umami dashboard and copy the website ID
  3. Replace the GA4 script tag with the Umami script tag
  4. Add a useUmami composable for custom event tracking
  5. Remove all GA4-related code: gtag.js, consent management, cookie banner logic
  6. Update privacy policy to reflect the new, simpler data practices

The most satisfying part was deleting code. Every site had consent management logic, cookie banner components, and GA4 initialization code. All of it gone. The privacy policy page got shorter because there's less to disclose when you don't collect personal data.

After migration, I built UmamiDash to have a unified view across every site I run on Umami. Instead of opening Umami tabs for each site or switching between properties in GA4, I have a single dashboard with real-time data for everything. Each site gets a card with live visitors, top pages, geographic distribution, and a 24-hour activity sparkline.

The enterprise case for Umami

If you're evaluating analytics for an enterprise environment, here's what the comparison actually looks like.

On compliance: Umami eliminates cookie consent banners, data processing agreements, and GDPR overhead for analytics entirely. GA4 requires all of it. On data ownership: self-hosted Umami keeps everything on your infrastructure. GA4 sends data to Google's servers where it feeds their ad business.

On accuracy: Umami sees every visitor because it doesn't need consent. GA4 only counts the ones who click "accept."

On the API: Umami gives you simple REST endpoints with clean JSON. GA4's Data API requires OAuth service accounts, has quota limits, and returns data in a dimensions/metrics model that needs transformation before it's useful.

On performance: 2KB tracking script vs. 28KB+ for GA4 plus consent management scripts. On vendor risk: MIT license, no sunsetting (remember Universal Analytics?), no forced migrations.

On cost: my self-hosted Umami instance on Railway runs for a few dollars a month. GA4 is "free" but you're paying with your data. GA360 enterprise pricing has historically started at six figures annually (Google doesn't publish a public price sheet — confirm with your rep).

On customization: the API is open, so you can build whatever you need. UmamiDash exists because I could.

Conclusion

Google Analytics was the default for a long time because there wasn't a real alternative. Now there is.

I migrated five production sites in a weekend. The code got simpler, the privacy policy got shorter, and the data got more accurate because every visitor is counted, not just the ones who click "accept" on a cookie banner. Then I built a real-time multi-site dashboard in a few days because the API made it easy to do. That's the part I keep coming back to: Umami doesn't just replace GA, it gives you a foundation to build things GA never could.

If you're carrying GDPR compliance overhead for analytics, or you're tired of GA4's interface, or you just don't love the idea of feeding Google's ad machine with your customers' behavioral data: try it. Self-host an instance, point one site at it, and see how it feels. I think you'll delete the GA script tag pretty quickly after that.

UmamiDash is open source at github.com/charlesjones-dev/umamidash. Umami itself is at umami.is.

Contact

Drop me a line. I read everything and reply within a day.

Required fields are marked “(required)”.