Blast Analytics and Marketing

Analytics Blog

Supporting Leaders to EVOLVE
Category: Google Analytics

Using Multiple Trackers in Google Analytics

April 17, 2013

Why would you want to use multiple trackers?

In case you didn’t know, there are ways to put tracking code on pages that will track to two or more Google Analytics accounts or web properties. It can get kind of tricky but once you understand the concept, it’s a breeze.

Let’s start with having a reason to put multiple trackers on your site’s pages. I’ll give you two:

  1. Tracking for affiliates – Suppose you have an e-commerce site and the vendor you use for transactions requires tracking transaction information to their own Google Analytics account.
  2. Your company has multiple sites – Perhaps your company has several locations, each with its own domain, and you want both an individual look at each domain and an aggregate look for all domains combined. This is referred to as a “roll-up tracker.” A roll-up tracker could be Profile based, Property based or even Account based. Each domain would then track on its own plus to the roll-up.

What if you have multiple sites AND also track for affiliates, would you need to have 3 trackers on some pages? YES

Is it possible to track to more than two Google accounts or web properties? the good news is YES!

Do I need a Profile, Property or Account Rollup?

Account Roll-up:
In the case of an affiliate, the need for a separate tracker is more like a requirement. The affiliate company will be tracking to their account and your site tracks to your own account.

Property Roll-up:
A Property roll-up as opposed to an Account based roll-up offers the advantage that since all Properties within an Account share users, filters and data sources, it’s much easier to configure these items and assign them to the appropriate Properties without the need to create them multiple times.

Having each site on its own Property allows you to easily report only on that specific site without the need for filtering out traffic outside of the specified domain or sub-domain. This comes really handy when you have a large collection of sites. Imagine having to create Include and Exclude filters for 24 sites?

However, this advantage presents the disadvantage of not being able to report aggregate data. That’s where a roll-up account comes in. Implementing multi-tracking code on the sites to track to separate Properties, will let you see aggregated traffic on your roll-up Property while maintaining the singularity of your site’s own Property. Add a filter to show the full domain on your roll-up Property and now you’re able to see traffic to all sites within your content reports. Add cross domain tracking to your roll-up account and you’re able to see the flow of visitors across the sites.

Profile Roll-up:
Profile roll-ups don’t require multi-tracking code, simply because profiles share their parent Property ID so the code would be the same on all sites.

If you have 2 or 3 domains, setting up a Profile roll-up may be the best solution since you don’t have to change your code and handling filters is not that complicated. Creating multiple profiles is a lot easier than creating multiple Properties since copying a profile also copies assigned filters, goals and settings while there’s no option to copy a Property. Your roll-up Profile would still need to have a filter to show the full domain.

Now that we know what we want, how do we do it?

Although it can get a little tricky when you start thinking about cookie sharing and such, the key to the solution is namespacing your trackers. This presents a little more work for your development team and unfortunately introduces room for error.

Multiple Trackers, The Standard Method

Google provides some brief guidelines into how the code needs to be structured in the “One Push, Multiple Commands” section of their development guidelines – however, they don’t really tell you much so here’s a good example:

[sourcecode language="js"]
  ['_setAccount', 'UA-XXXXX-1'],
  ['rollup._setAccount', 'UA-XXXXX-2'],
  ['affiliate._setAccount', 'UA-YYYYYY-1'],

The formula is simple, add a prefix to the Google Analytics command for your additional trackers and duplicate your code for every tracker you need. If you put two and two together, you see how this can be tedious work. You would need to duplicate every _gaq.push you have throughout your site. All Events, Pageviews, Custom Variables, and any other standard tracking commands but worst of them all, your e-commerce code complete with every _addItem command listed. That’s where it really gets heavy.

Multiple Trackers, The Blast Method

We believe in simplicity and automation. Eliminating development time and lowering the potential for errors is what drove us to develop this multi-tracker script. The benefits of the script include:

  • Easy to configure web property numbers and tracker names
  • Automated setAccount for all trackers
  • Ease of use by maintaining current method structure
  • Option to specify tracking on only specific trackers
  • Ability to modify how data is sent to Google

The Script

To start, we’re going to set some array variables at the beginning of your code:

