Skip to main content

Anonymous tracking

Snowplow enables you to track events without collecting personally identifiable information (PII). Use anonymous tracking to respect user privacy preferences, comply with regulations such as GDPR, or track events before a user has provided consent.

Every Snowplow event includes a number of identifiers. Read more about them in the overview and out-of-the-box tracking pages. You can configure your trackers to prevent the collection of these identifiers, as well as IP addresses and cookies, using anonymous tracking.

Some Snowplow trackers also provide options for tracking user consent interactions and GDPR basis for processing.

Anonymization levels

Snowplow trackers support multiple levels of anonymization to balance privacy requirements with analytics needs. Combine client-side and server-side anonymization to achieve the desired level of privacy.

As well as anonymous tracking, you can also use enrichments to pseudonymize or mask identifiers for tracked events, before they arrive at the data warehouse. This uses the PII pseudonymization or IP anonymization enrichments.

For more details on web cookie behavior, see Cookies and local storage.

Spelling

Some tracker APIs use the British English spelling: "anonymisation" rather than "anonymization".

Full client-side anonymization

When configured for full client-side anonymization, the tracker does not track any client-side user or session identifiers. Events can still be collected, but can't be grouped by user or session.

Here's some example code for enabling full client-side anonymization when creating a tracker on web or mobile:

javascript
snowplow('newTracker', 'sp', '{{collector_url_here}}', {
// No user or session identifiers will be added to events
// Network identifiers will be tracked
anonymousTracking: true,
});

By default, the tracker uses cookies and local storage to persist user and session information, as well as for buffering events. When anonymous tracking is enabled, identifiers are not saved to cookies or local storage.

Client-side anonymization with session tracking

In this mode, the tracker doesn't include user identifiers but preserves session tracking. You can analyze session-level behavior without identifying individual users.

Here's some example code for enabling client-side anonymization with session tracking when creating a tracker on web or mobile:

javascript
snowplow('newTracker', 'sp', '{{collector_url_here}}', {
// User identifiers won't be added to events
// Session and network identifiers will be tracked
anonymousTracking: { withSessionTracking: true },
});

The tracker uses cookies and local storage by default. With this configuration it will store session identifiers, but not user identifiers.

Server-side anonymization

Server-side anonymization prevents the event Collector setting the sp cookie for network_userid, or from capturing IP addresses.

Setting server-side anonymization will add a SP-Anonymous HTTP header to requests sent to the Collector. This requires the request method to be POST, which is the default for most trackers. When the SP-Anonymous header is present, the Collector doesn't set or read the sp cookie.

An alternative method for preventing IP address tracking is to set a null value, such as 0.0.0.0 within the tracker. Most Snowplow trackers support this option, although not the JavaScript trackers.

In the JavaScript trackers, setting server-side anonymization also sets full client-side anonymization. In the native mobile trackers, it's a separate configuration. You can choose either client-side anonymization, server-side anonymization, or both.

Here's some example code for enabling server-side anonymization when creating a tracker on web or mobile:

javascript
snowplow('newTracker', 'sp', '{{collector_url_here}}', {
// No user, session, or network identifiers will be tracked
anonymousTracking: { withServerAnonymisation: true },
});

For fully cookieless web tracking, configure the tracker with:

javascript
snowplow('newTracker', 'sp', '{{collector_url_here}}', {
// No user, session, or network identifiers will be tracked
// No data will be stored in the browser
anonymousTracking: { withServerAnonymisation: true },
stateStorageStrategy: 'none',
});

This configuration prevents the tracker from storing any data in cookies or local storage.

Tracker support

This table shows the support for anonymous tracking across the main Snowplow tracker SDKs:

TrackerSupportedSince versionClient-sideServer-sideNotes
Web3.0.0
iOS4.0.0
Android4.0.0
React Native❌/✅1.3.0❌/✅Version 4.x only supports server-side anonymization
Flutter0.3.0
Roku0.3.0Use Subject configuration to manage client-side anonymization
Node.js3.21.0
Golang
.NET
Java
Python
Scala
Ruby
Rust
PHP0.9.0
C++
Unity
Lua
Google Tag Managerv4

Toggle anonymous tracking

As well as setting it at tracker initialization, you can enable or disable anonymous tracking during a session. Use this to start with anonymous tracking until a user accepts a cookie banner, or to enable full tracking when a user logs in.

Here's some example code for toggling anonymization at runtime on web or mobile:

javascript
snowplow('enableAnonymousTracking');
snowplow('disableAnonymousTracking');

These methods also accept an optional configuration object to specify which levels of anonymization to enable.

On web, enabling anonymous tracking removes user identifiers from outgoing events but doesn't delete existing cookies. On mobile, toggling anonymization starts a new session.

Clear user data

When enabling anonymous tracking, you may want to clear any existing user identifiers stored in cookies or local storage.

Use the clearUserData() method in the JavaScript trackers to delete all data stored in the _sp_id and _sp_ses cookies. It takes an optional configuration object to specify which identifiers to clear. To delete the network_userid in the Collector sp cookie, set server-side anonymization.

There's no equivalent API for deleting stored data on mobile.

Anonymizable event properties

Use anonymous tracking to avoid collecting the following identifiers in your events. The table shows how you can anonymize each identifier using client-side anonymization, server-side anonymization, or enrichments.

Atomic and session user IDs

Snowplow events have two properties with similar names: the user_id atomic event property and the userId property in the session entity.

The former is a business user identifier you set via the tracker API, while the latter is a device ID generated by the tracker. Both can be anonymized using client-side anonymization.

PropertyLocation in eventIdentifier typeDescriptionClient-side anonServer-side anonEnrichment
domain_useridAtomicUserUUID stored in a first-party cookiePII
domain_sessionidAtomicSessionUUID for the current sessionPII
domain_sessionidxAtomicSessionCount of sessions for this user
network_useridAtomicNetworkUUID set by the Collector in a server-side cookiePII
user_ipaddressAtomicNetworkIP address captured by the CollectorPII, IP anonymization
user_id in atomic fieldsAtomicUserBusiness user identifier set via setUserId or similar APIPII
userId in session entityEntityUserDevice ID in the client session entity
sessionIdEntitySessionUUID for the session
appleIdfaEntityUserAdvertising identifier (IDFA) on iOS
appleIdfvEntityUserVendor identifier (IDFV) on iOS
androidIdfaEntityUserAdvertising identifier on Android
tabIdEntityUserUUID for the browser tab

The PII pseudonymization enrichment supports an anonymousOnly mode, available since Enrich version 5.3.0, that only pseudonymizes fields when the SP-Anonymous header is present. This lets you keep full identifiers for consented users while anonymizing non-consented users.

It can also pseudonymize fields for structured and legacy ecommerce events, as well as these fields that are populated during enrichment:

PropertyLocation in eventIdentifier typeDescription
refr_domain_useridAtomicUserFrom cross-domain tracking
ip_organizationAtomicUserAdded by IP enrichment
ip_domainAtomicUserAdded by IP enrichment
mkt_termAtomicMarketingAdded by campaign attribution enrichment
mkt_contentAtomicMarketingAdded by campaign attribution enrichment
mkt_clickidAtomicMarketingAdded by campaign attribution enrichment