Web analytics · hosted in the EU

Analytics that grows up with you.

Count every visitor from the first day, with no cookies and nothing kept on their device. When you need funnels, retention and revenue, tidekeeper asks your visitors and keeps the proof. Read all of it in the browser, in your terminal, or through your AI.

14 days free, then the plan's price until you cancel · one line of HTML

eza.rocks Easy23 on the site now
Visitors · 7 days18,406↑ 12% from 16,433
Views41,930↑ 8%
Time on page1m 12smedian
MonThuSun
Left out: 6,318 bot hits · 212 spamAn example
ChangedThursday's visitors came from news.ycombinator.com: 3,904 of them, to /install. Nothing else moved.
Under 2 KBof script, served from your own domain
No cookiesand nothing stored on the device, in easy mode
Every figureshows how it was counted, down to the bots
In the EUhosted in Germany; your figures stay in the EU
Grows as your compliance does

Start on the shore. Wade in when you're ready.

Most analytics make you choose a product for the rules you can handle today. tidekeeper is one product with a line drawn in it. You start where the law is simple, and move further when you need to, without changing your script, your dashboards or your tool.

Easy mode0 m · on the shore

How many, from where, and which pages.

  • Views, visitors, sources, pages, places, devices, goals and real time
  • No cookie and no storage; of the device, only the window's width is read
  • A visitor is recognised for one day, then the key is destroyed
  • The address gives a country and is dropped
  • Every visitor is counted
What your visitor sees
your-site.example

Nothing. No banner, no prompt, no cookie.

Hard mode−1 m · in the water

Who came back, and what they did next.

  • Funnels across visits, retention, paths, attribution and revenue
  • tidekeeper's own banner, where "no" is as easy as "yes"
  • A record of every answer, and of the words that were shown
  • Find, export or delete one visitor's data in a minute
  • Every figure says what share of visitors it covers
What your visitor sees
your-site.example

One script, both modes

Turning hard mode on changes no line on your site. Everyone is still counted the easy way; only those who said yes are followed, from that page on.

A line you can't cross by accident

tidekeeper draws it, asks before it recognises anyone, and keeps the proof. You can't publish a banner where "no" is smaller than "yes".

Hard mode in every plan

The banner, the consent records and the tools to answer a visitor's request are part of doing it properly. They are never an upgrade.

Pages

Your page, as your readers saw it.

tidekeeper keeps a clean copy of each page, with nothing on it that runs, and draws on it what your readers did: which links and buttons they clicked, on desktop and on phone, and how far down they got. See something worth counting? Click it, and it's a goal.

Clicks on the page itselfEach link and button, counted where it sits
How far readers gotScroll depth at every quarter of the page
Click it to make it a goalNo tag manager, no new code on your site
Desktop and phoneThe same page, as each kind of reader met it
An example · click anything on the page
eza.rocks/installStored copy
ezaDocs312ChangelogGitHub1,048

Install eza

cargo install ezaCopy2,031
Download1,284Read the guide406
Homebrew
Nix
268
100%reached
74%
46%
21%
Goals made here appear below. Try clicking “Download”.
Can I trust the number?

Every number shows its working.

Click any figure and tidekeeper shows how it was made: what arrived, what was left out as a bot, a retry or spam, and what was counted without a key. The same answer in the browser, the API, the terminal and the weekly email.

Views of /install · 7 daysAn example
Hits received11,204
Bots− 1,862
Retries of the same hit− 376
Spam and wrong hostnames− 50
Views8,916
$ tidekeeper why eza.rocks views --page /install
Analytics for the AI era

Built for the terminal, and for the agents that live there.

Every figure is a command away: as text for you, as JSON for your scripts, and through an MCP server for your AI. When a number looks wrong, your agent can ask tidekeeper why, and get the same step-by-step answer you would.

$ tidekeeper status
SITE           MODE   SCRIPT       7 DAYS     NOW
eza.rocks      easy   receiving    18,406      23
lurk.example   hard   receiving     2,318       6
fem.gg         easy   receiving     1,284       1
books.fem.gg   easy   silent 26h       96       -

1 site needs attention: books.fem.gg has sent nothing for 26 hours.
$ echo $?
1
$ 
$ tidekeeper why eza.rocks views --page /install --json
{
  "metric": "views",
  "page": "/install",
  "period": "7d",
  "received": 11204,
  "left_out": [
    { "reason": "bot",   "count": 1862 },
    { "reason": "retry", "count": 376 },
    { "reason": "spam",  "count": 50 }
  ],
  "counted": 8916,
  "without_key": 1104
}
$ tidekeeper changed eza.rocks
This week against the one before

↑ news.ycombinator.com     3,904 visitors   new
↑ /install                 +2,710 views     +61%
↓ /blog/release-0.24       −412 views      −38%

Everything else moved by less than a fifth.
Your assistant, with a read-only token · an example
Why did signups drop on Tuesday?
tidekeeper.changed site=eza.rocks period=tue
tidekeeper.why goal="Signed up" page=/pricing
Visits to /pricing were normal. After the deploy at 14:02 the signup button stopped sending its event: 312 views of /pricing had no "Signed up" after them. Nothing was dropped as a bot. The button's data-tk-event attribute is missing in the new build.
MCPtidekeeper's MCP server gives any MCP client the same figures and the same explanations as the terminal, behind a token that can only read. Connect it at /api/v1/mcp, or run tidekeeper mcp. How
JSON from every commandAdd --json to anything and pipe it on. Nothing is screen-scraped.
Exit codes that mean somethingstatus exits 1 when a site needs attention. Put it in cron or CI.
The whole API, describedOpenAPI for every endpoint, so a client can be generated in a minute.
Tokens that only readPer site, per purpose. An agent never does more than you allowed it.
A dashboard in the terminaltidekeeper tui for when a browser is one window too many.
Checks your install for youtidekeeper check https://your-site.example says whether the line is there and answering.
And the rest of a working day

Everything you'd expect, done carefully.

Alerts that know a spike from a quiet day

By email, push, webhook or Alertmanager, when your traffic does something it doesn't usually do.

A weekly report

Monday morning, the week in one mail, with the numbers in it rather than a link to them.

Bring your history

Import from Plausible, umami, GoatCounter or Matomo, checked before anything is written.

Share it, or show it

A public dashboard, or a private link with a password that ends when you say.

Served from your own domain

Your visitors' browsers talk to your site and nobody else. One proxy line, given for nginx and Caddy.

Leave with everything

A full export as CSV and JSON that reads without us or our software.

Pricing

Pay for what the tide brings in.

One price for the events tidekeeper receives in a month, across all your sites. Both modes are in every plan, and bots are never counted against you.

Shore
€9a month

Without VAT

  • 50,000 events a month
  • 3 sites · 2 members
  • 13 months of history
  • Easy and hard mode
Start counting
TideMost sites
€19a month

Without VAT

  • 250,000 events a month
  • 10 sites · 5 members
  • 25 months of history
  • Easy and hard mode
Start counting
Sea
€49a month

Without VAT

  • 1,000,000 events a month
  • Any number of sites and members
  • 37 months of history
  • Easy and hard mode
Start counting

Every plan starts with 14 days free, with a card. Cancel in them and nothing is charged; after them the plan's price is charged each month or year until you cancel. A year costs ten months. All about pricing

One line of HTML

See what the last tide left.

<script defer src="/t.js" data-site="your-site.example"></script>
Start counting →

14 days free, then the plan's price until you cancel · nothing charged if you cancel in them · hosted in the EU