Cookie Settings and Subdomain Tracking in Universal Analytics

How the cookieDomain settings works in your Google Analytics tags, and what happens if you don't set it.

Welcome back my friends (to the show that never ends)! It’s been a couple of weeks since my last barrage of articles, and I think the time is ripe to do some testing!

First things first, here’s a picture of me shovelling snow:

And now back to the topic at hand.

One of the things that seems to be a hot topic in Universal Analytics is cross-domain tracking. I’ve never really tackled the beast head-on, since there’s such a wealth of excellent articles about it out there. However, I have taken a plunge into the deep end with some specific stuff, such as iframe and subdomain tracking.

I want to pick up where I left off in the subdomain article, and focus on something really cool but complicated: cookie settings.

First, take a look at the official developer guide for Universal Analytics’ cookie stuff. It’s an excellent resource to get started with.

What I want to talk about is what are the implications of inconsistent field settings as well as leaving the cookieDomain field out entirely from your tracker settings.

I give you…drumroll…my epic, sugar-rush, pigeon-army, mudslide, Iron Man, lollapalooza, Han-shot-first, cookie-testing-extravaganza-MIND-EXPLOSION!

Sorry.

What we know

Let’s start at the beginning (always a good idea). This is what we, most likely, know about Universal Analytics’ cookies.

  1. Universal Analytics uses a single _ga cookie to establish the user dimension.

  2. This cookie stores a unique Client ID in its last two segments (GA1.2.12345.23456).

  3. By default, i.e. without any settings, the cookie is written on the current subdomain and all even more nested subdomains thereof (.sub.domain.com, .www.sub.domain.com, .simo.rules.ok.sub.domain.com would all share the cookie written on .sub.domain.com, but www.domain.com or domain.com would not).

  4. By setting cookieDomain to auto, or manually setting it to the topmost possible domain name (i.e. .domain.com), all subdomains can use the cookie.

I hope that’s all clear.

This is why the “tracking snippet” for Universal Analytics always has the recommendation of including 'auto' as the third parameter of the 'create' command. That’s the equivalent of adding the field cookieDomain : 'auto' into the tracker object:

ga('create', 'UA-12345-1', 'auto');
// is the same as
ga('create', 'UA-12345-1', {'cookieDomain' : 'auto'});

NOTE! The Universal Analytics Tag in Google Tag Manager does not add this field by default! The implications of leaving this field out are the focus of this test, so bear with me.

The test

I want to test the following:

  1. What happens if 'cookieDomain' : 'auto' is missing from your tracker, and you move across subdomains?

  2. What happens if there are multiple _ga cookies, each written on different domains

  3. What is the air-speed velocity of an unladen swallow?

Let’s start with the first one.

1. No 'cookieDomain' : 'auto' set

I’ll browse to test.simoahava.com, make sure there are no pre-existing _ga cookies, and type in the following command:

ga('create', 'UA-12345-1', {'name' : 'test1'});

So, no cookieDomain anywhere. This results in a new _ga cookie, written on .test.simoahava.com:

You can also see where the cookie is written on:

That’s all clear, right?

Next, I browse to www.simoahava.com, and run the same command:

ga('create', 'UA-12345-1', {'name' : 'test1'});

And this is what I’ll see:

The cookie itself is set on the parent domain (without www.):

Now, let’s go back to test.simoahava.com and see what happens:

This is expected, of course. We see both the cookie written on the subdomain in the first step, as well as the cookie written on the main domain in the second step. The latter cookie is available here as well, as since the cookie was written on the parent domain, it can be used by all subdomains as well.

This has one very important implication. If you don’t have 'cookieDomain' : 'auto', and the traffic is from the parent domain to subdomains, there’s no issue here. Two different _ga cookies will still exist on the subdomain, as they have different domain settings, but they will share the same Client ID, thanks to one of the core features of the Universal Analytics library, which copies the Client ID from both pre-existing _ga cookies as well as legacy __utma cookies. Here’s an example where I first landed on the parent domain and then entered the subdomain:

However, if the traffic lands on the subdomain first, and then moves to the parent domain, you will end up with different _ga cookies and different Client IDs on both domains, and thus the user will be different as well!

This is quite significant. I’ll return to the implications later.

2. What happens if there ARE multiple _ga cookies?

Now, if you DO end up with multiple _ga cookies, two things can happen:

  1. They share the same Client ID, i.e. the movement was from higher-level-domain to subdomain, and all is fine.

  2. They have different Client IDs, i.e. the traffic was from the subdomain to a higher-level (or same-level) domain.

The first case is just fine. All your Tags will share the same Client ID, you won’t have problems with some Tags firing starting new sessions or creating new users, and you can sleep soundly at night.

The second case is problematic. Let’s say you DO end up with two different _ga cookies, and that it’s, at least you claim it is, intentional. How do you choose which cookie you’ll interact with your trackers?

Well, actually, it’s pretty straight-forward. When you create a tracker, it will use which ever _ga cookie shares the cookieDomain setting of the tracker.

Allow me to explain.

Let’s say you now have two different _ga cookies, one written on .simoahava.com, and one written on .test.simoahava.com. You are now on test.simoahava.com, and you want to use the Client ID of the cookie written on this subdomain. You need to create a tracker, which would write the cookie on .test.simoahava.com if you want to interact with the cookie. In other words:

ga('create', 'UA-12345-1', {'name' : 'test1'});

This would work, because without 'cookieDomain' : 'auto', the cookie would be written on .test.simoahava.com. Now, since a _ga cookie already exists on .test.simoahava.com, it is used in all interactions with tracker named test1.

If you want to interact with the cookie written on .simoahava.com, then you need to add the cookieDomain parameter, and make sure it would write the cookie on the top-most possible domain:

ga('create', 'UA-12345-1', {'name' : 'test2', 'cookieDomain' : 'auto'});
// OR
ga('create', 'UA-12345-1', {'name' : 'test2', 'cookieDomain' : '.simoahava.com'});

Both would do the same thing: attempt to write the _ga cookie on .simoahava.com. However, since that cookie already exists, the tracker named test2 can now be used to interact with that particular cookie.

Phew! So much talk about cookies it makes my stomach growl.

Implications

Now, let’s talk about what this all means. I’ll split this up into a little Q&A, which might help interpret the results.

Q: Should I set 'cookieDomain' : 'auto' on in all my Tags and trackers?

A: I would say that, by default, yes. Having the setting on in all Tags ensures that the same Client ID is used everywhere across your subdomains. Even if you have Tags collecting data to different UA-XXXXX-Y properties, it doesn’t matter that they share the Client ID, since it’s just a label each property uses to assign hits to the same user.

Q: What would happen if only one of my Tags has 'cookieDomain' : 'auto', but the others don’t?

A: You should still be fine, as long as that one Tag fires on every single page. Basically, when a Tag fires on the page, it first checks for a pre-existing _ga cookie. If one is found, it then checks the domain on which the cookie is written, and whether or not this matches the tracker settings. If the settings match, then the Tag simply uses this cookie. If the settings don’t match, a new _ga is written on the current domain, but the Client ID is still copied from the first cookie.

Thus, as long as one Tag on the page is fired with 'cookieDomain' : 'auto', the Client ID copying mechanism ensures that the same Client ID is accessible across your domains.

Q: What happens if I don’t have the 'cookieDomain' : 'auto' setting anywhere?

A: In the best case scenario, nothing. This would require that traffic is always from a higher-level-domain to its subdomain. This way the subdomain can copy the Client ID from the higher-level-domain cookie.

However, if traffic can be the other way around, so starting from deeper in the domain structure and moving up (or parallel), you’re in trouble. You’ll end up with different Client IDs since the cookies are not shared across the domains.

I hate doling out “best practices” since I don’t believe they exist, but in this case we’re talking about a technological reality. I strongly recommend that you always add the 'cookieDomain' : 'auto' field to all your Tags and trackers. If that’s a stretch, then make sure that at least one Tag which is guaranteed to fire on all pages has that setting. This way the Client ID will be copied and passed across the domains.

Next time I’ll write something lighter, I promise!