[sourcecode language="js"]
var GA_Account_IDs = ['UA-XXXXXX-1','UA-XXXXXX-2','UA-YYYYYY-1'];
var GA_Tracker_Names = ['main','rollup','affiliate'];
var GA_Trackers = [];

You’ll want to enter the actual web property numbers for GA_Account_IDs. For the tracker names, we’ve set a pretty accurate default set of names. Feel free to change them as you please. The values can be either hard coded or populated servers side. In the example of an affiliate solution, you may be interested in capturing e-commerce transaction pages but not necessarily every page of your site. A server-side script could determine whether or not to populate the affiliate information. Make sure that you always match the position of the UA# with the position of the Name. For example, if you didn’t want to track to the roll-up on a specific page, you would enter the first and third UA#s along with “main” and “affiliate” names in the same order.

The following configuration is the star of the show:

[sourcecode language="js"]
var GA_Track = function() {
  // check to see if list of trackers is set, otherwise set to blank
  var trackers = (typeof(GA_Tracker_Names) === 'undefined') ? ['']: GA_Tracker_Names;
  // grab function arguments and put into array args
  var args=[], c = [], p = [], d;
  // check for 'bam' for specifying tracker names
    // if 'bam' is the first item of the first argument, grab the supplied tracker names and put into array trks
    c.trks=(trackers.length>1) ? args[0].splice(1): trackers;
    // drop first argument and put the rest into args
  } else { // if no 'bam' is present, use trackers and args as supplied
  for (d=0; d<c.trks.length; d++) { p[d] = [];
    for (var a=0; a<c.args.length; a++) { p[d][a] = [];
      for ( var i=0; i<c.args[a].length; i++ ) { p[d][a][i] = [];
        // if not main tracker and if first argument, insert tracker name, otherwise if main tracker leave blank, if not first argument, skip
        var r = ( i != 0 ) ? '_': ( c.trks[d] == trackers[0] ) ? '': c.trks[d]+'.';
        p[d][a][i] = (r!='_') ? r+c.args[a][i] : c.args[a][i];
      // console.log( p[d][a] ); // debug:
      _gaq.push( p[d][a] ); // push to _gaq object for GA only
// initiates the GA accounts and populates the Trackers
for ( var id=0; id < GA_Account_IDs.length; id++ ) {
  GA_Track(['bam',GA_Trackers[id]],['_setAccount', GA_Account_IDs[id]]);


More on the script will follow, but we have one more step before the task is done.

Code Replacements

As Google officially starts introducing Universal Analytics, moving forward we need to take steps to minimize the amount of work for future migrations. Since Universal Analytics uses a different syntax than Google Analytics, a migration to Universal Analytics would require you to change all existing tracking code and adjust it to the new syntax. However, Universal Analytics is a developing technology and not all existing features of Google Analytics (GA) are fully supported. So the best solution is to implement tracking code via a function that will collect the necessary data throughout the site and then reformat the way the data is sent to Google within that function.

The basis of the script is to replace the _gaq.push method with the GA_Track function on the initial Google Analytics code implementation. Right at the very end of the GA_track function, you determine how data is formatted and sent to Google. A sweet bonus is that you can enable the debug console.log and you’ll see exactly what is getting sent to Google.

On existing implementations, we will take the first step towards a smooth Universal Analytics migration now by changing all the push methods on the site as follows:

Example code case:

[sourcecode language="js"]
_gaq.push(['_setCustomVar',1,'Customer Type','member',1],['_trackPageview']);
   '1234',           // transaction ID - required
   'Womens Apparel', // affiliation or store name
   '28.28',          // total - required
   '1.29',           // tax
   '15.00',          // shipping
   'San Jose',       // city
   'California',     // state or province
   'USA'             // country
   '1234',           // transaction ID - necessary to associate item with transaction
   'DD44',           // SKU/code - required
   'T-Shirt',        // product name
   'Olive Medium',   // category or variation
   '11.99',          // unit price - required
   '1'               // quantity - required
_gaq.push(['_trackEvent','page-interaction','cart confirmation','print page', 0, true]);

With the standard method, you would need to duplicate the code above for each of the trackers. On a site with a roll-up tracker and an affiliate tracker, the code would need to be placed 3 times as shown on the previous example.

Instead, all you need to do is replace _gaq.push with GA_Track as shown below: (you’ll thank us later!)

[sourcecode language="js"]
GA_Track(['_setCustomVar',1,'Customer Type','member',1],['_trackPageview']);
   '1234',           // transaction ID - required
   'Womens Apparel', // affiliation or store name
   '28.28',          // total - required
   '1.29',           // tax
   '15.00',          // shipping
   'San Jose',       // city
   'California',     // state or province
   'USA'             // country
   '1234',           // transaction ID - necessary to associate item with transaction
   'DD44',           // SKU/code - required
   'T-Shirt',        // product name
   'Olive Medium',   // category or variation
   '11.99',          // unit price - required
   '1'               // quantity - required
GA_Track(['_trackEvent','page-interaction','cart confirmation','print page', 0, true]);

Choosing Your Trackers

Using the example of tracking for an affiliate, you would only be interested in tracking transactional pages. The account tracker does not need to be present on all pages of your site. This would be easily handled by simply omitting the tracker UA# and “affiliate” name. However, on the completion page, you want to track if the user prints the page and the affiliate does not care about this data.

You would then make a function to listen for the “print” option, or a click on the “print” button and then fire off an event tracker. However, since there have been 3 items already defined on the page; doing a simple GA_Track() call would go to all three.

To send only to the “main” and “rollup” trackers, you’ll need add an initial array whose first item is “bam” and is followed by the names of the desired trackers. Be sure your names here match exactly how they were initialized.

[sourcecode language="js"]
GA_Track(["bam","main","rollup"],['_trackEvent','page-interaction','cart confirmation','print page', 0, true]);

So what if we only have 1 tracker? No problem, just enter 1 UA# and 1 tracker name. The functionality remains exactly the same. The difference being that you can go from 1 tracker to 3 trackers by simply adding the additional numbers/names. You can also go from standard GA to Universal or both, from one location.


So exactly how many trackers can you send to simultaneously? Well, that all depends. It’s hard to imagine a scenario needing more than 4 trackers per site. We would love to hear from anyone who has needed to do so!

Limits are set by how many hits can be done in a burst. For regular Google Analytics, this is set to 10 and then it replenishes at a rate of 1 per second. In Universal Analytics, this limit is 20, replenishing at 2 per second. Anything above that will be ignored. Read more about that on Google’s Developers pages.

Keep in mind, these limits are set for hits, regardless of what type of hits they are. If you initialize your page with 3 trackers, you’ll start off with 3 pageviews. If you fire off an Event immediately after, you’ll have 6 hits. A burst is any number of hits sent within a second. If you have to send several hits to several trackers, you may need to add some delays.

Use this Free Script

Feel free to use our script on your next project. If you have any questions about implementation, simply post them as comments below. Be sure to share, like and +1 if you enjoyed this post.

  • Ah yes, JS Arrays. Nice and simple.

  • Nice tricks… thanks a ton for sharing with us.

  • Nicholas Blexrud

    Gorgeous! Thanks for the share.

  • Yehoshua Coren

    Hi Olaf,

    This is a really good article explaining a very clear and understandable method for managing multiple trackers. A +1 as always to good stuff coming from the Blast blog.

    One comment regarding limits, the burst rates that you mentioned are only for events, not for the other hit types. Pageview, commerce, social etc hits are not subject to the 10 hit per second limitation. As such, people need to be mindful of the number of hits they are rattling off with events, but not so with the other hit types. It is also worth mentioning that there is a 500 hit / session limit, which can also become an issue with 3 to 4 trackers per page.


    • @yehoshuacoren:disqus Great point. Yes, the hit limitations are subject to Events on Classic GA with a replenishment rate of 1 hit per second. The point on the 500 hit per session is also VERY important if you have any pages that have several events sent on page load and you have multiple trackers. It is important to plan these things out prior to development to ensure that they are efficient and accurate.

      • Bole

        Above mentioned limitations are defined per tracker. Adding new tracker should not have effect at all as hits are counted for each tracker individually.

  • James Carroll

    Hi, very interesting post! But it looks like the javascript got a bit messed up when you made the code/syntax highligher divs. In particular these for loops don’t look valid..

    for (d=0; d p[d] = [];
    for (var a=0; a p[d][a] = [];

    • @disqus_A2cavbWRTT:disqus thank you for pointing that out – I did update the script on there now – not sure what happened but I’m glad you caught it!

  • Massimo Como

    Hi Olaf – This is great but as I’m not quite experienced in creating scripts and tracking, I was wondering if you can guide me in the best method to use for the following scenario:

    I need to add GA tracking to one of our subdomains ( which is managed by a third party and they have their own tracking code set in place and we need to add ours. We also want to eliminate referral tracking from the subdomain to main domain ( and keep it as a single entity.

    Since the third party has to implement the tracking functionality I’m not sure if the script would be overkill. Therefore, Google’s “One Push, Multiple Commands” may be enough.

    This is my attempt at the code is the following:

    [‘_setAccount’, ‘UA-XXXXX-1’],
    [‘_setCampaignCookieTimeout’, 0],
    [‘rollup._setAccount’, ‘UA-XXXXXX-2’],
    [‘_setDomainName’, ‘’]

    UA-XXXXXX-1 is subdomain (third party)
    UA-XXXXXX-2 is main domain (ours)

    Plus, just placing it within the subdomain template file good enough or on every single page?

    Thanks for you help.



    • Hello Massimo,

      Google’s “One Push, Multiple Commands” only refers to the fact that you can piggy back several sets of commands within a single .push(). So instead of this:

      _gaq.push([ … set 1 … ]);
      _gaq.push([ … set 2 … ]);
      _gaq.push([ … set 3 … ]);

      You can simply do this:

      _gaq.push([ … set 1 … ],[ … set 2 … ],[ … set 3 … ]);

      Personally, I like doing that myself, however whenever a third party is involved it may be better to keep things separate in case either side needs to make changes to their set.

      Namespacing is critical in your situation. If you’re coming in as the “second” tracker and you set the account as “rollup” any tracking you want coming into your account should be prefixed with “rollup.”

      In your example, the first 3 items are the third party and the last three are yours. All of yours should be namespaced as such:

      [‘_setAccount’, ‘UA-XXXXX-1’],
      [‘_setCampaignCookieTimeout’, 0],
      [‘rollup._setAccount’, ‘UA-XXXXXX-2’],
      [‘rollup._setDomainName’, ‘’]

      Another thing you need to consider is timing. On any links that load on the same window, there will not be enough time to consistently fire off two pixels in time prior to dropping the document so you need to implement a delay ( about 300ms ).

      As far as placement, you need the code to be on Every page of the site, so if the subdomain template gets used on every page, that’s where you want it to be. Depending on the third party and whatever framework they’re using, this may present a challenge. You would need to contact them to see if they’re open to changing their template for you.

      Your case sounds like it can be a little complicated. You’re always more than welcome to purchase some consultation time and we will provide you with the necessary code and direct guidance for implementation as well as instructions to provide to that third party.

      • Massimo Como

        This is great, thx Olaf.

        Is there a difference who’s ‘first’ or ‘second’ tracker? Could ‘second’ tracker lose data because of placement if there’s enough time?

        • It makes a difference when you have different settings for the trackers, that’s the whole purpose of name spacing. Which one you actually place first as in the order of the syntax, doesn’t really matter. Timing WILL come into the picture if you don’t have a delay on links which cause a page reload. Both trackers may not always come through. Since it’s asynchronous code, the “first” tracker may not always be the first tracker in code order, although code order matters, how long it takes the first tracker, in code order, to get a response may vary from the second and thus may cause it to tracker after. I hope that’s not too confusing to understand?

          • Richard Barg

            Olaf. For the past 7 years, we have been using individual property accounts for 50 sites. Recently we created a new roll-up account that captures data for all 50. Thus we now have two tracking codes on each site, the individual property tracker and the roll-up code. Unfortunately, we’ve discovered today, that during April, there has been a dramatic dropoff in the number of pageviews (and other data) being reported for each the individual properties. (The roll up account was created in late March.) When filtering by hostname in the rollup account, the data is accurate, approx 15,000 pageviews for one of the sites in question. Whereas, for he GA reporting of the individual property using its won GA Code, that number is 1,000. I have confirmed both the UI for the account and the tracking code are using the new universal analytics. Any idea what may be going on here?

  • Fede Pikholc

    Hi Olaf,

    Let me ask you about cookies. It Is not a problem using multiple trackers while trying to construct a roll up? Is it possible to get two sets of cookies?

    • Hello Fede,

      Depending on how you have the rollup configured, you don’t have any issues with cookies. If you are doing crossdomain tracking on the main account but none on the rollup, or vice-versa, then you would need to make sure that each tracker is set on a different cookie and you can simply specify the cookie for it. Otherwise, sharing the cookie is ok for both accounts.

  • ChrisB

    Hi Olaf – in addition to my previous question – how would I use 2 Universal GA codes with cross domain linking and e-commerce? Thanks for the advice!

  • Tim Smith

    Has anyone had any experiences (good or bad) using more than one property with a site using Google Tag Manager?

    • We haven’t had any bad experiences although not many scenarios really call for multiple trackers on the page.

  • Sam Cardozo

    Typing “add multiple trackers ga.js” or other variant in google search bar returns very few results. Most of them are old and just one thread is from 2013. Looks like google doesn’t really wants us using multiple tracking ID for same page. It seems that it is creating cookies conflicts and then messes up with analytics reports. Anyways I have tried many times and failed. The technique described above shall be my last resort, but as a beginner I do not understand many things : why we have UA-XXXXXX-1 then UA-XXXXXX-2 ( the second is the same as the first but only ending by number 2?) And we have a third UA-YYYYYY-1…I want to use 2 ID like UA-123456-2 and UA-654321-3, so I have to put UA-123456-2 then UA-123456-3 and then the other UA-654321-3?
    Can please someone post the entire code and just not snippets as above.

    • The XXXXX’s indicate the account number and you can have 2 trackers to the same account number but to separate Properties. This is usually the case when you have a rollup across several sites. Each site will have it’s own property but they’ll be in the same account. Your rollup property would then be different but track across all sites. I used a YYYYY to indicate that this tracker would be from a separate account. This would be the case for a third party vendor.

      All of the code necessary is on the post, however, this code is now out dated so I would not use it as is. The other portions of the post explain how additional code would be used depending on what you need to do.

  • Andrey Netseplyaev

    Olaf, thanks for such a great post!
    I just have one question: I’m new to GA, and want to use GA in a “Rollup”-way, but to track ONLY those orders (conversion) from another websites, that was made after coming from my website. E.g., I’d like to provide for each shop I advertise, a specific ga-tracking code, which will at the end send information to my rollup GA account about orders that were done after the customer clicked on a link from my website. But I don’t need to know about other orders that were made on those webiste.

    Is that possible with rollup account? Or what is the best way to do that?

    • Hello Andrey

      Yes, you’re describing a very common scenario and a definite reason for having multiple trackers on a page. Although the code on this post is out dated, the method is still valid ( but you have to update the syntax to UA ). You’ll need to have cross domain enabled on both sites and then you’ll need them to place a namespaced tracker with your account ID in order for it to work.

      • Katherine Watier Ong

        Do you have updated roll up tracking code for UA developed?

        • Hello Katherine,

          Things have come a long way since this article was written. Most sites are now utilizing some sort of Tag Management solution and depending on what is implemented, the ability to track to multiple GA accounts comes in different methods. For example, Tealium supports this natively. Google Tag Manager simply requires implementation of additional GA tags which would fire with the same Triggers. This would give you additional control if you ever want something to fire to only one of the two properties.

          Additionally, if you’re on a Premium Account, Google offers a Rollup property which requires no additional trackers on the page. The rollup property is configured within the User Interface and you simply select which properties you would need to rollup.

          For this reason, although we did at some point in time develop a UA version of the script, it has not been updated for quite some time and does not make use of additional features that have been enabled since then.


Olaf Calderon
About the Author

Olaf is the Director of Implementation at Blast Analytics & Marketing. He and the implementation team, handle configuration, installation and training of analytics tools. He spends the majority of time developing tracking code and He loves the challenges that every project presents and is always finding more efficient ways for our clients to collect, read and analyze their data. His passion is developing tools, processes or methods to make everyone's life easier.

Add Olaf to your circles on Google+ Olaf Calderon has written on the Web Analytics Blog.

Ready To Do More With Your Data?

If you have questions or you’re ready to discuss how Blast can help you EVOLVE your organization, talk to an Analytics Consultant today.

Call 1 (888) 252-7866 or contact us below.