Sessions

Last updated:

|Edit this page

A session is a set of events that try to capture a single use of your product or visit to your website. They are used in multiple areas of PostHog:

  • Session replays
  • Web analytics
  • Session aggregations
  • Session properties

Sessions enable you to analyze how exactly users are using your product, their entry and exit points, how long they spend on your site, how active they are, bounce rate, and more.

How does PostHog define a session?

Our JavaScript Web library and mobile SDKs (Android, iOS, React Native, and Flutter) add a $session_id property to each event. Events captured from the same user, browser, and device get the same $session_id within the same session, until a new session is started. A new session is started by default when either there's no activity for 30 minutes or the session has reached the maximum session duration of 24 hours. Subsequent events are grouped into a new session and a new session triggers a new session replay.

A session can span multiple tabs and windows, but only on the same browser and device. For example, if a user goes from one Chrome tab to another, it counts as a single session. If they go from Chrome to Firefox, a new session is created. You can also create a new session by calling posthog.reset() (which also starts a new session replay).

Activity is defined as any event sent from the client including autocapture events and replay activity like mouse movement. The inactivity period can be configured using the session_idle_timeout_seconds configuration option.

Note: If you are migrating data or using a CDP, you may need to manually set the $session_id property if you want to query sessions or connect them to session replays. If you are using the JavaScript Web SDK alongside your CDP, you can get this value by calling posthog.get_session_id().

Session properties

Session properties are data about the session that is autocaptured by PostHog and separate from event or person data. They can be queried and used like other properties in aggregations, filters, breakdowns, and more. Session properties include:

Session propertyDescription
$session_idUnique identifier for a session, persists across events in the same session
$start_timestampTimestamp when the session started
$end_timestampTimestamp when the session ended
$entry_current_urlURL of the page where the session started
$entry_pathnamePathname of the page where the session started
$exit_current_urlURL of the page where the session ended
$exit_pathnamePathname of the page where the session ended
$entry_utm_sourceUTM source of the session start page
$entry_utm_campaignUTM campaign of the session start page
$entry_utm_mediumUTM medium of the session start page
$entry_utm_termUTM term of the session start page
$entry_utm_contentUTM content of the session start page
$entry_referring_domainReferring domain of the session start page
$entry_gclidGoogle Click ID when the session started
$entry_gad_sourceGoogle Ads source when the session started
$pageview_countTotal number of pageviews during the session
$autocapture_countTotal number of autocapture events during the session
$channel_typeType of channel through which the session was initiated
$session_durationTotal duration of the session
$is_bounceIndicates if the session was a bounce (single pageview session)

You can query all of these from the sessions table using SQL insights.

Using session data

The easiest way to analyze a session is to view a session replay. This enables you to playback and watch exactly what happened in that session. This includes events, navigation, mouse movement, console logs, and more.

Web analytics also gives you an easily accessible overview. The top section contains sessions, session duration, and bounce rate, while further down provides more details on entry paths, exit paths, top channels, device types, and more.

Session data in web analytics

For more detailed analysis, you can use insights to filter, break down, and aggregate session data.

Session aggregation

You can aggregate trends by Unique sessions just as would Unique users or Weekly active users.

This provides the count of unique sessions where the specified event occurred. This can be helpful to remove the noise if you have specific events that are sent a bunch of times within a single session.

To do this, select Unique sessions from the aggregation dropdown.

Session counts

This can then be used in a formula to understand things like the average number of sessions per user or the average number of events per session.

Session formula

Filtering by session properties

You can use any of the session properties to filter your data. For example, to remove sessions that are shorter than 10 seconds, you can filter for sessions where duration is greater than 10 seconds.

Session duration filter

Plotting session properties

You can plot session properties over time like you would with an event count. To do this, select one of the property aggregators (e.g. median, 90th percentile, etc.) and then select the session property to plot. For example, to plot the median session duration, select Property value median and then select Session duration as the property.

Session median duration

Breaking down by session properties

You can view the distribution of different session property values by breaking down by that property.

This is useful for understanding entry URLs or UTMs. For example, to break down sessions by entry URL, click Property value and then select Entry URL.

Entry URL breakdown

Server SDKs and sessions

Our server-side SDKs do not send $session_id by default. If you want to use sessions with server-side events, you can manually set the $session_id property. This lets you use session aggregations for these events and can be useful if you want to connect server-side events to session replays or web analytics sessions.

You can either pass the session ID from posthog-js into your back end, or generate a new session ID. You can then use this session ID in your server-side events.

If the events are logically part of the same session, e.g. a user starts a purchase on the front end and you receive confirmation on the back end, it's better to re-use the session ID from the front end. On the other hand, if the events have no corresponding front-end session, you can generate a new session ID.

Passing Session IDs from client-side code into server-side events

Get the session ID from posthog-js with posthog.get_session_id() and send it to your server with custom code. Then, you can set the session ID on the server-side event with posthog.capture({ ..., '$session_id': session_id }).

Here's an example of how you might do this:

JavaScript
// Client side code
// Get the session ID
const posthog_session_id = posthog.get_session_id()
// Make a request to your server. This is just an example, you should replace this with your own code.
fetch('https://your-api.example.com/purchase', {
method: 'POST',
body: '[your request body]', // replace with your own request body
headers: {
'Content-Type': 'application/json',
'X-POSTHOG-SESSION-ID': posthog_session_id // include the posthog session ID in a header
}
})
JavaScript
// Server side code
// This is an example route handler using Express, the actual implementation will depend on your server framework and programming language
app.post('/purchase', (req, res) => {
const { posthog_distinct_id } = handleUserAuthentication(req) // replace with your own user authentication logic
const posthog_session_id = req.header('X-POSTHOG-SESSION-ID') // get the session ID from the header
// Handle the purchase
handlePurchase(req.body) // replace with your own business logic
// Send a custom event, including the session ID
posthog.capture({
distinct_id: posthog_distinct_id,
event: 'Purchase Succeeded',
properties: {
'$session_id': posthog_session_id
}
})
res.send('OK')
})

Custom session IDs

Custom session IDs must meet the following requirements:

  • Must be consistent across events in the same session
  • Must not be reused by a different user or session
  • Must be a valid UUIDv7
  • The timestamp part of the UUIDv7 must be equal to or before the timestamp of the first event in the session
  • The timestamp part of the UUIDv7 plus 24 hours must be after the timestamp of the last event in the session

Any events with session IDs that do not meet these requirements are not included in session aggregations.

Our JavaScript Web library and mobile SDKs (Android, iOS, React Native, and Flutter) automatically create session IDs for you, but if you override them, you also must ensure they meet these requirements.

Questions?

Was this page useful?

Next article

Timestamps

PostHog automatically computes timestamps for captured events, but you can also set them manually. For example: If the payload contains timestamp and sent_at fields, the sent_at field is compared to the server time to account for clock skew. The event's timestamp is adjusted by this difference before being stored. This is the method our libraries use. If the payload includes a timestamp but no sent_at field, then timestamp is directly used as the event timestamp. If the payload…

Read next article