The FPID Cookie for Google Analytics in Server-Side Tagging

The new FPID HttpOnly cookie is used by Google Analytics to replace the script-readable _ga cookie. It requires a Server-side tagging setup to work. In this article, I'll show you how FPID works, and how to set it up.

Last updated 27 April 2023 with details about preventing FPID access in cookieless scenarios.

With Server-side tagging, the developer community has a chance to vastly improve the data collection capabilities of Google’s analytics platforms (Universal Analytics and App+Web). The ability to build our own templates is particularly potent with a Server container.

However, it’s not as if Google themselves are just sitting idly by and seeing what the community can come up with.

In the built-in Universal Analytics Client template in a Server container, there’s an option to migrate to a Server Managed Client ID.

When using this particular Client for proxying Google Analytics requests, the Server container introduces a new cookie that is only accessible to the webserver and not to browser JavaScript. This cookie is named FPID (First Party Identifier) by default. The value stored in FPID will be used for setting the Client ID in the request to Google’s servers.

In this article, I’ll walk you through how this works and what its implications are for data collection and security.

How it works

Be sure to check out the main guide for an introduction to Server-side tagging. An understanding of how Clients and tags work will make following this article much easier.

Google Analytics uses the &cid URL parameter in its data collection HTTP request to pass the Client ID from the browser (or device) to Google Analytics’ servers. This Client ID is persisted in a first-party cookie written (and read) with JavaScript.

With FPID, Google is moving away from the JavaScript-accessible cookie to an HTTP-set one, which is further secured with the HttpOnly flag. The new setting in the Universal Analytics Client gives you a couple of approaches to how to migrate (or not).

JavaScript Managed - business as usual

When you set the configuration in the Client to JavaScript Managed, the Client will read the incoming request as usual, use the &cid parameter from the request to set the Client ID in the outgoing request to Google Analytics, and then not really do anything else. So if you don’t want to use this new way of storing the client identifier, you need to set the option to JavaScript Managed.

However, when you set it to Server Managed, the Client will now parse the identifier from a new cookie and prefer that to what the browser (or device) sends as the value of the &cid parameter. The new cookie is written in the Set-Cookie HTTP header in the response back to the browser or other network source.

In other words, without making adjustments (see below), the Server container will generate a new FPID cookie (if one doesn’t already exist) and use that to populate the Client ID of the outgoing request to Google Analytics servers.

The cookie is set with the HttpOnly flag, which means it is not accessible to browser JavaScript. Only the webserver can read the value of the cookie. This mitigates against cross-site tracking, as first-party JavaScript-readable cookies are often repurposed for building cross-site profiles.

Setting the cookie in the HTTP response also makes it a bit more resilient against browsers with measures in place to reduce the utility of JavaScript cookies (see e.g. Apple’s Intelligent Tracking Prevention).

Migrating from JavaScript Managed to Server Managed

To ensure that the Server container doesn’t just start creating new Google Analytics users en masse, you can select the Migrate from JavaScript Managed Client ID option.

With this option, the Universal Analytics Client will continue using the original JavaScript Managed Client ID value until such a time that the _ga cookie is deleted or the Client ID is reset. At that point, the system will migrate to the new Server Managed option stored in the FPID cookie.

Here’s what it does in detail:

  1. IF the incoming HTTP request doesn’t have the FPID cookie but does have the &cid parameter set in the request, a new FPID cookie is created with a hash from the value of the &cid parameter in the incoming request. This &cid value is passed through to Google Analytics as the Client ID, thus not resetting the user.
  2. IF the incoming HTTP request has both the FPID cookie and the &cid parameter AND the FPID hash has been generated from this precise &cid parameter, the value of the &cid in the incoming request is passed through to Google Analytics as the Client ID, thus not resetting the user.
  3. IF the incoming HTTP request has the FPID cookie and either doesn’t have the &cid parameter OR the values differ, then the hash stored in FPID is sent to Google Analytics as the Client ID. This technically “resets” the user, but since the &cid already has a different value than what the FPID was originally derived from, the user would have been reset anyway.

Note that the FPID hash generated from the &cid value also includes a server-side seed, making it impossible to deduce the FPID value from that stored in the _ga cookie using client-side code.

If these hits sent by the Server container are collected in a new Google Analytics property, it makes no sense to enable the migration option, as there would be no pre-existing users. Just use the Server Managed option without the migration selection checked.

On the other hand, if you start with a Server Managed setup but then want to switch to the migration flow, perhaps because you decide to start collecting to your main Google Analytics property instead of a test property, you can enable the migration option. However, you’ll first want to rename the FPID cookie or else the value stored in FPID from the original setup will be used instead of the Client ID of the incoming request. Renaming the FPID cookie essentially resets it.

Caveat 1: Multiple Google Analytics cookies

One problem that arises with the Server Managed FPID cookie is when your site’s trackers use different Client IDs. This is quite common, especially with cross-domain tracking, where the roll-up cookie is kept separate from the regular Google Analytics cookie to avoid cross-domain tracking from overwriting the Client ID for trackers that don’t want to use cross-domain tracking.

There is no support for multiple Client IDs in the Server Managed FPID option, so if you don’t want the Server Managed option to break your multi-cookie setup, you need to hold off until a solution is released.

Caveat 2: Cross-domain tracking

Update 12 August 2021: This caveat is no longer valid, as cross-domain tracking now works with the FPID cookie, too.

Similarly, because FPID is HttpOnly, it doesn’t lend itself to cross-domain tracking. Cross-domain tracking is enabled with client-side code, and the HttpOnly flag makes it impossible for client-side code to access the Client ID for cross-domain link decoration.

There is very likely a feature being designed to support cross-domain tracking, but until such a feature is released, you should hold off from running with the Server Managed option.

Caveat 3: No cookieless option

Update 27 April 2023: This caveat is no longer valid, since you can now conditionally set the FPID name to an empty string to prevent SGTM from accessing the cookie.

Client-side Google Analytics can be used without cookies. This is a viable option in the EU if the user hasn’t given consent for storing or persisting any data in the browser or device.

Unfortunately, the Server Managed FPID cookie doesn’t currently have a way to comply with this wish. Incoming HTTP requests claimed by the Client with the Server Managed option activated generate the FPID cookie in all cases.

Again, if this is a deal-breaker for you, you’ll need to wait for the Client to support a cookieless option.

Summary

If Google Analytics engineers were given a chance to redesign how GA persists the client identifier, they would build GA with the FPID (or something similar) and steer far away from JavaScript cookies.

Cookies are notoriously tricky to get right, but the fact is that the closer they are to client-side access, the less secure they are. Even though the Google Analytics identifier doesn’t have any personal data encoded within, nor can it be used as an access key for any authentication systems, it’s still a vector for cross-site tracking.

The Google Analytics cookie is a persistent first-party identifier that can be repurposed for cross-site tracking in cookie syncing setups, for example.

By moving the identifier to an HttpOnly cookie, the identifier is protected from misuse.

Give FPID a spin - you can use the JavaScript Managed option for best compatibility. Just be mindful of the caveats listed in this article.