GoAccess vs Umami: Self-Hosted Analytics Compared
Quick Verdict
Want analytics without touching your site’s code? GoAccess reads your existing server logs — no tracking scripts, no cookies, zero page load impact. Want a polished Google Analytics replacement with real-time dashboards and event tracking? Umami gives you that with a lightweight JavaScript snippet. For most self-hosters running Nginx or Apache, GoAccess is the simpler path. For anyone building a product or tracking user behavior across pages, Umami is the better tool.
Updated March 2026: Verified with latest Docker images and configurations.
Overview
GoAccess is a real-time web log analyzer written in C. It parses Nginx, Apache, Caddy, or any CLF/combined log format and generates analytics in your terminal or as a self-updating HTML report. No JavaScript. No cookies. No database. GoAccess reads what your web server already records. Official site.
Umami is a JavaScript-based analytics platform built with Next.js. You add a <script> tag to your pages, and it collects page views, referrers, browser data, screen sizes, and custom events — all stored in PostgreSQL or MySQL. Cookie-free by design and GDPR-compliant without consent banners. Official site.
These tools solve the same problem (web analytics) in fundamentally different ways. GoAccess is passive — it analyzes data your server already generates. Umami is active — it requires instrumentation but captures richer data.
Feature Comparison
| Feature | GoAccess | Umami |
|---|---|---|
| Data source | Server access logs (Nginx, Apache, Caddy) | JavaScript tracking snippet |
| Cookies | None (log-based) | None (cookieless by design) |
| Page load impact | Zero | Minimal (~2 KB script) |
| Real-time dashboard | Terminal UI + WebSocket HTML report | Web dashboard with live updates |
| Custom event tracking | No | Yes (JavaScript API) |
| Multi-site support | One log source per instance | Unlimited websites per instance |
| User sessions | Estimated from IP + UA | Tracked with anonymous session IDs |
| API | None (HTML report export) | Full REST API |
| Database | Flat file (optional persistent storage) | PostgreSQL or MySQL required |
| Geolocation | GeoIP database (MaxMind) | Built-in country detection |
| Bot filtering | Configurable exclusion patterns | Automatic bot detection |
| Data retention | Configurable (or keep all logs) | Configurable per-site |
| License | MIT | MIT |
Installation Complexity
GoAccess needs one container and access to your web server’s log files:
services:
goaccess:
image: allinurl/goaccess:1.10.1
container_name: goaccess
restart: unless-stopped
ports:
- "7890:7890"
volumes:
- /var/log/nginx/access.log:/var/log/access.log:ro
- goaccess-data:/srv/data
- goaccess-html:/srv/report
command: >
--log-file=/var/log/access.log
--log-format=COMBINED
--real-time-html
--ws-url=wss://analytics.example.com
--output=/srv/report/index.html
--persist
--restore
--db-path=/srv/data
volumes:
goaccess-data:
goaccess-html:
No database container. No config files. Point it at your log file and it works.
Umami requires two containers — the app and a PostgreSQL database:
services:
umami:
image: ghcr.io/umami-software/umami:v3.0.3
container_name: umami
restart: unless-stopped
ports:
- "3000:3000"
environment:
DATABASE_URL: "postgresql://umami:changeme@umami-db:5432/umami"
APP_SECRET: "change-me-to-random-string"
depends_on:
umami-db:
condition: service_healthy
umami-db:
image: postgres:17
container_name: umami-db
restart: unless-stopped
environment:
POSTGRES_DB: umami
POSTGRES_USER: umami
POSTGRES_PASSWORD: changeme
volumes:
- umami_db:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U umami"]
interval: 10s
timeout: 5s
retries: 5
volumes:
umami_db:
After deploying Umami, you still need to add the tracking script to every page on your site. GoAccess requires zero changes to your website.
Winner: GoAccess. One container, no database, no code changes. Plug into your existing logs and go.
Performance and Resource Usage
| Metric | GoAccess | Umami |
|---|---|---|
| RAM (idle) | 30–80 MB | 150–300 MB (app + PostgreSQL) |
| Disk (30 days, 10K pages/day) | 5–20 MB (depends on log retention) | 50–200 MB (PostgreSQL storage) |
| CPU | Spikes when parsing large logs | Low (async event processing) |
| Network overhead | None | ~2 KB per page view (tracking script) |
| Containers | 1 | 2 (app + database) |
GoAccess is dramatically lighter. It processes logs with zero network overhead and can run alongside your web server with minimal resource impact. Umami’s PostgreSQL database is the main resource consumer — acceptable for most servers, but unnecessary if you only need basic visitor stats.
Data Accuracy
GoAccess counts every HTTP request your server handles, including bots, crawlers, and prefetch requests. You configure exclusion patterns manually. This means raw numbers from GoAccess tend to be higher than real visitor counts.
Umami only counts visits where JavaScript executes in a real browser. Bots that don’t run JavaScript are invisible. Ad blockers that block the tracking script will undercount real visitors. Neither tool uses cookies, so both estimate unique visitors rather than tracking them precisely.
| Accuracy dimension | GoAccess | Umami |
|---|---|---|
| Bot inflation | Higher (needs manual filtering) | Lower (JS-only) |
| Ad blocker impact | None (server-side) | Undercounts blocked visitors |
| JavaScript-disabled visitors | Counted | Missed |
| Single-page app tracking | No (only initial page load logged) | Yes (with router integration) |
For content sites with server-rendered pages, GoAccess is more complete. For SPAs and interactive products, Umami captures user behavior that never hits server logs.
Use Cases
Choose GoAccess If…
- You want analytics without adding tracking scripts to your site
- Privacy is paramount — you want zero client-side data collection
- You already run Nginx, Apache, or Caddy and want to use existing logs
- You prefer a terminal-first workflow
- Resource efficiency matters — you can’t spare RAM for PostgreSQL
- You run a static site and just need traffic numbers
Choose Umami If…
- You need custom event tracking (button clicks, form submissions, signups)
- You manage multiple websites from one dashboard
- You want a clean web UI similar to Google Analytics
- Your team needs an API to pull analytics data programmatically
- You run a JavaScript-heavy SPA where server logs miss client-side navigation
- You want shareable public dashboards for stakeholders
Community and Support
| Dimension | GoAccess | Umami |
|---|---|---|
| GitHub stars | ~19,000 | ~24,000 |
| First release | 2009 | 2020 |
| Primary language | C | TypeScript/Next.js |
| Development pace | Stable, infrequent releases | Active, frequent releases |
| Documentation | Good (man page + website) | Excellent (docs.umami.is) |
| Hosted option | No | Yes (Umami Cloud) |
GoAccess has been around since 2009 and is rock-solid — it rarely needs updates because log parsing doesn’t change. Umami moves faster with new features (custom reports, funnel analysis, UTM tracking) but may require more frequent upgrades.
Final Verdict
The practical choice is GoAccess because it requires zero changes to your website and zero additional infrastructure. If you already have a web server generating logs, you’re five minutes from analytics. No tracking scripts to maintain, no database to back up, no JavaScript for visitors to block.
Choose Umami when you outgrow log-based analytics — when you need event tracking, multi-site management, team access, or API integrations. It is a genuine Google Analytics replacement, not just a traffic counter.
For many self-hosters, running both makes sense: GoAccess for server-level traffic monitoring, Umami for user-facing analytics you share with others.
FAQ
Can GoAccess track clicks or form submissions?
No. GoAccess only analyzes HTTP requests logged by your web server. Client-side interactions that don’t generate a new HTTP request are invisible. Use Umami or Plausible for event tracking.
Does Umami work with static sites?
Yes. Add the tracking script tag to your HTML template. It works with Hugo, Astro, Jekyll, or any static site generator. The script is under 2 KB and doesn’t slow page loads.
Which is more GDPR-compliant?
Both are cookie-free and can be GDPR-compliant. GoAccess has an edge because it collects no client-side data at all — everything comes from server logs that your web server already generates. Umami’s JavaScript snippet technically collects browser data (screen size, language, referrer), though it anonymizes it.
Can I use GoAccess with Cloudflare or CDNs?
Partially. If Cloudflare serves cached pages, those requests never hit your origin server and won’t appear in your logs. You can use Cloudflare’s CF-Connecting-IP header in your log format, but cached-page visits will be undercounted.
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments