Counter: aggregate-only web analytics that stores nothing about you
Web Analytics made simple
At a glance
- What is it?
- Counter is a small Go server with static assets that records how many people visit a web application, keeping everything in Redis and archiving older data in a normal SQL database. It deliberately collects only aggregated counts and never assigns a user id, which is the source of both its low cost and its limits, and it is licensed AGPL-3.0.
- Who is it for?
- Counter suits a small site or a side project where page counts are enough, a cookie banner is unwelcome, and the operator would rather run the analytics than hand traffic data to a third party, since the service is a single Go binary with a Redis backend and a documented self-hosting path.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 49 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The data model is the product
Counter shows how many people visit your web application, and the interesting part is what it refuses to collect.
Most analytics solutions track users individually, assigning a user id via cookies or fingerprinting techniques. Counter collects only aggregated data. The README gives the reason in two parts: this requires cheaper database queries, and considerably less data is saved.
That is the whole design, and it propagates through everything else. There is no user table, no session record that outlives a request, and no way to answer a question about what one person did. In exchange, the storage cost per visit approaches zero and the privacy story is structural rather than a policy you have to trust.
The counting of unique users is achieved with a combination of relying on sessionStorage facilities, the browser's cache mechanism and inspecting the referrer. The README is explicit about the trade: this considerably reduces the complexity and load on the server while improving data privacy, at the cost of knowing less about users. We can't and don't want to be able to connect single page views to a user identity.
That last sentence is the clearest statement of the project's philosophy anywhere in the documentation, and it is worth reading before anyone adopts it expecting conventional analytics features.
Only the first page view is tracked
One bullet in the README is struck through, and the strikethrough is more informative than the text.
The struck-out claim is that usually web analytics solutions track every page loaded, whereas Counter only tracks the first page the user views, described as more privacy-friendly and additionally resulting in substantially fewer HTTP requests the server has to handle. The stated consequence is that Counter is able to show top landing pages but not top pages.
The formatting suggests this behaviour was changed at some point, since the bullet is marked obsolete while the surrounding text about landing pages remains part of the argument. The README does not say which behaviour is current. That is a genuine gap for anyone planning to use the landing page data.
The privacy argument stands either way. If a visitor loads ten pages and only the first is recorded, the server sees one request instead of ten, and the resulting dataset is a set of entry points rather than a set of paths walked. For a site whose purpose is to be found, top landing pages is the more useful number. For a site whose purpose is to be navigated, it is not.
The struck-through bullet about the tracking script follows the same pattern. The original claim was that while most other analytics solutions provide the tracking script as an externally hosted file, Counter uses a small inline tracking script, which mitigates the need to host and serve such a script and avoids efforts to secure an externally hosted script that would have to be trusted by all users. That is also marked obsolete, and the current tracking mechanism is not described.
Redis for the hot path, SQL for the archive
The technology section is short and clear: Counter is a small Go server and static assets, everything is saved to Redis, and a normal SQL database is used for archiving older data.
That split is a deliberate cost decision, stated in the list of reasons the service can be free. The infrastructure is designed for high load with a static binary to handle the HTTP requests in Golang and an in memory database that is regularly backed up to disk in Redis. The README compares this to a typical relational database accessed by a scripting language and calls it much more economical.
The deployment story follows from that. Web applications nowadays typically make use of platform as a service providers for hosting, and the README argues that substantially more performance for the same amount of money can be gained by renting dedicated or virtual servers. That is what Counter does, at the price of having to manage everything by hand and developing strategies to reduce needed maintenance efforts.
That last clause is the honest cost. A managed platform would give you the binary, the database and the backups, and this project trades that away for a cheaper unit cost. The Makefile shows how manual it is: the deploy target rsyncs the config, the production script and the scripts directory to a remote host, rsyncs the built binary, then runs a remote command that kills dtach, waits five seconds and restarts the process under dtach. There are separate targets for tailing logs over ssh, for running integrations over ssh, and for pulling a Redis dump off the server with cp and rsync.
The self-hosting path is a separate repository, counter.dev-selfhost, which is where someone deploying this for themselves should start.
A Makefile that documents the whole operation
The Makefile is the most informative document in the repository, because it lists every operational action the author performs.
For local development there is make devserver, which calls make buildlocal and then sources .config/dev.sh and execs the webstats binary. The buildlocal target is a plain cd backend and go build -o ../webstats. The tests target sources .config/test.sh and runs go test. The format target runs go fmt over the backend tree and prettier over the rest.
The deploy target is where the shape of the operation becomes clear.
rsync .config/makefile.env root@counter:/state/config/ -v
rsync .config/production.sh root@counter:/state/config/ -v
rsync scripts/* root@counter:/state/scripts/ -av
rsync webstats root@counter:/state/webstats
ssh root@counter "pkill -x dtach; sleep 5; dtach -n /tmp/dtach /state/scripts/prodrun"A single remote host, addressed by the alias counter, running the binary under dtach, with configuration and scripts pushed by rsync. The Redis dump is fetched with a cp on the remote host followed by an rsync with --append, which is how a production snapshot is pulled down without restarting the service.
There is a convenience target for running a local Redis against the production dump, docker run with the 6379 port published and the dump file mounted, and the alpineversion variable set to edge at the top of the file suggests the production host is Alpine based.
The blog is a separate concern: it is based on pelican, the templates are in templates/blog, the articles are in the posts directory, and make blog autogenerates into static/blog at every deploy.
The cost arithmetic and the donation-funded reality
The section titled real world validation is where the project stops being a design document and starts being a running service.
The README cites issue 114 for the underlying measurement. Real world resource usage to serve millions of unique visits per month is roughly at 25% on a small VPS that costs 5 dollars per month. The service has a few hundred active users, and every user causes non-fixed costs, the domain plus an extra VPS backup service, of about one cent per month. The author says the costs are covered via donations, and asks for donations to appreciate the effort for maintenance, further development and ongoing customer service.
So the economics of Counter are: one cheap machine, a per-user cost of about a cent, and a service whose upkeep is paid for by donations rather than a subscription. That is a materially different proposition from a commercial analytics product, and it also means the SLA is whatever the author can sustain.
The two struck-through bullets in the free list are worth pairing with this. The claims about tracking only the first page and using an inline tracking script are both marked obsolete, which suggests the project's current behaviour differs from the argument the README still makes in places. For a service whose selling point is its privacy properties, that is a documentation gap that matters, and the repository's own issue tracker is where you would look for the current state.
The cookie banner question has no answer yet
The FAQ section asks whether you can avoid a cookie banner when using counter.dev, and the answer is I don't know, with a link to issue 71.
The reasoning is given though. With the information available, it seems that due to the ePrivacy Directive all SaaS web analytics, including counter.dev, needs consent, even though most providers might claim the contrary. The README notes a proposal for a new ePrivacy Regulation that could fix that.
This is an important honesty point for anyone evaluating the service. A privacy-focused analytics tool whose tracking script still triggers a consent requirement under current European rules is not a way to avoid the banner. If the reason you are considering Counter is to skip the banner, this entry says plainly that the author does not think it works.
What Counter does offer is a smaller data surface and a different data model, which is a reason on its own. But a team that has to show a banner anyway will find themselves paying for consent UI around a tracker that stores no user identifiers, which is a different proposition from what the project's privacy framing suggests.
The licence is AGPL-3.0, and the README states the reason in one line: Counter is Open Source for transparency reasons. For a hosted service, the copyleft terms of AGPL matter for anyone who modifies it and offers it over a network, which is a legal question rather than a technical one. The contributors listed are Ana Maria Sandoval Jimenez as Data Scientist and Irae Hueck Costa as Backend Developer, and the last push was on 2026-09-04.
Editorial conclusion
Counter suits a small site or a side project where page counts are enough, a cookie banner is unwelcome, and the operator would rather run the analytics than hand traffic data to a third party, since the service is a single Go binary with a Redis backend and a documented self-hosting path. It is the wrong tool if you need per-user journeys, funnel analysis, referrer attribution beyond the first page, or anything the AGPL-3.0 terms would make awkward in a commercial product you distribute. Before you deploy it, read the self-hosting repository at github.com/ihucos/counter.dev-selfhost, and note that the consent question is unresolved in the project's own FAQ, which points at issue 71 and the ePrivacy Directive rather than claiming an exemption.
Frequently asked questions
What data does Counter collect about visitors?
Only aggregated counts. The README says Counter collects only aggregated data, and that it cannot and does not want to connect single page views to a user identity, with unique counting done through sessionStorage, the browser cache and referrer inspection.
How do I run Counter locally?
Run make devserver. The Makefile builds the local binary with make buildlocal and then sources .config/dev.sh and runs webstats, and you need a Redis server at localhost on the default port.
Can I self-host Counter?
Yes. The README points to a separate self-hosting repository at github.com/ihucos/counter.dev-selfhost, and the main repository also has a redis-server target that runs a Redis container against a downloaded production dump.
Do I need a cookie banner when using counter.dev?
The README's FAQ says it does not know, and points at issue 71. It notes that under the ePrivacy Directive all SaaS web analytics including counter.dev appears to need consent, even though many providers claim otherwise.
What licence is Counter released under?
AGPL-3.0. The README says Counter is Open Source for transparency reasons, and the LICENSE file is in the repository root.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ihucos-counter-dev)Was this useful?