Unique Visitors Without Cookies, Explained

No cookie, no stored ID, and still a visitor number on the dashboard. Here is where that number comes from, what it quietly cannot know, and how to read it next to pageviews.

By Null Agency · Updated October 27, 2026 · Written for site owners who dropped the cookie banner and want to know what "visitors" now means

TL;DR: cookieless "unique" means unique within a short window

A cookie-based tool recognizes you by a file it left on your device. A cookieless tool has no such file, so any "unique visitor" figure has to be built from something else, and that something else is deliberately forgetful.

How cookie-based tools decide a visitor is "unique"

To call someone unique you first need a way to recognize them. The classic answer is a cookie: on the first visit the tool writes a random identifier into a small file in the browser, and on every later request the browser hands it back. Count the distinct identifiers over a period and you have unique visitors. Count how many were seen before the period began and you have returning visitors.

That model follows one browser across days and supports "new vs returning" splits and retention. GA4 works this way: it sets a first-party cookie (_ga) that holds a client ID, and its user counts are built on that identifier. Check the current Google Analytics documentation for how it defines "users" and "active users" today, because Google adjusts these definitions.

The cost is that the identifier is a stored, persistent, per-browser ID, which is why cookie-based analytics generally requires consent in the EU and UK. If that is the part you are weighing, our guides on whether you need a cookie banner and analytics without a consent banner cover it. It also means the model has well-known blind spots of its own: clearing cookies creates a new "visitor", a second browser creates another, and a visitor who declines consent may not be counted at all.

How cookieless tools count without an identifier

Strip out the stored ID and you still have a request. Every HTTP request arrives with an IP address and a user agent string, which are enough to tell most visitors apart from each other on a given day. The cookieless approach turns those into a throwaway identifier:

visitor_hash = SHA-256( daily_salt + "|" + site_id + "|" + ip + "|" + user_agent )

Three details make this defensible rather than a cookie in disguise.

  1. The salt is secret and random. Without it, anyone holding a list of IP addresses could hash them and look for matches. With it, the hash cannot be recomputed from a known IP and user agent.
  2. The salt changes every day and the old one is deleted. Once yesterday's salt is gone, yesterday's hashes cannot be reproduced and cannot be matched to today's. There is no persistent identifier to join on.
  3. The site ID is part of the input. The same person on two different sites gets two unrelated hashes, so the tool cannot act as a cross-site tracker.

The raw IP and user agent are used in memory to compute the hash and are not what gets stored. Vercel's analytics documentation describes the same family of design: visitors identified by a hash of the request that resets daily, so they cannot be tracked between days or between sites. Plausible and Fathom are also cookieless; check each one's current documentation for exactly which inputs it hashes and how long it keeps them.

The consequence for the word "unique" is built in. A unique visitor in this model is a distinct hash within a salt period. It is not a person, and it is not a browser over time.

What GhostMetrics actually does

GhostMetrics has two separate mechanisms, and mixing them up is the most common way to misread its visitor figures.

Mechanism one: the daily salted hash

When a beacon reaches the worker, it computes a hash from four inputs: a daily salt, the site ID, the connecting IP address and the user agent, joined with a separator and run through SHA-256. Only the first 16 hex characters are kept, which is 64 bits. The salt is 32 random bytes, generated on the first request of each UTC day and stored with a 48-hour expiry, so yesterday's salt deletes itself. The IP address and user agent are used in memory to compute the hash and are not written to the database. The hash is stored on every event row.

That hash is used for four things:

Mechanism two: the tab session behind the Visitors card

The tracker keeps a pageview counter in sessionStorage under gm_depth. It is per tab and disappears when the tab closes. The first pageview in a fresh tab has depth 1 and is flagged as an entry; every later pageview in that tab, including single-page-app route changes, is not.

The dashboard's Visitors card is the sum of that entry flag over the selected period. It is not a distinct count of hashes. So the Visitors card is best read as "tab sessions that started in this period". The same card, with the same definition, appears in the per-day drill-down. Pages / Session is pageviews divided by that Visitors figure, and bounce rate uses it as the denominator, which is why the three cards always agree with each other.

The price of this design is that Visitors counts something other than people, and the card label does not say so. It is unaffected when two people share a hash.

QuestionWhere it comes fromWhat it counts
Visitors card (overview, day drill-down)Sum of the entry flag from the tab-session counterTab sessions that started in the period
Pages / SessionPageviews ÷ Visitors cardAverage pageviews per tab session
Entry Pages panelEntry flag grouped by page (top 10)Tab sessions by landing page
Live VisitorsDistinct daily hashes, last 5 minutesDistinct IP and user-agent combinations right now
FunnelDistinct daily hashes on entry and goal pagesDistinct IP and user-agent combinations that hit both
Browser, OS, device and language panelsRow count per value (top 10)Pageviews, not visitors

