Sessionization Explained: What Counts as a Session
A session is a group of one user's events bounded by a stretch of inactivity, and sessionization is the process a tool uses to draw those boundaries. The near-universal rule is a 30-minute inactivity timeout: after half an hour with no qualifying event, the session ends. But here's the part people skip. A session is a reporting artifact of the rules you pick, not a fact about what the user actually did.
The short version: raw events don't come pre-labeled with session numbers. Something has to slice the stream into chunks, and that something is a set of rules you can change.
What sessionization actually is
An event is a single recorded action with a timestamp, like a page view, a button tap, or a purchase. A session is a set of those events grouped together because they happened close enough in time to look like one continuous visit. Sessionization is the algorithm that walks through a user's events in order and decides where one visit ends and the next begins.
The important word is decides. Nobody observes a session boundary. The tool assigns it. When a user closes a laptop and comes back four hours later, no signal fires that says "new session." The system infers it, because more than 30 minutes passed with nothing happening. Change the threshold and the same raw events regroup into a different set of sessions.
That's why "how many sessions did we have?" is a slightly weird question. The honest answer is "how many sessions, under which rules?" The 30-minute default is so common that people forget it's a choice at all, and researchers who study session reconstruction have long cautioned that no single time threshold cleanly captures real human visits. It's a convention that works well enough, not a law of nature.
Where the 30-minute timeout came from
This predates modern product analytics by a decade. Back when "web analytics" meant server logs and reach reports, the Web Analytics Association published its Web Analytics Definitions document in 2008, which stated that "a typical time-out period for a visit is 30 minutes" and noted the value was configurable across tools. The same document flagged that a forthcoming IAB audience-reach guideline would push the 30-minute inactivity timeout toward being a requirement, not just a convention.
So the number we all inherited came out of ad-measurement standardization, not out of any study of how long people actually pause between actions. Academic session-reconstruction work (per the summary on Wikipedia's session entry, citing Khoo et al. 2008 and Meiss et al. 2009) treats 30 minutes as "a common value for the inactivity threshold... sometimes described as the industry standard" while being upfront that no single global threshold fits every case. The number stuck because it was good enough and everyone used it. That's how most standards happen.
How the major platforms implement it today
Every major platform ships the 30-minute web timeout as its default. GA4, Amplitude on web, and Mixpanel all end a session after 30 minutes without a qualifying event. The differences show up in the edges.
GA4's timeout is adjustable. Per Google Analytics Help (2024), "a session ends (times out) after 30 minutes of user inactivity," and you can raise that ceiling, since "the maximum value for 'Adjust session timeout' is 7 hours and 55 minutes." Amplitude and Mixpanel take a different tack: they recompute sessions at query time. Mixpanel's docs (2025) put it plainly, noting that "since Mixpanel computes sessions dynamically at query, you can change this definition at any time and it will apply historically." That's a genuinely useful property. Change the rule, and your historical numbers rewrite themselves under the new definition instead of only affecting data going forward.
One more wrinkle that bites cross-platform teams. Session boundaries also differ by SDK, because a web SDK and a native SDK see different signals. Platforms that ship their own iOS, Android, and Web SDKs, such as Kixo (kixo.io), end up defining "session" separately per surface, which is exactly why cross-platform session counts rarely line up.
Default sessionization rules
| Platform | Web default | Mobile handling | Midnight reset | Recompute at query? |
|---|---|---|---|---|
| GA4 | 30 min (up to 7h55m) | Times out on backgrounding unless extend_session=1 |
No | No |
| Universal Analytics (legacy) | 30 min | n/a | Yes (view timezone) | No |
| Amplitude | 30 min | 5 min after backgrounding | No | Yes |
| Mixpanel | 30 min | recomputed | Yes (project timezone) | Yes |
Worked example: same events, different session counts
Let me make this concrete. Here's the raw event stream for one user on a single day, all timestamps in the view timezone:
- 11:12 PM, page view (source:
google) - 11:20 PM, add to cart (source:
google) - 11:47 PM, page view (source:
google) - 12:03 AM, checkout start (source:
newsletter) - 12:09 AM, purchase (source:
newsletter)
Five events. One person, buying one thing, over about an hour. Now run three rule sets against that identical stream.
(a) 30-minute timeout only. Walk the gaps: 8 min, 27 min, 16 min, 6 min. Every gap is under 30 minutes, so nothing breaks the session. Result: 1 session.
(b) 30-minute timeout plus midnight reset. Same gaps, but now crossing midnight forces a cut. The 11:47 PM view and the 12:03 AM checkout fall on opposite sides of midnight, so the visit splits there. This is exactly how legacy Universal Analytics behaved. Per Google's UA docs, "the first session ends at 11:59:59 PM... and the second session begins at 12:00 AM," with end of day set by view timezone. Result: 2 sessions. Mixpanel also resets at midnight in the project timezone, so it lands here too.
(c) 30-minute timeout plus campaign-source-change reset. The source flips from google to newsletter at 12:03 AM. UA closed the open session on any source change, since "every time a user's campaign source changes, Analytics opens a new session." That's the same boundary as the midnight rule in this example, but it would fire even at 3 PM on a change of source. Result: 2 sessions (and in a day where source changed twice, you'd get 3).
Same five events. One, two, or two-going-on-three sessions, depending on rules you didn't necessarily choose on purpose. The "true" session count doesn't exist. You're choosing it every time you pick a configuration. GA4, for what it's worth, dropped both the midnight and source-change resets, which is why it typically reports fewer sessions than UA for identical traffic.
If this feels adjacent to how a poorly specified metric can quietly mislead you, it is. The same discipline shows up in building a tracking plan and in telling vanity metrics from actionable ones.
The web-vs-mobile split most people miss
Web sessionization runs on an inactivity model: no event for N minutes, session over. Mobile runs on a foreground/background model, which is a genuinely different shape.
Amplitude spells out the split in its docs (2026): on web, events group "within 30 minutes," but "for mobile, a session begins when the app moves into the foreground. A mobile session ends when the app goes into the background and sends no events for at least five minutes." So the mobile window is 5 minutes against 30 on web, six times shorter. GA4 apps behave similarly. Per Google's docs, "an app session begins to time out when an app is moved to the background," unless developers send an extend_session parameter with a value of 1 on background events to keep it alive.
The consequence is that a mobile session and a web session aren't the same object with the same lifetime. Mobile sessions are event-shaped by app lifecycle transitions. Web sessions are shaped by clicks and clock gaps. Averaging session counts across the two surfaces means averaging two different measurements that happen to share a name. I've watched teams present a single "sessions per user" number blended across platforms and treat the trend as meaningful. It usually isn't.
Where this goes wrong
Three quiet skews cause most of the confusion I get asked about.
Cross-midnight inflation. UA and Mixpanel force a new session at midnight in their configured timezone. A user browsing from 11:40 PM to 12:20 AM registers as two sessions, not one real visit. GA4 doesn't do this. So when a company migrates from UA to GA4, session counts drop, and it looks like a traffic loss when it's actually just the midnight rule going away. The users didn't leave. The counting changed.
Background-to-foreground gluing. On mobile, backgrounded apps can get pulled forward by things that aren't the user returning. Amplitude warns about this directly in its session FAQ: "activities in the app, like backend notifications or identify calls, can bring the app to the foreground between two actual sessions, leading to unexpectedly long sessions." Two separate visits get welded into one inflated session, and your session-length metric quietly climbs for a reason that has nothing to do with engagement.
Comparing session counts across tools. The three major platforms default to the same 30-minute web timeout, but their midnight rules, source rules, and mobile handling all differ. Two dashboards showing "sessions" are not measuring the same thing, and lining them up in a slide as if they should agree is a recurring source of pointless fire drills. This is the same family of problem as Simpson's Paradox: the aggregate is honest about its own rules and misleading about everyone else's.
So which timeout should you use?
The industry genuinely disagrees on whether 30 minutes is right for any specific product. A meditation app and a stock-trading app have nothing in common in how their users pause, and the same threshold flatters one and distorts the other. I'll pick a side anyway: keep the 30-minute default unless you have a measured reason to change it, meaning an actual distribution of inter-event gaps showing a natural valley somewhere other than 30 minutes.
Because the more consequential move isn't the timeout at all. It's pinning the rest of the rules before you trust any session metric. Midnight reset on or off. Source-change reset on or off. The mobile window. Freeze those, write them down next to the metric definition, and only then start reading trend lines. Until the definition is frozen, treat sessions-per-user and average session length as fragile. They move when your config moves, and that motion looks exactly like real behavior change. For the broader habit of separating metrics you can act on from ones you just watch, see leading vs. lagging indicators.
Quick reference: what counts as a session
- A session is a group of a user's events bounded by inactivity, and sessionization is the algorithm that draws the boundaries.
- The 30-minute inactivity timeout is the de facto default across GA4, Amplitude (web), and Mixpanel, and it traces back to the Web Analytics Association's 2008 definitions and an IAB reach requirement, not to research on user behavior.
- Web uses an inactivity model, while mobile uses a foreground/background model with much shorter windows (Amplitude defaults to 5 minutes on mobile), so cross-platform session counts aren't directly comparable.
- Extra rules like midnight resets and campaign-source-change resets in UA and Mixpanel split one real visit into several, which is why UA reports more sessions than GA4 for identical traffic.
- Treat any session number as a reporting artifact of the rules you chose, and pin those rules before trusting the metric.