GoatCounter or Cloudflare Web Analytics: what I learned switching in one evening
My site, Where Do My Prompts Go?, tracks what 25 AI tools do with your data, with a source for every entry. It is a static site on GitHub Pages. Because the whole site is about privacy, I had one hard rule for analytics: no cookies, and no tracking people across sites.
On October 25, 2026 I added analytics twice. First GoatCounter, then Cloudflare Web Analytics. This post is what I found. I have no traffic data yet, so this is not about whose numbers are better. It is about setup, privacy, and who each tool suits.
Round one: GoatCounter
GoatCounter is a free, open source analytics tool made by one developer, Martin Tournoij. The repo has been on GitHub since May 2019 and has about 6.1k stars. Sign-up was an email, a password, and an email check. Then I pasted one tag:
<script data-goatcounter="https://YOURSITE.goatcounter.com/count" async src="//gc.zgo.at/count.js"></script>
That was PR #7, a +3/-1 change. It worked.
But it looked a bit weird to me. The script loads from gc.zgo.at, a domain most people have never seen, and the dashboard is very plain. Nothing was wrong with it. It just did not feel as familiar as I wanted for a site that asks readers to trust it.
Round two: Cloudflare Web Analytics
So I switched in PR #9. Cloudflare Web Analytics is also free. I had to create a Cloudflare account, add the site, and copy a snippet. My site does not go through Cloudflare's proxy. You do not need to change DNS; the JS snippet is enough. The beacon loads from static.cloudflareinsights.com.
The diff was small: +2/-2 in one file. One line swapped the script tag. The other updated my Method page, which now says the site "uses no cookies and does not track you across sites."
What each one actually does
Both tools say they set no cookies. GoatCounter says it stores nothing in the browser at all: no cookies, no localStorage. Cloudflare says its beacon does not read or store cookies, localStorage, sessionStorage or IndexedDB.
IP addresses are handled differently. GoatCounter keeps a mix of site, IP and browser string in memory for up to 8 hours, so a reload is not counted as a new visit. That mix is never written to disk. Cloudflare says it gets the IP as part of the normal request, drops it at the nearest data center, and does not store it in its main databases or logs. It counts a "visit" as a page view that came from another site, so it does not need to remember you.
What gets kept is different too. GoatCounter stores counts per day or per hour (path, browser, OS, country, language, screen width) in separate tables that cannot be joined. You choose how long to keep data: 31 days to 5 years, or 0 to keep it forever. Cloudflare keeps full beacon data for 7 days, then keeps about a 10% sample. In the dashboard you can see the last six months.
Cloudflare also measures page speed (Core Web Vitals). GoatCounter has events and campaign tracking. Cloudflare says it does not support UTM parameters or custom events yet.
GDPR and banners
I am not a lawyer, so I will only repeat what each side says. GoatCounter has a page saying it "probably doesn't require a GDPR consent notice," because it stores no personal data and site owners have a legitimate interest in counting visits. Cloudflare says Web Analytics "does not collect or use your visitors' personal data." I did not find a Cloudflare page that says plainly whether you need a banner. My site shows none, and the Method page explains what runs.
Script size and ad blockers
I measured both scripts with curl on October 25, 2026:
- GoatCounter
count.js: 9,213 bytes, about 3.3 KB gzipped - Cloudflare
beacon.min.js: 31,853 bytes, about 10.3 KB gzipped
Both are blocked by ad blockers. The EasyPrivacy filter list blocks gc.zgo.at and cloudflareinsights.com when they load as third-party scripts. Cloudflare's own FAQ admits its beacon is blocked by Adblock Plus, Brave and others. So with either tool, readers who block trackers will not be counted. On a privacy site, many of mine probably do. I am fine with that.
Quick comparison
| GoatCounter | Cloudflare Web Analytics | |
|---|---|---|
| Cookies | None | None |
| IP address | In memory up to 8 h, not stored | Dropped at data center, not stored |
| Data kept | Your choice (31 d to 5 y, or forever) | 6 months in dashboard |
| Open source | Yes (EUPL 1.2, slightly modified) | No |
| Self-host | Yes (SQLite or PostgreSQL) | No |
| Price | Free for reasonable use, donations | Free, no traffic limit stated |
| Sites | Not stated | Soft limit of 10 per account |
| Export / API | JSON and CSV export, JSON API | GraphQL API |
| Script (gzip) | about 3.3 KB | about 10.3 KB |
| Events, UTM | Yes | Not yet |
| Run by | One developer in Ireland, servers in Finland and Germany | Cloudflare, Inc., US public company (NYSE: NET) |
Which one fits who
Pick GoatCounter if you want code you can read, want to self-host one day, want to set your own retention, or want events and campaigns. You also have to be fine with an odd domain and a plain dashboard. You can host count.js yourself if the domain bothers you.
Pick Cloudflare Web Analytics if you want a name readers already know, page speed numbers, and no traffic worries. In exchange you trust a big US company, you cannot see the code, and you get six months of history.
I moved to Cloudflare mostly because of how it feels, not because GoatCounter failed me. I am also giving up open source code and control over retention. If I ever want those back, switching is still a two-line change.
Sources
- My PRs: https://github.com/rebuildlab/where-do-my-prompts-go/pull/7 and https://github.com/rebuildlab/where-do-my-prompts-go/pull/9
- GoatCounter home and pricing: https://www.goatcounter.com/
- GoatCounter privacy policy (what is stored, IP, servers, operator): https://www.goatcounter.com/help/privacy
- GoatCounter sessions (8-hour in-memory mapping): https://www.goatcounter.com/help/sessions
- GoatCounter GDPR page: https://www.goatcounter.com/help/gdpr
- GoatCounter CSV export: https://www.goatcounter.com/help/export
- GoatCounter JSON API: https://www.goatcounter.com/help/api
- GoatCounter license: https://github.com/arp242/goatcounter/blob/master/LICENSE
- GoatCounter self-hosting (README): https://github.com/arp242/goatcounter
- GoatCounter retention setting (source): https://github.com/arp242/goatcounter/blob/master/tpl/settings_main.gohtml and https://github.com/arp242/goatcounter/blob/master/settings.go
- GoatCounter repo stats (created 2019-05-28, 6,095 stars on Oct 25, 2026): https://api.github.com/repos/arp242/goatcounter
- Cloudflare Web Analytics about: https://developers.cloudflare.com/web-analytics/about/
- Cloudflare FAQ (ad blockers, sampling, 7 days, six months, 10 sites, no UTM or events): https://developers.cloudflare.com/web-analytics/faq/
- Cloudflare data collection: https://developers.cloudflare.com/web-analytics/data-metrics/data-origin-and-collection/
- Cloudflare RUM beacon privacy and IP handling: https://developers.cloudflare.com/speed/observatory/rum-beacon/
- Cloudflare launch post (no cookies, no fingerprinting, how visits are counted, free with no traffic limits): https://blog.cloudflare.com/privacy-first-web-analytics/
- Cloudflare dimensions and GraphQL API: https://developers.cloudflare.com/web-analytics/data-metrics/dimensions/
- Cloudflare, Inc. investor relations (NYSE: NET): https://www.cloudflare.net/home/default.aspx
- EasyPrivacy filter list: https://easylist.to/easylist/easyprivacy.txt
- Script sizes: measured with
curl -s URL | wc -candcurl -s URL | gzip -9 | wc -con Oct 25, 2026, about 23:40 WIB (UTC+7). Wire size with gzip was 3,401 and 10,264 bytes.