Skip to content

User & Session

In analytics, user and session sit at two different levels of granularity. Mixing them is one of the most common mistakes when reading reports. One user can produce many sessions, and one session can produce many events. Get the hierarchy right and the dashboard becomes interpretable.

The hierarchy

User (or "visitor")
└── Session 1
│   ├── Pageview /
│   ├── Pageview /pricing
│   └── Custom event "Sign Up"
└── Session 2 (different day, or after a 30-min gap)
    ├── Pageview /
    └── Custom event "Trial Started"

A user is a person, or more precisely a stable identifier the analytics tool uses as a proxy for one. A session is a continuous burst of activity by that user, bounded by inactivity. A session contains events: pageviews, engagement signals, custom events fired from your code.

How Statable counts users

Statable identifies users (called visitors) using a server-side daily hash: SipHash(siteID, ip, user_agent, date). The hash rotates every 24 hours, and nothing is stored in the browser.

Practical consequences:

  • Two visits on the same day from the same IP and browser: one visitor.
  • Two visits on different days: two visitors, even if it's the same person, since the daily salt makes the hashes differ.
  • The same person on phone and laptop: two visitors, since IPs and User-Agents differ.

This trade-off, slightly inflated daily totals for full privacy and no consent banner, is the central design choice of Statable's tracking model. It is intentional, not a limitation. See Unique Visitors for the longer rationale.

How Statable counts sessions

A session is a sequence of events from the same visitor with no more than 30 minutes of inactivity between them. There are no other session boundaries. Switching traffic source mid-session does not end the session.

Practical consequences:

  • A user who reads an article, leaves the tab open, returns 25 minutes later: same session.
  • A user who closes the tab, returns 2 hours later: new session, same visitor (if same calendar day).
  • A user who lands from Google, browses, then comes back via a Twitter link in the same 30-minute window: still one session.

Sessions are computed server-side from the event stream. The SDK does not assign session IDs in the browser.

Events inside a session

Events are the atomic units. Statable records:

  • Pageviews: fired automatically on initial load and every SPA route change.
  • Engagement: sent at session end, carrying scroll depth and time on page.
  • Custom events: anything you fire with window.statable.t('Event Name', { ... }) or via data-statable-event attributes. See Custom events.
  • Auto-tracked custom events: outbound link clicks (Outbound Link Click) and file downloads (File Download).

Each event carries the visitor ID and session ID it belongs to. Every report can roll up to the level you need: pageviews per page (event level), bounce rate per source (session level), visitor counts per country (visitor level).

Why this hierarchy matters

Most dashboard metrics aggregate over one of three levels:

Aggregate over…Examples
VisitorsVisitors KPI, Countries breakdown, daily uniques
SessionsSessions KPI, Bounce Rate, Session Duration, Source / Channel reports
EventsPageviews, Custom Event counts, Goal completions

When two metrics seem to disagree ("more pageviews than sessions"), the answer is almost always that they live at different levels. One session contains many pageviews. Reading the hierarchy correctly is the difference between confidence and confusion.


Ready to take control of your web analytics? Try Statable free for 30 days — no credit card required, full feature access, GDPR-compliant by default. Start your free trial or view a live demo.