User and session identifiers
Snowplow tracks a number of different identifiers to help you understand user behavior across sessions and devices. Read more about these in the identifiers overview page.
The main user and session identifiers are tracked as:
- Atomic event properties
- Session entity properties
Not all trackers have session tracking capabilities.
User atomic event properties
These properties can be assigned using most Snowplow trackers, regardless of the platform.
Some trackers set certain user properties automatically, while others require you to set them manually using the tracker's API.
If you don't manually set an IP address or network_userid, the event Collector will automatically add them to the event based on the request HTTP headers and the Collector cookie. You can turn this feature off using server-side anonymization.
| Tracker | Supported | Since version | Notes |
|---|---|---|---|
| Web | ✅ | 0.1.0 | Set user_id only. Tracker sets the domain_userid, network_userid, domain_sessionid, and domain_sessionidx automatically from cookies. |
| iOS | ✅ | 0.5.0 | Set all properties except domain_sessionid and domain_sessionidx. |
| Android | ✅ | 0.1.0 | Set all properties except domain_sessionid and domain_sessionidx. |
| React Native | ✅ | 0.1.0 | Set all properties. |
| Flutter | ✅ | 0.1.0 | Set user_id only on web. Set user_id, domain_userid, network_userid, and user_ipaddress on mobile. |
| Roku | ✅ | 0.2.0 | Set user_id and network_userid only. You can automatically populate domain_userid, domain_sessionid, and domain_sessionidx by configuring sessionAsCookies. |
| Node.js | ✅ | 0.8.0 | Set all properties. |
| Golang | ✅ | 1.0.0 | Set all properties. |
| .NET | ✅ | 0.1.0 | Set all properties. |
| Java | ✅ | 0.10.0 | Set all properties except domain_sessionidx. |
| Python | ✅ | 0.13.0 | Set all properties. |
| Scala | ✅ | 0.6.0 | Set all properties except domain_sessionid and domain_sessionidx. |
| Ruby | ✅ | 0.3.0 | Set all properties. |
| Rust | ✅ | 0.1.0 | Set all properties except domain_sessionidx. |
| PHP | ✅ | 0.1.0 | Set all properties. |
| C++ | ✅ | 0.1.0 | Set user_id and user_ipaddress only. |
| Unity | ✅ | 0.1.0 | Set all properties. |
| Lua | ✅ | 0.1.0 | Set user_id only. |
| Google Tag Manager | ❌ | Set using custom configuration. |
Session timeouts
A session is a period of time in which a user interacts with your application. A new session starts the first time an event is tracked after the previous session's timeout has elapsed.
There's no maximum session duration, but sessions do have a configurable inactivity timeout. If there's no user activity for the specified time, the session ends. A new one will start when the user returns.
For most trackers, the timeout is based on the gap between the last tracked event and the current event. Mobile trackers have two session timeout settings, allowing you to specify different timeouts if the app is in the foreground or background.
| Tracker | Foreground timeout, min | Background timeout, min | Notes |
|---|---|---|---|
| Web | 30 | - | Page pings from activity tracking will keep a session alive |
| iOS | 30 | 30 | |
| Android | 30 | 30 | |
| React Native | 30 | 30 | |
| Flutter | 30 | 30 | |
| Roku | 30 | - | |
| .NET | 10 | 5 | Uses a timer so it can expire a session independently of a new tracked event |
| C++ | 30 | 30 | |
| Google Tag Manager | 30 | - |
Session entity
Some trackers can track an entity containing information about the current session.
This table shows the support for client_session entity tracking across the main Snowplow tracker SDKs:
| Tracker | Supported | Since version | Auto-tracking |
|---|---|---|---|
| Web | ✅ | 3.5.0 | ✅ |
| iOS | ✅ | 0.5.0 | ✅ |
| Android | ✅ | 0.5.0 | ✅ |
| React Native | ✅ | 1.0.0 | ✅ |
| Flutter | ✅ | 0.2.0 | ✅ |
| Roku | ✅ | 0.3.0 | ✅ |
| Node.js | ❌ | ||
| Golang | ❌ | ||
| .NET | ✅ | 1.0.0 | ✅ |
| Java | ❌ | ||
| Python | ❌ | ||
| Scala | ❌ | ||
| Ruby | ❌ | ||
| Rust | ❌ | ||
| PHP | ❌ | ||
| C++ | ✅ | 1.0.0 | ✅ |
| Unity | ❌ | ||
| Lua | ❌ | ||
| Google Tag Manager | ✅ | v4 | ✅ |
The client_session entity contains data such as the session identifier and session index, as well as information about the previous session to help analysis.
The userId property is the device ID.
client_session
Eventiglu:com.snowplowanalytics.snowplow/client_session/jsonschema/1-0-2Example
{
"sessionIndex": 7,
"sessionId": "bca0fa0e-853c-41cf-9cc4-15048f6f0ff5",
"previousSessionId": "fa008142-c427-4289-8424-6fb2b6576692",
"userId": "7a62ec9d-2aa0-4426-b014-eba2d0dcfebb",
"firstEventId": "1548BE58-4CE7-4A32-A5E8-2696ECE941F4",
"eventIndex": 66,
"storageMechanism": "SQLITE",
"firstEventTimestamp": "2022-01-01T00:00:00Z"
}
Properties and schema
- Table
- JSON schema
| Property | Description |
|---|---|
userIdstring | Required. An identifier for the user of the session. It is set on app install. |
sessionIdstring | Required. An identifier for the session |
sessionIndexinteger | Required. The index of the current session for this user |
eventIndexnull | Optional. Optional index of the current event in the session |
previousSessionIdnull | Required. The previous session identifier for this user |
storageMechanismstring | Required. The mechanism that the session information has been stored on the device Must be one of: SQLITE, COOKIE_1, COOKIE_3, LOCAL_STORAGE, FLASH_LSO |
firstEventIdnull | Optional. The optional identifier of the first event for this session |
firstEventTimestampnull | Optional. Optional date-time timestamp of when the first event in the session was tracked |
{
"$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
"description": "Schema for a client-generated user session",
"self": {
"vendor": "com.snowplowanalytics.snowplow",
"name": "client_session",
"format": "jsonschema",
"version": "1-0-2"
},
"type": "object",
"properties": {
"userId": {
"type": "string",
"pattern": "^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$|^[0-9a-f]{16}$",
"maxLength": 36,
"description": "An identifier for the user of the session. It is set on app install."
},
"sessionId": {
"type": "string",
"format": "uuid",
"description": "An identifier for the session"
},
"sessionIndex": {
"type": "integer",
"minimum": 0,
"maximum": 2147483647,
"description": "The index of the current session for this user"
},
"eventIndex": {
"type": [
"null",
"integer"
],
"minimum": 0,
"maximum": 2147483647,
"description": "Optional index of the current event in the session"
},
"previousSessionId": {
"type": [
"null",
"string"
],
"format": "uuid",
"description": "The previous session identifier for this user"
},
"storageMechanism": {
"type": "string",
"enum": [
"SQLITE",
"COOKIE_1",
"COOKIE_3",
"LOCAL_STORAGE",
"FLASH_LSO"
],
"description": "The mechanism that the session information has been stored on the device"
},
"firstEventId": {
"type": [
"null",
"string"
],
"format": "uuid",
"description": "The optional identifier of the first event for this session"
},
"firstEventTimestamp": {
"description": "Optional date-time timestamp of when the first event in the session was tracked",
"type": [
"null",
"string"
],
"format": "date-time"
}
},
"required": [
"userId",
"sessionId",
"sessionIndex",
"previousSessionId",
"storageMechanism"
],
"additionalProperties": false
}
Warehouse query
- Snowflake
- BigQuery
- Databricks
- Redshift & Postgres
select
unstruct_event_com_snowplowanalytics_snowplow_client_session_1 client_session_1
from
atomic.events
where
events.collector_tstamp > getdate() - interval '1 hour'
and events.event = 'unstruct'
and events.event_name = 'client_session'
and events.event_vendor = 'com.snowplowanalytics.snowplow'
select
unstruct_event_com_snowplowanalytics_snowplow_client_session_1_0_2
from
PIPELINE_NAME.events events
where
events.collector_tstamp > timestamp_sub(current_timestamp(), interval 1 hour)
and events.event = 'unstruct'
and events.event_name = 'client_session'
and events.event_vendor = 'com.snowplowanalytics.snowplow'
select
unstruct_event_com_snowplowanalytics_snowplow_client_session_1
from
atomic.events events
where
events.collector_tstamp > timestampadd(HOUR, -1, current_timestamp())
and events.event = 'unstruct'
and events.event_name = 'client_session'
and events.event_vendor = 'com.snowplowanalytics.snowplow'
and unstruct_event_com_snowplowanalytics_snowplow_client_session_1 is not null
select
"client_session_1".*
from
atomic.events events
join atomic.com_snowplowanalytics_snowplow_client_session_1 "client_session_1"
on "client_session_1".root_id = events.event_id and "client_session_1".root_tstamp = events.collector_tstamp
where
events.collector_tstamp > getdate() - interval '1 hour'
and "client_session_1".root_tstamp > getdate() - interval '1 hour'
and events.event = 'unstruct'
and events.event_name = 'client_session'
and events.event_vendor = 'com.snowplowanalytics.snowplow'