The last row matters. The charts on the Visitors tab are labelled by visitor attributes, but they count pageview rows, so a visitor who reads five pages weighs five times as much as one who reads one. Use them for the shape of your audience, not for a headcount.

Why the count is per day, not for life

If the salt lasted a year, the hash would be a pseudonymous identifier that follows a person for a year. That is a cookie moved from the browser to the server. Rotating the salt daily and deleting the old one is the whole privacy argument: after the rotation there is nothing, anywhere, that connects Monday's hash to Thursday's.

The same rotation is the reason lifetime numbers are impossible. "Unique visitors this month" cannot be a union of daily distinct counts without double counting every person who came back, and the tool has no way to know who came back. A monthly total built from daily hashes is the sum of daily visitors, not the number of different people.

GhostMetrics' Visitors card is a sum of tab sessions over the selected window, so a 30-day figure is "tab sessions in 30 days", not "30-day reach".

The rotation boundary is UTC midnight, not midnight in your time zone. A visitor in New York browsing at 7:50 pm and 8:10 pm Eastern straddles the boundary for part of the year and gets two hashes. For the Visitors card that makes no difference, because the tab session carries on. For the Live count and funnels, a visit that crosses the boundary splits into two hashes, so funnels are most reliable inside one UTC day.

What a cookieless count cannot do

Every item below follows from not storing an identifier, and any cookieless product has these limits in some form.

Returning visitors

Someone who read your guide on Monday and came back on Thursday is two visitors, and nothing on the dashboard says they are the same person. There is no "new vs returning" split, no retention curve and no multi-session attribution. GhostMetrics UTM attribution is first-touch inside a single tab session for the same reason.

Cross-device

A laptop and a phone have different user agents and usually different networks, so they hash differently. This is also true of cookies, which do not follow a person across devices either, unless the visitor signs in and the tool stitches users by account.

Shared networks

Two colleagues behind one office router, running the same browser version on the same operating system, can present the same IP and the same user agent string. On that day they share a hash. For Live Visitors and funnels, they count once. For the Visitors card, which does not use the hash, each of their tabs counts separately. The inverse also happens: one person on a phone who moves from Wi-Fi to mobile data changes IP address mid-visit and can show up as two hashes.

Reopened tabs

Close the tab and open the site again: new tab session, new entry, one more on the Visitors card. Open the site in two tabs at once and that is two as well. Conversely, a tab left open for days that keeps navigating stays one session, because the counter only resets when the tab closes.

Blocked storage

If a browser refuses sessionStorage, the tracker cannot keep its counter and falls back to depth 1 on every page load. In that case each pageview from that browser is flagged as an entry, so the Visitors card moves toward the pageview count. Suspect it first if Visitors and Pageviews look suspiciously close.

Visitors who send nothing

The tracker honors Global Privacy Control and Do Not Track by sending no beacon at all, and an ad blocker that blocks the script has the same effect. These visitors are in neither the hash nor the entry count.

Same behavior, different counts

The table lays out how a handful of ordinary behaviors register. "Cookie ID tool" means a typical identifier-based tool at its default settings; the other two columns are GhostMetrics.

What the visitor doesCookie ID toolGhostMetrics Visitors cardGhostMetrics hash (Live, Funnel)
Reads 3 pages in one tab1 user11 hash
Opens the site in 2 tabs1 user21 hash, same day
Returns Monday and Thursday1 returning user22 hashes, no link
Laptop and phone2 users unless signed in22 hashes
Two coworkers, same office, same browser build2 users2Usually 1 hash
Browser blocks sessionStorageNot applicableOne per pageview1 hash
Sends Global Privacy ControlDepends on consent setup0None

No column is the truth. Each is a consistent way of counting something fuzzy, and what matters is that it moves when real traffic moves.

Reading visitors next to pageviews

Treat visitors and pageviews as a pair. Visitors approximates how many times people showed up; pageviews says how much they did once they arrived. Their ratio is Pages / Session, and the way each number moves on its own tells a different story.

A worked example with made-up numbers: last week your site shows 400 visitors and 1,200 pageviews, so Pages / Session reads 3.0. This week it shows 500 visitors and 1,250 pageviews, which is 2.5. Visitors rose 25% and pageviews rose about 4%. The audience grew, but each arrival read less, which points at what changed in your traffic mix, not at what changed on your pages.

Bounce rate is defined from the same tab sessions, so the two cards share a denominator; our guide to bounce rate vs engagement rate covers the reading, and time on page vs session duration covers why GhostMetrics measures time per page.

How to sanity-check your own visitor number

