GoAccess
Real-time web log analyser that runs in your terminal or renders a single self-contained HTML dashboard
GoAccess is an open-source, MIT-licensed log analyser written in C that reads your web server's access log and shows you what your server actually served — as an interactive terminal dashboard, or as a single self-contained HTML file you could email to someone. It parses Apache, Nginx, Caddy, CloudFront, S3, Elastic Load Balancing, Traefik and IIS logs out of the box, plus any custom format you describe, and needs only ncurses to run. It had 20,890 GitHub stars as of 2 September 2026. For a founder it answers a narrow question very well: what was requested, what your server replied, and how long it took — including the requests that never ran your JavaScript.
What GoAccess actually is
GoAccess (github.com/allinurl/goaccess) has been maintained since 2013 and is written in C, which shows up as the thing you notice first: one required dependency, ncurses, and it starts instantly. Point it at a log — `goaccess access.log` — and you get an interactive dashboard in the terminal. Add `-o report.html --real-time-html` and it writes a single HTML file with no external file dependencies, then pushes live updates to it over a WebSocket server it ships itself, on port 7890 by default.
- It reads the log format you already have Apache common and combined, Nginx, Caddy's JSON structured format, Traefik, Squid, IIS W3C, Amazon CloudFront, S3, Elastic Load Balancing and Google Cloud Storage are predefined. Anything else you describe with a custom format string.
- It runs where the log is, or where you are It parses files, globs of rotated and gzipped files piped through `zcat --force`, or standard input. So you can leave it uninstalled on the server entirely and run `ssh -n you@server 'tail -f /var/log/nginx/access.log' | goaccess -` from your laptop.
- It keeps history without a database `--persist` dumps its dataset to disk and `--restore` loads it back, appending anything new. It tracks each file's inode plus the timestamp of the last line it parsed, so a re-run does not double-count, and `--keep-last=5` recycles storage older than five days.
- It groups traffic the way an operator thinks Panels for requests, 404s, static files, bandwidth, response time, referrers and virtual hosts, plus — with the optional MaxMind database — geography and ASN, which is the panel that makes a single noisy network obvious.
- It is still actively worked on The latest tag is v1.11 from 15 July 2026, and the commits in the last days of August 2026 are ordinary product work: a dedicated AI-crawler category, Fediverse traffic separated from crawlers, ASN traffic exclusion, UTM campaign reporting replacing the old keyphrase panel, and a live requests-per-second metric.
The licence is a plain MIT, stated in the repository's COPYING file rather than left to a badge. There are 449 open issues, which for a thirteen-year-old C project that parses every log format anyone has ever invented reads closer to evidence of use than of neglect — a large share are log, date and time format questions, and the README links straight to the several hundred already closed.
What it costs to run
The real cost is not CPU, it is access. You need to be able to read the access log at all, which rules this out on most platform hosts where you never see one. You need to know your log format, and this is where the time actually goes — a mismatch between your log's date format and the locale GoAccess is running under is the single most common reason a first run shows nothing. And you need to decide about persistence up front, because without `--persist` your report is only as old as the file you fed it, and log rotation is deleting your history on a schedule somebody else chose.
What you get back is a tool with no account, no tag, no sampling and no monthly bill, answering within seconds of the request happening. It is emphatically not product analytics: it has no idea who a user is, what they clicked, or whether they came back next week. It is the layer underneath that, and the two answer different questions well enough that most teams who run one end up running both.
Where a log stops telling you the truth
A log analyser is exactly as truthful as the log, and the fastest way to make your log stop describing your traffic is to put a CDN in front of it. We did that on agentceres.com in August 2026 and the effect on the origin was not subtle: the page cache our origin process was holding fell from 1.33 GB to 0.31 GB, because most requests simply stopped arriving. Every one of those edge-served hits is a real visit the origin log will never contain.
- A CDN in front of it. Cached responses are served at the edge, so your origin log holds the misses. Read the CDN's own logs for the whole picture, or know that you are measuring cache misses and say so.
- Log rotation. The default on most systems keeps a week or two. Anything you did not persist is gone, and it goes without an error.
- A proxy or load balancer. Without the forwarded-for header configured, every request appears to come from one internal address and your geography and ASN panels become decoration.
- Static assets and health checks. A hit is not a pageview. Filter down to the requests you actually mean before you quote a number to anyone.
We learned the value of reading the raw thing in the other direction too. Three hours of our own origin log held 1,438 requests across 558 distinct URLs — 2.58 hits per URL — and roughly three quarters of it was datacentre traffic with spoofed or empty user agents. None of that ratio was visible in our JavaScript analytics, because almost none of that traffic runs JavaScript, and it settled an argument we had been having for weeks about why a two-hour cache lifetime bought so little on a long-tail content site. The fuller version of that argument is in our page on how much of your website traffic is bots.
Where it fits when you are trying to grow
The growth use is narrower than the tool's full range and worth naming precisely. First, crawl reality: which pages Googlebot and the AI crawlers actually fetched, how often, and what status they got — a 404 in your log is usually a link somebody published to a page you moved. Second, the referrer panel, which catches inbound links before any backlink tool notices them. Third, response time per request, because a page that is slow only for real visitors is invisible to a synthetic test. That the project added a dedicated AI-crawler category and split Fediverse traffic out of crawlers in late August 2026 is a decent signal that the first of those is now a question a lot of people are asking.
None of that is the growth work itself, and this is the honest limit of every measurement tool: a log tells you what happened and never what to do about it. Publishing the page the crawler came looking for, writing the outreach that earns the referrer, fixing the 404 that was quietly costing you a link — that all still needs doing by someone. That is what AgentCeres — the AI Growth Officer at agentceres.com — is for: a roster of specialists that drafts the work, with a person approving anything that goes out. If you are earlier than that and the question is simply why nobody is arriving, start with why your website is not getting traffic.
FAQ
- Does GoAccess replace Google Analytics or Plausible?
- No, and treating it as a replacement is how people end up disappointed. A tag-based tool follows a person through a session and can tell you what they clicked and whether they came back. GoAccess reads what your server was asked for and what it answered, with no notion of a user at all. The overlap is roughly the pageview count, and even that will disagree, because a log counts requests that never ran JavaScript and a tag counts sessions your origin may never have seen.
- Can I use it if my app is on a platform host with no log access?
- Usually not directly, and that is the first thing to check before spending time on it. If you cannot read an access log, your equivalent is your CDN's log export, if it has one, or your platform's own request log. Some hosts will stream logs to a file you can pipe in, which works fine — GoAccess is happy reading standard input and does not care where the lines came from, as long as you can tell it the format.
- Will running it slow down a busy server?
- It reads the log file rather than sitting in the request path, so it cannot slow a response down the way an in-process agent can. On a large backlog the parse itself is the only real cost, and the README's own suggestions cover it: run it at low priority with `nice`, use `--jobs` for multi-threaded parsing, and raise `--chunk-size` from its default. The other option is not to run it on the server at all and pipe the log to your own machine over SSH.
- How do I keep more than a week of history?
- Persist it. Run once with `--persist` to write the dataset to disk, then `--restore --persist` on each subsequent run to load what you had and append the new lines. Because it stores each file's inode and the timestamp of the last line parsed, re-running against a rotated log will not double-count. Add `--keep-last` if you want a rolling window rather than everything forever.
You built it. Now grow it.
AgentCeres is a managed AI marketing team — specialists draft the SEO, social, and outreach that fill your links, you approve what ships. 14-day free trial, from $39/month.