Cookieless Tracking Explained: How It Works
How analytics counts visitors without cookies: salted daily hashes, server-side sessions, referrer tricks and what each costs in accuracy. With code.
Cookieless tracking counts visits without storing an identifier on the visitor's device. Instead of a cookie ID, the analytics server derives a short-lived identifier from information every request already carries (the IP address and user agent), mixes in a secret salt that rotates every day, hashes the result, and throws the inputs away. You get accurate pageviews, sources and daily unique visitors, and you give up long-term recognition of returning visitors.
This article is the engineering view: the techniques in use, what each one gets wrong, and how to judge a vendor's claims. If you want the consent side of the story, read Do you need a cookie banner for analytics?; for a walkthrough of one product's implementation, see how cookie-free analytics works.
Key takeaways
- Most cookieless analytics identifies a visitor with hash(daily salt + site + IP + user agent); the salt is random, rotated every 24 hours and deleted, so yesterday's hashes can never be linked to today's.
- Hashing an IP address without a secret salt is not anonymization: the IPv4 space is small enough to brute-force.
- Cookieless counts are accurate for pageviews, referrers, pages and daily uniques; returning-visitor and multi-day attribution are where they lose fidelity.
- Shared IPs (offices, carrier-grade NAT) can merge people; network changes (Wi-Fi to cellular) can split one person into two.
- Fingerprinting (canvas, fonts, hardware) is not cookieless analytics: regulators treat it like a cookie, and it requires consent.
What problem does a cookie solve in analytics?
Counting pageviews needs no identifier at all: one request, one pageview. The identifier exists to answer three questions. Are these five pageviews one visit or five? Is this visitor new or back? Which source gets credit when this person converts next week? A long-lived cookie answers all three by giving each browser a stable ID. Cookieless designs keep the first answer, approximate the second within a day, and give up most of the third.
| Question | Cookie-based | Cookieless (daily hash) |
|---|---|---|
| Pageviews, top pages, referrers, UTM campaigns | Exact | Exact |
| Grouping pageviews into sessions | Exact | Near-exact within a day |
| Unique visitors per day | Exact per browser | Close; small merge/split error |
| Unique visitors per month | Exact per browser | Overcounted: each day is a new ID |
| New vs returning | Yes | Only within 24 hours |
| Multi-day funnels and first-touch attribution | Yes | Not without your own help (see below) |
How does the daily salted hash work?
This is the technique popularized by Plausible and used, with variations, by most privacy-first tools. On every incoming event, the server computes:
import { createHash } from "node:crypto";
// salt: 32 random bytes, generated at 00:00 UTC, kept only in memory or a
// short-lived store, and deleted when the next one is generated.
function visitorId(salt: Buffer, siteId: string, ip: string, userAgent: string) {
return createHash("sha256")
.update(salt)
.update(siteId)
.update(ip)
.update(userAgent)
.digest("hex")
.slice(0, 32);
}
// Then: find the latest session for this id on this site. If its last event
// is < 30 minutes old, attach the event to it; otherwise start a new session.
// Store the id and the event. Never store ip or userAgent themselves.Each ingredient has a job:
- The IP and user agent make the hash differ between visitors. Neither is stored; once the hash is computed, the raw values are discarded (a coarse country or city lookup may run on the IP in memory first).
- The site ID keeps hashes site-specific, so the same person on two different sites produces two unrelated IDs. That is what rules out cross-site tracking.
- The salt makes the hash unguessable and makes it expire. Once the day's salt is deleted, nobody, including the vendor, can recompute which IP produced which hash.
Why a secret salt is not optional
There are only about 4.3 billion IPv4 addresses. A modern GPU computes billions of SHA-256 hashes per second, so sha256(ip) can be reversed by trying every address in seconds. Add a common user agent and it is barely slower. An unsalted or fixed-salt hash of an IP is pseudonymous at best. A random salt that is destroyed daily is what makes old hashes unlinkable.
Where do cookieless numbers go wrong?
The hash is only as stable as its inputs, and IP addresses and user agents are not stable identifiers. The errors run in both directions:
| Situation | Effect | Direction of error |
|---|---|---|
| Office, school or café behind one public IP, same browser build | Several people produce one hash | Undercount |
| Carrier-grade NAT on mobile networks | Many subscribers share IPs | Undercount (partly offset by UA diversity) |
| Phone moves from Wi-Fi to cellular mid-visit | New IP, new hash, new session | Overcount |
| IPv6 privacy extensions rotate the address | New hash when the address changes | Overcount |
| Browser auto-updates and the user-agent string changes | New hash | Overcount (rare within a day) |
| Visit spans midnight UTC when the salt rotates | Session splits in two | Overcount (small) |
| VPN or iCloud Private Relay | IP changes by region or session | Overcount |
In practice the daily unique count from a well-built cookieless tool lands close to a cookie-based count for the same day. The bigger, structural difference is in anything longer than a day: a person who visits on Monday and Thursday is two visitors to a daily-hash system. That is a design choice, not a bug, and it is the price of not storing anything on the device.
What other cookieless techniques exist?
No identifier at all
Some tools skip visitor IDs entirely. Simple Analytics, for instance, has described estimating unique visits from the referrer: if a pageview's referrer is another page on the same site, it is a continuation; if it is external or empty, it is a new visit. This is the most private option and the least detailed: no sessions in the strict sense, no per-visitor paths.
Server logs
Parsing your web server or CDN logs needs no script and sees every request, including bots and visitors with ad blockers. It also counts every crawler, prefetch and health check, cannot see client-side route changes in a single-page app, and knows nothing about scroll, clicks or Web Vitals. Logs are excellent for crawler analysis (see how to track AI crawlers) and poor as product analytics on their own.
Session-only browser storage
Keeping an ID in sessionStorage avoids persistence across tabs and days, but it is still storage on the device, so it falls under the same ePrivacy rule as a cookie. It is not cookieless in the sense that matters legally.
Fingerprinting
Combining canvas rendering, installed fonts, screen size, GPU details and dozens of other signals into a stable ID survives cookie deletion and works across days. It is also exactly what privacy regulators target: the Article 29 Working Party's Opinion 9/2014 put device fingerprinting under the consent rule, and the EDPB's Guidelines 2/2023 reaffirm it. Browsers fight it actively (Safari, Firefox and Brave all add fingerprinting defenses). A vendor that markets “cookieless” but builds a stable cross-day ID from device characteristics is fingerprinting.
Signals for bot detection are a different matter
Some tools read a few browser properties (navigator.webdriver, language count, screen size) once to decide whether a visit is a bot, then discard them. The difference from fingerprinting is that nothing is stored and no ID is built from them. VisitTrack's bot filtering works this way and stores only the verdict.
Is cookieless tracking anonymous under GDPR?
Not during processing. The IP address is personal data under GDPR (the Court of Justice said so for dynamic IPs in Breyer, C-582/14, in 2016), and the server processes it to compute the hash. A salted hash that cannot be linked back once the salt is deleted gets close to anonymous for stored data, but regulators judge the whole pipeline. So treat cookieless analytics as low-risk personal data processing: you need a lawful basis (typically legitimate interest), a privacy policy entry and a processor agreement with the vendor. What you largely avoid is the device-storage consent requirement.
How do you keep attribution across days without cookies?
The usual answer is to let your own application carry the first touch. When a visitor lands, the analytics script knows the referrer, UTM tags and landing page. If your signup form captures those values in a hidden field and stores them with the new account, you can send them back to analytics at signup. The visitor's first touch is then known even if the signup happens days later, without any cookie from the analytics vendor.
VisitTrack implements this pattern: in cookieless mode, the script fills any input marked data-vt-first-touch with the current visit's attribution, and your server can send it back with the signup event. The details are in the cookieless mode docs. The general idea works with any tool that accepts a first-touch payload, and it ties directly into first-touch attribution for revenue.
How do you evaluate a cookieless analytics vendor?
- 1.Open your site in a fresh browser profile, load a few pages, and check DevTools → Application. Cookies, localStorage, sessionStorage and IndexedDB should contain nothing from the analytics domain.
- 2.Read the vendor's documentation for the identifier recipe. Look for a salted hash, the rotation period and what happens to the salt afterwards.
- 3.Check the salt is random and secret, not derived from the date. A date-derived “salt” can be recomputed by anyone.
- 4.Confirm the raw IP and full user agent are not stored, and find out where the IP is processed (EU region or not) and for how long.
- 5.Ask what the script reads from the browser. A handful of properties for bot detection is normal; dozens of canvas and font probes is fingerprinting.
- 6.Compare a week of daily uniques against your current tool. Expect daily numbers to be close and monthly uniques to be higher, because each day is a new ID.
- 7.Decide what you need beyond 24 hours (retention, journeys, attribution) and whether a hybrid model, cookieless in the EU and a first-party ID elsewhere, fits better.
If you are still deciding between tools, the comparisons of Plausible, Fathom and Google Analytics cover how each one identifies visitors and what that means for your numbers.
How does cookieless tracking identify unique visitors?
Most tools compute a hash of a secret daily salt, the site, the visitor's IP address and user agent on the server. The same browser produces the same hash all day, and an unrelated one the next day after the salt rotates.
Is cookieless tracking accurate?
For pageviews, referrers, pages and campaigns, yes. Daily unique visitors are close to cookie-based counts, with small errors from shared IPs and network changes. Multi-day metrics such as returning visitors are where cookieless tracking loses accuracy.
Is cookieless tracking the same as fingerprinting?
No. Cookieless analytics uses request data the server receives anyway and forgets it daily; fingerprinting probes many device characteristics to build a stable cross-day ID. Regulators treat fingerprinting like a cookie, requiring consent.
Is hashing an IP address enough to anonymize it?
No. Without a secret salt, the roughly 4.3 billion IPv4 addresses can be hashed and matched in seconds. A random salt that is deleted after a day is what prevents old hashes from being linked back to an address.
Does cookieless analytics work with ad blockers?
Not by itself. Cookieless describes what is stored, not how the script is loaded. Blockers that list the analytics domain will still block the script; server-side collection or serving the script from your own domain are the usual mitigations.
Can I see returning visitors with cookieless analytics?
Only within the salt period, typically 24 hours. Someone who returns the next day gets a new identifier and counts as new, so retention and returning-visitor reports need a stored identifier or your own account data.