Guide

What cookieless tracking does to funnels and retention

A daily-rotating identifier is a new person every midnight. Here is exactly which metrics that breaks, which ones it leaves alone, and why the fix is a split rather than a filter.

The whole problem in one line

Cookieless analytics works by deriving a temporary identifier server-side instead of storing one on the device, and rotating it — usually daily — so it cannot be used to follow anyone over time. That rotation is the privacy guarantee. It is also, from the perspective of every metric that counts people, a catastrophe:

A daily-rotating identifier is a new person every midnight. Any metric that counts people, or divides by them, is reading a fresh stranger each day and cannot tell you otherwise.

This is the reason cookieless has historically been the domain of web analytics — pageviews, sessions, referrers — and not product analytics. It is not that product analytics is less privacy-conscious. It is that funnels, cohorts and flows are all built on the one thing rotation is designed to destroy. What follows is what actually happens, metric by metric.

What breaks

Unique users inflate, and the error grows with your window

A visitor who comes back on five separate days produces five different identifiers, and a unique-user count reads that as five people. The distortion is not a fixed percentage — it scales with how many distinct days the average visitor appears on. A daily unique count is fine. A weekly one is modestly wrong. A 30-day one can be wrong by a multiple, and a loyal audience makes it worse, because the more someone comes back the more people they appear to be. The number moves in the direction that looks like growth, which is the worst possible failure mode for a metric nobody is checking.

Per-user averages deflate by the same factor

“Events per user”, “sessions per user”, anything with people in the denominator: the numerator is right and the denominator is inflated, so the average drifts steadily toward one. A tool reporting healthy event volume alongside an engagement average that keeps sagging is often not describing a disengaging audience — it is dividing by a headcount that grows every night.

Funnels leak at every day boundary

A funnel tracks one person across ordered steps. Any funnel whose steps can span a night — signup with an email confirmation, a trial that converts later, a checkout someone sleeps on — sees the returning person as a stranger. They vanish from step two as a drop-off, then reappear at step three as somebody who skipped the beginning. You get an understated conversion rate and a phantom cohort entering mid-funnel, and neither is labelled as an artifact.

Retention collapses to approximately zero

This is the sharpest one. A retention cohort asks whether the people who first appeared on day 0 came back on day 1, day 7, day 30. With rotating identifiers, none of day 0’s identifiers exist on day 1 — so the answer is no, always, by construction. The curve does not degrade or get noisy. It goes flat at zero and stays there no matter what you ship. A metric that returns a confident, precise, always-wrong number is considerably more dangerous than one that returns nothing.

User flows fragment nightly

Path analysis reconstructs the sequence of screens one person moved through. Rotating identifiers cut every journey at midnight, so long or multi-session paths — exactly the ones worth studying — are chopped into disconnected fragments that each look like a short visit.

Top-K by user counts the same person repeatedly

Any “top N” ranked by distinct users — most-visited pages by user, most-triggered events by user — inherits the same inflation, and unevenly. Pages that returning visitors hit repeatedly get over-credited relative to pages people see once, so the ranking itself distorts, not just the magnitudes.

What does not break

It would be easy to conclude that cookieless traffic should be dropped from reporting altogether. That is its own silent wrong answer, and a worse one in some ways, because it under-counts your real traffic while looking authoritative.

  • Event totals are exact. A consent-declining visitor’s pageview is still a pageview. Counting events never requires knowing who produced them, so totals, sums, averages, minimums and maximums over event properties are all fully correct on cookieless traffic — and excluding it would make them wrong.
  • Session metrics are exact. A session is stitched from activity inside a short inactivity window — 30 minutes is the usual convention — which only ever needs to know that two events arrived close together from the same visitor on the same day. Rotation happens at a boundary sessions do not cross, so session counts, duration and pages-per-session are unaffected.
  • Same-day uniques are exact. The identifier is stable for the day it was minted, so a daily active count over cookieless traffic is sound. It is only the multi-day window that inflates.

The rule: split by what the metric counts

Put those together and the correct handling is not a global filter in either direction. It is a split, applied per metric, on a single question — does this number count people, or divide by them?

  • Counts or divides by people — unique users, per-user averages, funnels, retention, user flows, user-dimension top-K. Exclude cookieless identifiers. Including them corrupts the answer invisibly.
  • Counts events or properties — totals, sums, averages, minimums, maximums. Include cookieless identifiers. Excluding them under-counts real traffic.
  • Counts sessions — include, unconditionally. Session metrics never read a person identifier at all, so the question does not arise.

