Start by separating three different counts
A small analytics report can show more sessions than visitors, and more conversions than either number of people or form submissions. That is not automatically a counting bug. These labels describe different records. Before comparing a campaign or a landing page, decide whether your question is about browser identifiers, visits, or sessions that met a goal.
- A visitor in WhoVisited is a site-scoped browser identifier. It is not a verified person, account or company.
- A session is a period of tracked activity with its own session ID and acquisition fields.
- A conversion in the Growth report means a session contains at least one retained event matching the selected goal. It does not count every matching event as a separate converted session.
For example, one browser can return on Monday from a newsletter link and on Wednesday from a search result. That can be one visitor and two sessions with different sources. Two matching goal events during Monday's session still make one converted session in that report. Use event-level records when the question is how many times an action occurred.
How the browser state affects WhoVisited IDs
The current tracker stores a visitor ID in localStorage and a session ID plus activity timestamp in sessionStorage. Both keys include the configured website ID. In normal browser storage, localStorage is shared by documents on the same origin and can persist after the browser closes; sessionStorage belongs to an origin and page session, usually a tab, and survives reloads while that page session remains open.
This means a reload usually does not create a new visitor or session. A different browser profile, device, origin or unavailable storage can produce a different ID. A newly opened tab generally has separate sessionStorage, though browsers can copy an opener's initial session storage in some cases. Treat these as browser measurement boundaries, not as a person-level identity graph.
Storage access can also be unavailable or blocked. The tracker attempts to continue with in-memory state when a storage operation fails, but that state does not survive a page reload. Privacy controls, consent settings, blockers and failed collection requests can all mean that a real visit is absent from the report. Browser analytics should not be expected to reconcile perfectly with signups or server logs.
When a later action becomes a new session
WhoVisited refreshes the stored activity time whenever the tracker records an allowed action. If more than 30 minutes have passed since that timestamp, the next tracked action gets a new session ID. The comparison is strictly greater than 30 minutes: exactly 30 minutes does not cross the threshold in the current implementation. This is an inactivity rule, not a promise that a person left the site or closed the browser.
function sessionStartsAfterIdleGaps(times, idleLimitMs = 30 * 60 * 1000) {
const parsed = times.map((time) => Date.parse(time));
if (parsed.some((time) => !Number.isFinite(time))) {
throw new TypeError("Use valid ISO timestamps");
}
return parsed.flatMap((time, index) => {
if (index === 0) return [index];
return time - parsed[index - 1] > idleLimitMs ? [index] : [];
});
}
console.log(sessionStartsAfterIdleGaps([
"2026-10-12T09:00:00+08:00",
"2026-10-12T09:30:00+08:00",
"2026-10-12T10:00:01+08:00",
])); // [0, 2]The helper is a small planning aid, not a copy of the tracker: it assumes every timestamp is an allowed tracked action and uses the previous action as the idle baseline. In this example, the first two timestamps are exactly 30 minutes apart, so the second remains in the same session. The third follows after 30 minutes and one second, so it starts a new one. If there are untracked actions between these timestamps, the estimate will not match browser behavior.
Why a return visit can have a different source
WhoVisited saves a session's landing path, referrer origin and supported UTM values when that session is first inserted. Later events for the same session update its last-seen time; they do not replace those acquisition fields. A new session can therefore record a different landing path and source, while navigating to another page inside the current session does not rewrite the original landing source.
The Growth report groups sessions by source and campaign. It prefers a saved utm_source, then recognizes Google, Bing and DuckDuckGo referrers, then uses another external referrer host, and finally shows Unknown source when neither is present. A person who returns through a tagged campaign after a long idle gap can appear in a new source row. If they open the tagged link in an existing session, the session keeps the original acquisition data.
This is session attribution. It does not claim that the newest source caused the eventual signup, nor that the first source across every visit receives credit. Use campaign links consistently and compare sessions and goal-qualified sessions over the same date range. For a person-level or multi-touch attribution model, this browser session report is not sufficient.
Run a repeat-visit test without disturbing real users
- Use a staging website or a clearly identified test website with collection enabled and the correct allowed origin.
- Open a fresh browser profile, honor the site's consent choice, and visit a neutral test landing page with a synthetic UTM source.
- Reload and navigate to a second page before 30 minutes of inactivity. Confirm that the visitor and session remain the same and the original landing source stays attached to the session.
- Wait more than 30 minutes after the last tracked action, then open a second synthetic campaign link. Confirm that the browser visitor remains the same when storage is available, while a new session and acquisition row appear.
- Trigger the selected test goal once, then inspect the session and event records separately. Do not submit real leads or copy customer IDs, email addresses or complete network requests into notes.
Make sure the first action after waiting is actually tracked. With required consent, withheld consent does not count as an activity event; browser privacy signals can also keep collection disabled. A fresh profile helps isolate local and session storage, but it does not bypass the privacy rules your site is required to follow.
Interpret the report at the level it measures
- Use visitors as a rough count of site-scoped browser identifiers, not unique people.
- Use sessions to compare acquisition periods, entry pages and same-session goals.
- Use individual retained events when you need the number of button actions, accepted form events or repeated conversions.
- Use server-side signup or order records for business totals and reconciliation; analytics collection can be blocked or consent-limited.
A sudden change in the visitor-to-session ratio can come from actual return behavior, browser storage changes, consent, a new site ID or a deployment that changed the tracker context. Check those conditions before interpreting the ratio as a change in how many people your marketing reached.
WhoVisited is useful here because it keeps the browser visitor, session acquisition and retained events distinct. Its source and goal report answers a focused question about sessions; it cannot identify anonymous people or connect the same person across browsers and devices.