You can verify all of this on your own site in about ten minutes, with nothing but a second device. These steps use panels on the free plan.

  1. Open the Overview and note Visitors and Pageviews. Write both down, with the period selected.
  2. Visit your own site in a new tab, wait a minute, then refresh the dashboard. Figures are cached for about a minute. Visitors and Pageviews should each rise by one: a fresh tab session producing an entry. If nothing moves, check your browser is not sending Global Privacy Control or Do Not Track.
  3. Click to a second page in the same tab and refresh again. Pageviews rises by one; Visitors does not.
  4. Open the site in a second, new tab. Visitors rises by one more. Do not duplicate the tab: a duplicate copies its session storage and continues the old session.
  5. Check Live Visitors from a second device. Load the site on a phone over mobile data, a different IP and user agent from your computer. The Live count should rise by one. It is cached, so allow up to a minute. Load a second tab from the computer instead and it will not, because both tabs share one hash.
  6. Divide Pageviews by Visitors and compare it with the Pages / Session card. They should agree.
  7. Compare periods of equal length. Use the "vs prev" trend figure under each card, which compares against the equal-length period before. Do not compare your Visitors figure with another tool's "users" figure and expect a match.

Which visitor definition for which decision

DecisionGood enough with a cookieless count?What to use
Is traffic growing week over week?YesVisitors and Pageviews trend, same period lengths
Which channel sends the most arrivals?YesReferrers, source types and UTM Breakdown
Did a campaign page convert?Yes, with a counted actionA data-gm-event on the call-to-action button
How many different people visited this quarter?NoAn identifier-based tool, and a decision about consent
What share of visitors come back?NoGA4 or another cookie or account-based tool
Does the same person return after seeing an ad?NoGA4 with Ads integration, where multi-session attribution is its strength
Do I need a consent banner for the number?Generally no for cookieless collectionSee the cookieless tracking guide

The pattern is that decisions about volume and direction work with a cookieless count, and decisions about individuals over time do not. If your business runs on the second kind, such as subscriptions, retention or audience-based ad buying, an identifier-based tool is the honest choice and you pay for it in consent. Our GA4 alternative guide lays out the trade-offs, and how to track website traffic without cookies covers the practical setup.

A visitor count with no cookie, and a plain definition of it

Cookieless$0 forever1 site free$9.99/mo Pro

GhostMetrics sets no cookies and no localStorage, stores no IP addresses (they are hashed), and keeps no cross-session identifier. Its Visitors card counts tab sessions, its Live count uses a daily-rotating salted hash, and neither can tell you who came back tomorrow. If you need returning-visitor or cross-device counts, use GA4. Install is one script tag in <head>, about 3 KB compressed on the wire.

The free plan is free forever, no card: one website, unlimited pageviews, a real-time dashboard, every view and full history. Raw event export as CSV or JSON is on every plan, including free. Pro is $9.99/mo flat with unlimited websites (fair-use ceiling of 250) and a public shareable dashboard, and it starts with a 30-day free trial that needs a card and charges nothing for 30 days.

Start free, no card See the live demo

FAQ

How can analytics count unique visitors without cookies?
By deriving a short-lived identifier from what every request already carries, typically an IP address and user agent, mixed with a secret salt that changes daily. The same browser gets the same hash for the rest of the day and a different one tomorrow, so repeat requests can be grouped without anything being stored on the visitor's device.
Does GhostMetrics count unique visitors with that hash?
Not for the headline Visitors card. That card counts pageviews flagged as the first one in a browser tab session, so it is closer to visits than to people. The daily salted hash drives the Live Visitors count, the Live tab and funnels, and it is stored on each event but never joined across days.
Why can't cookieless tools show returning visitors?
Recognizing a returning visitor needs an identifier that survives between visits. A cookieless tool deliberately has none: its hash resets every day and nothing is stored on the device. The privacy gain and the missing returning-visitor figure are the same design decision.
Will my visitor numbers change when I switch from GA4?
They can move either way, so run both tools for a few weeks and note the offset. GA4 counts users from a cookie-based identifier that persists across visits; GhostMetrics counts tab sessions. Blocked scripts, Global Privacy Control and Do Not Track also change which visitors each tool sees. Check the current Google Analytics documentation for its exact user definition.
Is a cookieless unique visitor count accurate?
It is consistent, not a head count. One person on two devices counts twice, a tab opened later counts again, and visitors sending Global Privacy Control or Do Not Track are not counted at all. Use it as a trend line and compare like with like over the same periods.

Keep reading

Cookieless Tracking Explained

What replaces the cookie, and what it costs you

Time on Page vs Session Duration

Two stopwatch metrics, two blind spots

Bot Traffic and Referrer Spam

Why automated visits inflate visitor counts

GhostMetrics Live Demo

The real dashboard, live data

Disclosure: GhostMetrics is built by Null Agency and we use it on this site, so we are not a neutral party about our own product. GA4's definitions are set by Google and change over time; check the current Google Analytics documentation before quoting exact figures. Competitor tools' hashing details are theirs to document; check their current docs. The numbers in the worked example are illustrative, not benchmarks.