The asymmetry in the failure modes is what makes the default matter. Wrongly excluding a volume metric under-counts visibly — the number is lower than you expected and someone asks why. Wrongly including a people metric over-counts invisibly — the number is higher than reality, which nobody questions. So when a new metric is added and nobody has decided which bucket it belongs in, excluding is the safer wrong answer.

How Pug enforces it

Pug mints cookieless identifiers with a reserved cookieless- prefix, so any part of the system can recognise one from the value alone without a lookup. That turns the rule above from a convention into something the query layer can apply directly, and it is applied by default — you do not opt in to correct counting.

The classification is written as an exhaustive switch over every aggregation type rather than a list of the two that exclude. That distinction is not stylistic. The list form fails open: an aggregation added later and not considered would default to “include”, quietly admitting rotating identifiers into a metric that may well count people, with no error raised at any layer. The exhaustive form fails the build instead, so adding a metric without deciding which bucket it belongs in is a compile error rather than a number that is wrong for a quarter before anyone notices. Session metrics are exempt by construction — they never read the identifier column.

The query API carries an include_cookieless flag for the cases where you deliberately want these identifiers back in — auditing raw volume, say, or reconciling against a web-analytics tool. It defaults to off. In the events table and live feed, cookieless identifiers render without a profile link, because there is no profile to open: an ephemeral identifier is not a person and the interface should not suggest it is.

What to do about it

  • Read volume from totals and sessions. These are correct across 100% of your traffic — better coverage than any consent-gated tool gives you, with nothing stored on the device.
  • Treat people-metrics as consented-only. Your funnel and retention numbers describe the population that opted in. That is a real limitation, but a known one, which beats a number that silently blends two incompatible populations.
  • Never compare uniques across window lengths. If a tool blends cookieless identifiers into uniques, a 30-day count is inflated relative to a 7-day count by an amount that depends on your own return behaviour, so the ratio between them is meaningless.
  • Ask any vendor which bucket they use. “Cookieless” tells you nothing about whether rotating identifiers reach the unique-user number. If the answer is vague, assume they are counted, and treat the headline figure as an upper bound.
  • Design your consent prompt for the metrics you actually need. If retention drives your roadmap, that is the argument for asking — and for asking well. See GDPR compliance for analytics for what a valid ask requires.

Cookieless is not a lesser form of measurement. It is an honest one with a specific, knowable boundary: it tells you what happened, reliably and completely, and it cannot tell you who kept coming back. Tools that appear to do both are usually not rotating their identifiers, which is a different trade-off entirely and one worth making deliberately.

FAQ

Common questions

Why does retention return zero with cookieless tracking?

Retention asks whether the same person came back on a later day. A daily-rotating identifier is a different value every day by design, so the query that looks for “this identifier, N days later” finds nothing. The result is not a small error — it is structurally zero regardless of how good your product is, which makes it worse than no number at all.

Can I count unique visitors with cookieless analytics?

Within a single day, yes — a rotating identifier is stable for the day it was minted, so daily uniques are sound. Across a longer window they inflate: a visitor who came back on five days is counted as five people. The error grows with the length of the reporting window, so a 30-day unique count is far more wrong than a 7-day one.

Should cookieless events be excluded from analytics entirely?

No — that swaps one wrong answer for another. Excluding them under-counts your actual traffic, and a consent-declining visitor’s pageview is still a pageview. The right split is by what the metric counts: keep cookieless traffic in event totals and session metrics, and keep it out of anything that counts or divides by people.

Do session metrics work without cookies?

Yes. A session is stitched from activity inside a short inactivity window — typically 30 minutes — which never requires knowing who the person is across days. That can be done server-side with no device storage at all, so session counts, session duration and pages-per-session stay correct for cookieless traffic.

How do I get real funnels and retention then?

You need a stable identifier, which means a consent path. Cookieless gives you honest volume and session data on 100% of traffic from day one; consented traffic gives you people-level analysis on the share who opt in. Treat them as two datasets answering different questions rather than expecting one number to do both.

Metrics that tell you which is which

Pug counts cookieless traffic in totals and sessions, and keeps it out of people-metrics by default. Free and open source under AGPL-3.0.

Questions? Email [email protected]