Tracking unique visitors without cookies

jamie_davenport1 pts0 comments

Tracking unique visitors without cookies — Margin← All postsengineeringprivacy<br>Tracking unique visitors without cookies<br>Every way analytics tools recognise a returning browser, from cookies and localStorage to fingerprints and salted hashes, exactly what Margin computes, and the trade-offs vendors don't usually print.<br>Jamie Davenport9 Jul 2026

"Unique visitors" is an identity problem wearing a metrics costume. To count people instead of pageviews you have to recognise that two requests came from the same person. For twenty-five years the answer was a cookie: set a random ID once, read it back forever. It works brilliantly, which is exactly why it now comes with a consent banner, an ePrivacy paper trail, and a growing population of browsers and extensions that eat it.

Margin sets no cookies, writes nothing to localStorage, and loads no fingerprinting library. It still shows you unique visitors. This post walks through the full menu of identity techniques, from cookies to salted hashes, explains which one Margin picked, and is honest about what it costs, because the trade-offs are real and mostly under-advertised.

The menu of identity techniques

Every analytics tool answers the same question: is this request from a browser I've seen before? There are only a handful of places an answer can come from, and each sits somewhere on a line between accuracy and privacy.

Strategy 1: a cookie

The classic. On first visit, mint a random ID and hand it to the browser; the browser dutifully returns it with every request until it expires.

// First-party analytics cookie, GA-style<br>let id = readCookie("_uid");<br>if (!id) {<br>id = crypto.randomUUID();<br>document.cookie = `_uid=${id}; Max-Age=63072000; SameSite=Lax; Path=/`;<br>// Two years of stable identity: cross-day uniques,<br>// retention curves, attribution windows. It all just works.<br>Third-party cookies (an ID shared across every site that loads the vendor's script) are effectively dead: blocked by Safari and Firefox for years and heavily restricted in Chrome. First-party cookies like the one above still work technically, but legally they're stored state on the visitor's device, which is exactly what the ePrivacy rules gate behind consent. Hence the banner. And even with consent, Safari's ITP caps script-set cookies at seven days, so your "two years of identity" quietly becomes one week for a large slice of traffic.

Strategy 2: localStorage

The tempting dodge: "the rules say cookies, so we'll keep the ID somewhere else."

// Same idea, different drawer<br>let id = localStorage.getItem("uid");<br>if (!id) {<br>id = crypto.randomUUID();<br>localStorage.setItem("uid", id);<br>This buys you nothing. Article 5(3) of the ePrivacy Directive covers "the storing of information, or the gaining of access to information already stored" on the user's device. It never says the word cookie. localStorage, sessionStorage, IndexedDB, cache tricks like ETag respawning: all the same rule, same consent requirement. Swapping the storage API and deleting the banner is a compliance bug, not a strategy.

Strategy 3: fingerprinting

If you can't store an ID, make the browser itself the ID. Enough quirks, combined, are unique.

// Pseudocode. Nothing is stored; the browser's shape is the identifier.<br>const fingerprint = await sha256(<br>navigator.userAgent,<br>navigator.language,<br>screen.width,<br>screen.height,<br>Intl.DateTimeFormat().resolvedOptions().timeZone,<br>await canvasQuirks(), // GPU + font rendering differences<br>await audioQuirks(), // DSP floating-point differences<br>].join("|"),<br>);<br>This is the darkest corner of the menu. It's durable (you can't clear what was never stored), invisible to the user, and research shows sites reach for it precisely when consent for cookies is refused. Regulators treat gaining access to device information this way as in scope of the same ePrivacy rules, and browsers actively sabotage it: Safari and Firefox deliberately blur the very APIs it reads. Any analytics vendor "solving" cookieless uniques with a fingerprinting library has just rebuilt the problem with worse optics.

Strategy 4: derive an ID on the server

Everything above stores something on, or reads something from, the visitor's device. The remaining option is to use only what the server was already handed: every HTTP request arrives carrying an IP address and a user agent. Hash them together and the same person produces the same value, at least until their IP or browser changes.

Raw, that's just fingerprinting moved server-side: a durable pseudonymous ID. The insight the privacy-first tools converged on is to make the hash expire. That's the family Margin belongs to, and it deserves its own section.

Strategy 5: give up on identity

Worth naming: some tools simply don't count uniques. Pageviews, referrers, and heuristic "sessions" (a gap of thirty minutes starts a new one) need no identity at all. It's the most private option and a perfectly honest one, but "how many people" is usually the first question analytics is asked, so...

cookies browser identity unique from localstorage

Related Articles