Cookieless analytics gets described as magic more often than it gets explained. The short version is that it identifies a visitor without ever storing anything in their browser. Sessions, funnels, and referrers still work, but the identity behind them comes from a hash computed on the server rather than from a cookie handed back on the next request. This post is the how behind our cookieless analytics approach: what cookies actually did for you, the honest ways to replace them, what daily salt rotation does to your numbers, and where this is the wrong choice.
What a cookie actually did for analytics.
Strip away the privacy debate and a cookie did one narrow job for analytics: it gave a visitor a stable identity across requests. HTTP is stateless. Each page view arrives as an independent request, and the server has no built-in way to know that the request for /pricing and the request for /signup ten seconds later came from the same person. A cookie solved that by writing a random id into the browser on the first visit and sending it back on every request after. That single value is what let a tool stitch page views into a session, measure a funnel, and recognize a returning visitor next week.
Everything else people associate with cookies, cross-site tracking, ad retargeting, data sold to networks, was built on top of that identity, not baked into it. For first-party analytics you do not need any of it. You need to answer two questions: did these events come from the same visit, and is this the same person who came before. The first question is the one that matters most, and it turns out you can answer it without touching the browser at all.
The three ways to identify a visitor without cookies.
There are really only three approaches in common use, and they are not equal. Two of them are honest about the tradeoff. One of them wears the cookieless label while quietly reintroducing everything a cookie did, and one of them is worse than a cookie in the way that matters.
| Approach | How it works | The honest tradeoff |
|---|---|---|
| Server-side hashing | The server derives a short hash from the IP and user agent plus a rotating secret salt. Nothing is written to the browser. Used by Plausible and Fathom style tools, and by GetFluxly. | Recognizing a returning visitor across days is deliberately weak, because the salt rotates. Shared office IPs behind one NAT can collapse several people into one hash for a day. |
| localStorage id | A script generates a random id on first visit and stores it in localStorage, then reads it back on later visits. No cookie, technically. | It is not really cookieless from a consent standpoint. localStorage is client-side storage, so the same ePrivacy consent rules that cover cookies apply. You get cookie-like persistence and cookie-like obligations. |
| Device fingerprinting | The script reads canvas, fonts, audio context, screen, and other device signals and combines them into a stable identifier that survives cache clears. | More invasive than a cookie, not less, because the visitor cannot clear it. Regulators treat it as tracking that requires consent. Responsible tools avoid it. |
The localStorage approach deserves a specific warning, because it is the one that catches teams out. Storing a random id in localStorage feels clever: no cookie, so surely no banner. But the ePrivacy Directive, the law that actually governs consent banners in Europe, does not care whether the storage is a cookie. It applies to storing or reading any information on the device. localStorage is storage on the device, full stop. If you use it to persist an id across visits, you have the same consent obligation you were trying to avoid, plus the persistence a real cookieless approach deliberately gives up. Fingerprinting is worse still. It survives a cache clear, the visitor cannot delete it, and regulators treat it as tracking that needs consent. A tool that reaches for it to patch the accuracy gap has picked the least defensible option on the table.
How the server-side hash is built.
This is the mechanism GetFluxly uses, and it is worth seeing concretely because the abstraction hides the important details. On a cookieless project, the SDK sends events with no anonymous id at all. The id is derived at ingest, on the server, from three things that already arrive with the request: the project id, the raw IP address, and the user agent string. Those are combined into one message and run through an HMAC-SHA256 keyed by a secret salt. The result is truncated and prefixed, so the stored anonymous id looks like gfh_9f2a...c714. The same project, IP, and user agent on the same day always produce the same id, which is exactly enough to group that visit into a session.
Two details make this genuinely private rather than cookieless in name only. First, the raw IP is read only inside the request that produced the event. It is never written to a log or a database. Only the anonymized IP is stored afterward, so the input that could identify a person exists for a few milliseconds and then is gone. Second, the salt is not a fixed secret. It is 32 random bytes generated fresh for each UTC day and shared across every ingest process so they all agree on the same value. Because the salt is part of the HMAC key, the hash for a given visitor is only stable while that salt is in use, which is a single UTC day.
It is worth stating what this design costs on the accuracy side so no one is surprised. The IP plus user agent input is not unique per person. Everyone in an office behind a single NAT gateway, running the same browser version, hashes to the same gfh_ id for that day and shows up as one visitor. A visitor who switches from wifi to cellular mid-session changes IP and gets a new id. These are real edge cases, and a tool that claimed perfect visitor counts while storing nothing on the device would be lying to you.
What daily salt rotation does to your metrics.
The salt rotation is the single decision that shapes what cookieless numbers mean, so it is worth being precise. Inside one UTC day, the salt is constant, so a returning visitor keeps the same hash and same-day session grouping and same-day unique counts are correct. When the salt rotates at the UTC day boundary, the same person visiting the next day hashes to a completely different id. The tool has no way to connect the two, by design.
The practical effect is that your daily unique visitor count is reliable, but a multi-day unique total will not de-duplicate a person who came back. Someone who visits Monday, Wednesday, and Friday counts as three anonymous visitors over that week, not one returning visitor three times. Uniques come out conservative in the sense that the tool refuses to claim two visits are the same person unless it can prove it within the salt window. Sessions are unaffected, because a session is grouped as a single visit and never depends on recognizing the visitor days later. If precise long-window returning-visitor counts are the number your business runs on, this is the tradeoff to weigh, and it is a reasonable reason to reach for a cookie-based tool instead.
What changes the moment someone identifies.
The whole cookieless mechanism only governs the anonymous window. The moment a visitor signs up, logs in, or submits a form and you call identify with your own user id, identity stops coming from any browser signal and starts coming from your product. Their prior anonymous sessions attach to a single profile keyed by that id, and from then on they are recognized correctly across devices and across days, because your user id does not rotate with a daily salt.
This is the part that makes cookieless analytics practical for a SaaS product specifically. The visitors you most need to understand in detail, your signups and your paying customers, are exactly the ones who have identified themselves. You get durable, cross-device profiles for the people who matter, and a deliberately short-lived, private view of the anonymous traffic on top of the funnel. The identity you rely on for retention and revenue was always going to come from your own database, not from a cookie. For what that per-person view looks like across the whole product, see the analytics overview.
What you actually lose, and who should care.
Being honest about the losses is the whole point, because the answer is not zero. You lose reliable recognition of the same anonymous visitor across days and across devices. You lose long-window attribution that depends on remembering an anonymous person for weeks before they convert, so a visitor who reads three blog posts over a month before signing up will not be stitched into one anonymous journey. You lose some precision on office and shared-network traffic, where several people can collapse into one id for a day.
For most SaaS teams these losses are minor, because the questions they actually ask are about identified users and about same-day funnels, both of which cookieless handles fully. The teams that should think harder are the ones running long, multi-touch anonymous acquisition funnels where cross-day anonymous recognition is the core metric, or publishers who genuinely need to count unique humans across a month rather than sessions. If that is you, a cookie-based tool with a consent flow may be the right call, and it is fair to say so. For a direct comparison with the most common cookie-based option, see our Google Analytics alternative page.
The consent and GDPR picture, stated carefully.
Here is the part where people want a promise, and the honest answer is a careful one. Cookieless analytics of this kind is designed to run without a cookie consent banner, because there is no personal data stored in the browser for anonymous visitors and no persistent client-side identifier to read back. The ePrivacy Directive ties the consent requirement to storing or reading information on a device, and a server-side hash that never touches the browser is outside that specific trigger. The raw IP is used to compute the hash and then discarded, so it is not retained as personal data.
What this is not is a guarantee of compliance for your whole site. It is designed to keep analytics itself outside the scope of the banner rules, which is a meaningful and specific claim. But if your pages also load advertising pixels, embedded third-party video, chat widgets, or anything else that sets its own cookies, those carry their own obligations that cookieless analytics does nothing to change. Treat the analytics layer as one solved piece, not the whole compliance question. We wrote up where this lands in more detail on the GDPR-compliant analytics page.
Cookieless analytics, answered.
How does cookieless analytics work?
A cookieless analytics tool identifies an anonymous visitor without planting anything in the browser. Instead of writing a cookie or a localStorage value that a script reads back on the next request, the server computes a short hash from signals that already arrive with every request, usually the IP address and the user agent, combined with a secret salt. Events that hash to the same value inside the same window are treated as the same visitor, which is enough to build sessions, funnels, and referrer reports. Nothing about the visitor is stored on their device, so there is no client-side identifier to accept, block, or expire.
Is cookieless tracking less accurate than cookies?
Within a single visit, no. Session grouping, funnels, and campaign attribution all work the same because they run on session and event data, not on a long-lived client id. Across days or across devices, yes, it is weaker. A daily salt rotation means the same anonymous visitor gets a different hash tomorrow, so a person who visits on Monday and again on Wednesday counts as two anonymous visitors rather than one returning visitor. That is a deliberate trade, not a bug: the tool declines to recognize someone before they have identified themselves.
What is the gfh_ id in GetFluxly and where does it come from?
It is the anonymous_id GetFluxly derives on the server for a cookieless project. The value is the string gfh_ followed by a hex HMAC-SHA256 digest of the project id, the raw IP, and the user agent, keyed by a salt that rotates every UTC day. The raw IP is read only inside the request that produced the event, never persisted or logged, and only the anonymized IP is stored afterward. Because the SDK writes nothing to the browser for anonymous visitors, there is no cookie or client-side id involved at any point.
Do I still need a cookie consent banner with cookieless analytics?
For analytics-only tracking, most teams do not, because there is nothing stored on the visitor's device to consent to. The ePrivacy Directive ties consent to storing or reading information on a device, and a server-side hash stores nothing client-side. This is designed to keep analytics outside the scope of the cookie consent rules, but it is not blanket legal advice. If your page also runs advertising pixels, embedded video, or third-party scripts that set their own cookies, those still need their own handling.
What happens when a visitor logs in?
Identity stops depending on the hash entirely. When you call identify with your own user id after a signup, login, or form submission, the visitor's prior anonymous sessions attach to a single profile keyed by that id. From that point forward, recognition comes from your product, not from any browser signal, so a logged-in user is stitched correctly across devices and across days. The cookieless mechanism only ever governs the anonymous window before someone has told you who they are.
Does cookieless analytics use fingerprinting?
Responsible cookieless tools do not, and GetFluxly does not. Fingerprinting reads canvas output, installed fonts, audio context, and other device signals to reconstruct a stable identity when a cookie is not available. That is arguably more invasive than a cookie, because the visitor cannot clear it, and most privacy regulators treat it as tracking that needs consent. Hashing the IP and user agent with a rotating salt is a different approach: the identifier is intentionally short-lived and cannot follow someone across days.
Cookieless analytics is not a weaker version of the same thing. It is a different bargain. You give up the ability to recognize an anonymous stranger across days and across devices, and in exchange you store nothing on their machine, skip the banner for analytics, and still get accurate sessions, funnels, and per-person profiles the moment someone identifies. For a SaaS product whose real customers are the ones who log in, that is usually the better bargain, and it is the one GetFluxly ships as the default rather than an add-on.