Private analytics, on your server
Analytics without a cookie banner.
See which pages, sources, campaigns and events drive results — without cookies, a consent banner, third-party SaaS or data leaving your server. Tadoru is self-hosted and installs in three commands.
What you get
Clear answers for improving your site.
Understand your audience, content and conversions at a glance — without building profiles of the people behind the numbers.
See what brings people in
Track visitors and pageviews, find your most useful pages, and compare referrers, countries, devices and UTM campaigns. Clean breakdowns show where attention comes from and where it goes.
Use that view to decide what to publish, promote or improve next — without digging through a complex analytics suite.
See what people do next
Measure engagement time, scroll depth, outbound clicks, downloads, custom events and goals. Core Web Vitals show whether real visitors get a fast, stable experience.
Tadoru gives you practical signals for content, campaigns and product decisions while keeping individual visitors out of the picture.
Analytics you can act on
The useful signals, without the personal profile.
Measure visitors, pages, referrers, campaigns, events and Web Vitals. Tadoru deliberately leaves out the details that would identify someone over time.
What is collected
- +Page paths, with sensitive details removed
- +Traffic sources and referring sites
- +Campaigns
- +Country only, never precise location
- +Device and browser family, not exact versions
- +Engagement time and scroll depth
- +Outbound clicks and file downloads
- +Custom events and goals
- +Web Vitals
What Tadoru does not collect
- ×Cookies or browser storage
- ×Browser fingerprinting
- ×Storage of raw IP addresses or full browser information
- ×Exact device or browser details
- ×Identifiers that last beyond the daily privacy reset
- ×Profiles that follow people across sites
- ×Data from visitors using DNT or GPC
This is not just a marketing promise: Tadoru only accepts these categories and rejects anything else, preventing extra personal data from quietly accumulating over time.
Installation
Install Tadoru in three commands.
On a VPS with Node 22 or newer: install, answer four questions, start the service. No Docker, separate database or crontab required.
Install the package
One global npm install and you are done. The GeoIP database is included, so there is no need to call an external service.
sudo npm install -g tadoru
Set it up
Pass the domains you want to measure. It creates the unprivileged user, writes a hardened unit, and prints the dashboard password once — copy it. Migrations run at startup; salt rotation, rollups and retention purges run inside the process. You do not need to manage any of that.
sudo tadoru install-service \ --sites yourdomain.com,another.dev
Start it
install-service deliberately starts nothing: turning the service on stays an explicit decision of yours.
sudo systemctl enable --now tadoru
Make it reachable
Tadoru listens on 127.0.0.1:3000 and never faces the internet itself. Point a subdomain at your server, terminate HTTPS with whatever you already run — nginx, Caddy, Apache, your host's load balancer — and forward to it, passing these along:
Host the public hostname X-Forwarded-Proto https X-Forwarded-For the visitor's IP
Without them the dashboard hands you a broken snippet, the admin cookie loses its Secure flag, and every visitor looks like they came from your server's own country.
Add the snippet to your site
One script tag. Around 4 KB, no dependencies. Your site is identified by its own domain — there is nothing to register.
<script defer src="https://tadoru.yourdomain.com/t.js"> </script>
The dashboard
See what is working in one screen.
Spot traffic changes, top content and audience sources without building reports first. The lightweight dashboard works in three languages and loads no third-party resources.
Top pages
| Path | Views | |
|---|---|---|
| / | 5,204 | |
| /docs/install | 3,177 | |
| /blog/cookieless | 1,982 | |
| /pricing | 1,093 | |
| /changelog | 624 |
Countries
| Country | Visitors | |
|---|---|---|
| Spain | 1,842 | |
| Germany | 866 | |
| Japan | 571 | |
| France | 442 | |
| Portugal | 298 |
Each breakdown calculates unique visitors independently instead of adding incompatible totals, so page, country and source comparisons stay useful and accurate.
Privacy by default
Useful totals without persistent identities.
// derived per request, then thrown away visitor_id = blake2b( daily_salt + site_id + ip + user_agent ).slice(0, 16) // the IP and the user agent are used here // and never written anywhere. There is no // ip column and no user_agent column in // the database to write them to.
- +No cookies or browser storage
- +Raw IP addresses and user agents are used briefly, never stored
- +No fingerprinting or cross-site tracking
- +DNT and GPC signals are respected
- +Raw events are deleted after 25 months; anonymous rollups remain
A daily salt creates a short-lived visitor id and is destroyed every 24 hours. The same person cannot be linked across days or across sites. A session crossing 00:00 UTC is therefore counted as two.
Living with it
The boring parts, already handled.
Backup is one command
tadoru backup vacuums the database into a dated file. Restoring is
tadoru restore, which refuses if the server is running and verifies the file
is really a Tadoru database first.
Health you can monitor
GET /health reports the database and every scheduled job, including whether
one has gone stale. tadoru status asks the same questions from the shell.
Lost the password
It is stored hashed, so nobody can read it back — sudo tadoru reset-password
generates a new one, backs up the env file, and prints the password exactly once.
Updates
sudo npm update -g tadoru then restart. Migrations are idempotent and apply
themselves at boot. There is no manual migration step.
Old data deletes itself
Raw events are purged at 25 months without you configuring anything. Rollups are anonymous aggregates and are kept.
It refuses to start unsafely
No admin password, or a placeholder one, and the service stops with an explanation instead of booting with a credential anyone could guess.
Questions
Reasonable questions before you install it.
Do I really not need a consent banner?
Who is responsible for the data — me or you?
Does it work with JavaScript disabled?
<noscript> pixel still records timestamp, site,
path, referrer, country, device family and language. Engagement time, scroll, outbound
clicks, custom events and Web Vitals need the script.
Why SQLite? Will it hold up?
How many sites can one installation measure?
What does it cost?
Can I export the raw data?
sqlite3 and query it however you
like — there is no export feature because there is no lock-in to escape from.
Measure your sites. Follow nobody.
Free, AGPL-3.0, and running on your own server in about five minutes.
sudo npm install -g tadoru