Google Analytics features 3 types of custom variables: page-level, session-level, and visitor-level. The official Google Code documentation on custom variables is pretty explicit about the fact that it’s best not to mix types:

“Generally it is not recommended to mix the same custom variable slot with different types as it can lead to strange metric calculations.”

What isn’t exactly clear is what happens if you do decide to mix types. Google Code provides two cases, but surely there are additional cases. To this end, I decided to test 9 total cases:


Case 1: Page to Page
Case 2: Page to Session
Case 3: Page to Visitor
Case 4: Session to Page
Case 5: Session to Session
Case 6: Session to Visitor
Case 7: Visitor to Page
Case 8: Visitor to Session
Case 9: Visitor to Visitor

Granted, three of these cases are not mixed type, but I decided to include those cases as well since the behavior for those cases should be well defined and good benchmarks for the other cases.

It would also be good to know exactly how Google Analytics attributes conversions in these types of situations. To that end, I set up a test with 5 different pages:

Page 1: Standard Google Analytics Tracking Code
Page 2: Set first type of custom variables
Page 3: Standard Google Analytics Tracking Code
Page 4: Set second type of custom variables
Page 5: Standard Google Analytics Tracking Code

In Google Analytics, I set up 5 different goals, one for each of the above pages. The idea is to see whether or not each custom variable gets credit for a conversion on a previous page, the current page, or any successive page.

I also included a second visit, with two additional non-goal pageviews just to confirm behavior for visitor-level custom variables.

Normally you’re restricted to using 5 custom variables, but it is possible to get more than this. This allowed me to run a single test with 9 custom variables at once, which looked something like the following on Page 2:

<script type=”text/javascript”>

var _gaq = _gaq || [];
_gaq.push([‘_setAccount’, ‘UA-12345-1’]);
_gaq.push([‘_setMaxCustomVariables’,9]);
_gaq.push([‘_setCustomVar’,1,’page_page_1′,’page_page_1′,3]);
_gaq.push([‘_setCustomVar’,2,’page_session_1′,’page_session_1′,3]);
_gaq.push([‘_setCustomVar’,3,’page_visitor_1′,’page_visitor_1′,3]);
_gaq.push([‘_setCustomVar’,4,’session_page_1′,’session_page_1′,2]);
_gaq.push([‘_setCustomVar’,5,’session_session_1′,’session_session_1′,2]);
_gaq.push([‘_setCustomVar’,6,’session_visitor_1′,’session_visitor_1′,2]);
_gaq.push([‘_setCustomVar’,7,’visitor_page_1′,’visitor_page_1′,1]);
_gaq.push([‘_setCustomVar’,8,’visitor_session_1′,’visitor_session_1′,1]);
_gaq.push([‘_setCustomVar’,9,’visitor_visitor_1′,’visitor_visitor_1′,1]);
_gaq.push([‘_trackPageview’]);

(function() {
var ga = document.createElement(‘script’); ga.type = ‘text/javascript’; ga.async = true;
ga.src = (‘https:’ == document.location.protocol ? ‘https://ssl’ : ‘http://www’) + ‘.google-analytics.com/ga.js’;
var s = document.getElementsByTagName(‘script’)[0]; s.parentNode.insertBefore(ga, s);
})();

</script>

On page 4, I changed all the names and values from _1 to _2 and made appropriate changes to the scope of each variable (3 for page-level, 2 for session-level, 1 for visitor-level).

There are a couple interesting things to note if you ever decide to run a test like this. First, if you run your test too soon after creating a new Google Analytics profile, it’s possible that the data from that test will never show up in your reports. So it may be a good idea to wait an hour or so after creating the profile before running the test to make sure that you’ll see any results.

Second, certain types of information take longer than others to show up in your profiles. While you can segment by custom variable keys and values pretty much as soon as the data shows up in your reports (in well under an hour in some cases), the dedicated Custom Variables (in the old version of Google Analytics) report actually takes as many as 48 hours before any data starts showing up in your reports. So this is something to be aware of if it looks like things are missing.

The result? Take a look:

custom_var.png

Just to be clear, when the custom variable appears with an _1, it means that the first custom variable set was reported. When the custom variable appears with an _2, then the second custom variable set was reported. For example, the entry for session_page_1 means that the session-level custom variable was reported, while the entry for session_visitor_2 means that the visitor-level custom variable was reported.

Based on the data, we can conclude the following:

1. If a visit only includes page-level custom variables, then each custom variable set will receive attribution for the page it was set on, including goal attribution if the goal was set for that page.

2. If a visit contains either a session-level or visitor-level custom variable, then the last of these set will be the only one that’s reported. Furthermore, that same custom variable will be the one that receives credit for any and all goal conversions during the visit, regardless of whether those goal conversion appeared before, at the same, or after the custom variable was set.

3. A corollary to #2 is that for a visit that contains a page-level custom variable and either a session-level or visitor-level custom variable, only the session-level or visitor-level custom variable is reported.

4. Based on the custom variables that received more than one visit, a visitor-level custom variable only persists if it was the last custom variable set. For example, while the entry for visitor_page_1 indicates that the visitor-level custom variable received credit for the visit, because the page-level custom variable was set after visitor-level custom variable, the visitor-level custom variable was not reported on the subsequent visit, as indicated by the fact that there was only 1 visit for this custom variable. If you watch the __utmv cookie, you’ll see that the data for the visitor-level custom variable is actually removed when a page-level or session-level custom variable is set for the same slot.

The results of this test also prompted a follow-up test for an edge-case:

Case 10: Visitor-level on the first visit, page-level on the very first page of the second visit.

It turns out that the visitor-level custom variable is reported on the first visit, as expected, but the page-level custom variable is reported on the second visit.

Based on these results, it looks like two cases is sufficient to account for all mixed type situations, but it might help if the first case provided in official Google Code documentation more clearly show-cased these rules.

For the first case, instead of the following scenario:

case_1.png

The following would more clearly illustrate the precedence property:

case_1b.png

The fact that the visitor-level custom variable set on page 2 would be the one reported more clearly indicate the way the precedence works. There would also be an opportunity to mention the fact that because the page-level custom variable occurred after the visitor-level custom variable, that the visitor-level custom variable would not be reported on any subsequent visits.

Feel free to leave any questions or comments about custom variables, especially if you can think of additional scenarios that are not covered by the official Google Code documentation or this post.