# How to count unique visitors without cookies

Counting page views is easy: every request to a page is one. Counting **visitors** is the hard
part, because the web has no built-in notion of "the same person again". The usual answer is a
cookie with a random ID. In the EU that answer comes with a consent banner, and a banner means
you only count the people who click "accept".

There is another way, used by Plausible and by datalove: recognise a visitor **for one day
only**, from what every request already carries, and forget them at midnight.

## The daily salted hash

Every request to your server arrives with two things: the network address it came from and the
browser's user agent (for example `Mozilla/5.0 (Macintosh; …) Safari/…`). Together they are
fairly specific, but not specific enough to follow a person around, and neither is a secret you
may keep forever. So they are never stored. Instead the server computes:

```text
visitor id = SHA-256( today's salt + site + address + user agent )
```

The **salt** is a long random value, made fresh every day and deleted the next. That one detail
does all the work:

- Two page views from the same browser on the same day produce the same visitor id, so they
  count as one visitor.
- Without the salt, nobody can compute the id back from an address, and nobody can test
  whether a given address visited.
- Tomorrow the salt is new, so the same browser gets a different id. There is nothing that
  links Monday's visitor to Tuesday's.

Nothing is written to the visitor's device: no cookie, no local storage, no fingerprinting
script. The address is used in memory to compute the hash and is then gone.

## Visits, bounces and time on site

Once views of a day carry a visitor id, the familiar website numbers follow:

- **A visit** is a run of page views by the same visitor with less than 30 minutes between
  them. A visitor who reads three pages at lunch and one in the evening made two visits.
- **The bounce rate** is the share of visits with a single page view.
- **Visit duration** is the time from a visit's first view to its last. A visit with one view
  lasts zero seconds, which is why the average is a floor, not a stopwatch.
- **The entry page, referring site and campaign** of a visit are those of its first view. A
  link from a newsletter brings a visit; the pages read after it do not carry the newsletter
  along.

An invented example: a visitor arrives from a search at 12:00 on the home page, opens pricing
at 12:05 and the documentation at 12:50. That is one visitor, two visits (45 minutes passed),
one of them a bounce, five minutes on site in the first.

## Why no consent banner is needed

In Germany the consent requirement for cookies and similar techniques comes from §25 TDDDG
(the national version of the EU ePrivacy rule). It is about **storing information on, or reading
it from, the user's device**. A server that reads the address and user agent it was sent anyway,
and stores nothing on the device, does not fall under it.

What remains is the GDPR: the address is personal data for the moment it is used. The usual
basis is legitimate interest (Art. 6 (1) (f)): knowing how many people read which page is a
reasonable interest, and a hash that cannot be reversed or linked across days keeps the
intrusion small. The privacy notice has to say what is done, and people can object.

This is the reading that cookieless tools and most German privacy advisors work with. It is not
legal advice; if you process anything beyond this, ask yours.

## What it does not measure

Be clear about the limits before you read the numbers:

- **Returning visitors.** Someone who comes back tomorrow is a new visitor. "Unique visitors
  in a month" is therefore the sum of daily visitors, higher than the number of people.
- **The same person on two devices** is two visitors, and several people behind one office
  address with the same browser version can be counted as one.
- **A visit that leads to a sign-up days later** cannot be tied to its referrer. Campaigns
  are compared by the visits and sign-ups they bring in the same period, not per person.

For a public website that is usually the right trade: numbers that include everybody, instead
of precise numbers about the minority that accepts a banner.

## Where the visitor recognition stops

Inside your product the picture is different. People sign in, so they are known by their
account, and there is no need to guess from addresses at all. That is where
[account-first analytics](/features/website-analytics) takes over: the website shows how many
people came and from where, the product shows which accounts then used what.
