The pitch
The problem: you manage five sites, not one
Most analytics tools assume you own one website. If you build sites for other people, that assumption breaks in three places at once.
Every site needs a consent banner. Google Analytics sets cookies, so European visitors get a dialog before they see the page. You didn't want the banner. Your client didn't want the banner. Nobody clicks it in good faith.
Every site costs money, separately. Hosted analytics is priced per site or per pageview. Five small client sites become five subscriptions, and the ones with almost no traffic cost nearly as much as the ones with real traffic.
Your client has to learn a new tool. You send them a login to a service they've never heard of, on a domain that isn't theirs. Most look once and never again — then ask you for a screenshot every quarter.
What Zenith does differently
Three decisions, each falling out of the problem above.
You host it once. One server, one docker compose up, every site you manage
reporting into it. Adding a client's site costs nothing and takes a minute. The data
sits on a disk you control, in two files you can back up.
It's cookieless, so there's no banner. A visitor is identified by a hash of their IP, user agent, and site ID, salted with a key generated in memory at boot and never written down. That hash can't be reversed into an IP, and it changes when the salt rotates — so there is nothing persistent to consent to. No cookie, no fingerprint, no local storage.
Your client's dashboard lives on your client's domain. This is the part no other
tool does. A proxy route inside their own app serves their analytics at
theirsite.com/analytics-dashboard — same-origin, first-party, password-gated, with
no Zenith branding. They never learn Zenith exists. They just have a page on their own
site that shows their numbers.
Honestly, how it compares
Zenith isn't the right answer for everyone. Here is where it actually sits:
| Capability | Google Analytics | Plausible / Fathom | Umami (self-hosted) | Zenith |
|---|---|---|---|---|
| Cookie banner needed | Yes | No | No | No |
| Cost per extra site | Free | Per site or pageview | Free | Free |
| You own the data | No | No | Yes | Yes |
| Client reads it on their domain | No | No | No | Yes |
| SEO audits built in | No | No | No | Yes |
| Monthly client emails | No | Some plans | No | Yes |
| Setup effort | Paste a tag | Paste a tag | Deploy a server | Deploy a server |
| Funnels, cohorts, replay | Extensive | Growing | Basic | Basic |
Choose something else if
you want zero infrastructure — Plausible and Fathom cloud are excellent — or you need deep product analytics: funnels, cohorts, session replay, attribution modelling. Zenith deliberately doesn’t do those.
Choose Zenith if
you look after several sites for other people, you’re tired of consent banners and per-site pricing, and you’d rather hand a client a page on their own domain than another login.
What you get
Cookieless analytics
Pageviews, referrers, countries, devices, and custom events from a ~1 KB snippet. No cookies, no consent banner.
Domain-native dashboards
A password-gated analytics page served from your client's own domain — same-origin and unbranded.
SEO audits
Every page opened in a real browser: titles, meta descriptions, heading order, broken links, structured data, Core Web Vitals. Downloadable as Markdown or JSON.
Monthly reports
Each site's owner is emailed last month's numbers on the 1st, automatically.
How the privacy actually works
Worth being precise, because "privacy-first" is a claim anyone can make.
When an event arrives, Zenith reads the IP address and user agent, uses them to derive a visitor hash and a coarse country/device/browser bucket, and then discards both. There is no IP column in the schema, and a test enforces that one can't be added. The site ID goes into the hash, so the same person visiting two of your sites cannot be linked across them.
The salt lives only in memory and is regenerated on restart. The trade: a visitor already counted today may be counted once more after a restart. That's deliberate — over-counting a few visitors is a rounding error, while a salt recoverable from disk would be a permanent way to de-anonymise everyone in the database.
Referrers are stored as a hostname, never a full URL, because referring URLs routinely carry private context in their paths and query strings.
Start here
Setup takes you from an empty server to live pageviews.