Tag Manager Strategy: One Container or Many?

More than any other question I got at HighEdWeb this year, this one came up over and over: Should I use one container across all of my sites in Google Tag Manager, or make a separate container for each site? This was occasionally coupled with a question about performance impacts. There are merits to both approaches, and neither is necessarily “wrong.” During my final presentation, I made a promise to the community to start addressing these sorts of questions in detail, so this will be the first of many articles on Tag Manager you’ll be seeing in the near future. Let’s talk about each container approach and what the implications of each are.

First I want to address why this question exists. The idea that you should follow the one site, one container rule seems reasonable at face value. Indeed, if you want the tl;dr summary, it’s the one I’d recommend to most folks. But I think it is a question that stems from the idea that a lot of people still treat Google Analytics the same way, plumbing several sites into a single profile, and using profile filtering and hostname stringing to keep everything in one place, and splitting out separate views to deal with silos. This approach isn’t wrong, and indeed may serve functional purposes for how the organization works. I think this is why one site, one container isn’t as obvious as it seems it should be. It’s a data management problem, and while the solution I recommend is right for most cases, it’s not necessarily right for all.

One-to-Many

I’ll start with the approach I don’t love first. This is the idea that you use one container across many domains to manage all the tags that fire. In theory, all your tags, triggers, and variables could be used on any site depending on their individual configuration.

Why It Works

For one, you end up with all your stuff in one single place, which can be ideal for people that are solely responsible for managing their Tag Manager implementation. It also means you can have a complex dataLayer along with the supporting variables and events that are available to you across a lot of properties without needing to copy a container or duplicate tags between them.

As a result, trigger and variable reuse is easiest in this scenario. You’ll never find yourself redefining a Google Analytics Profile ID variable over and over in containers, instead, probably using one single lookup table variable, for instance.

Lastly, if you ever decide to switch the way you handle containers, it’s not a big deal to duplicate the container, and just cut out the stuff you don’t need – unless there’s a lot you don’t need.

Why It Doesn’t Work

Clutter. For one, you’re going to have to make heavy use of folders in this implementation to make things easier to sort and keep organized. Even with that, you’ll find yourselves rapidly getting into lists that are hard to keep usable and easy to dig through. You’ll also get into arguments with yourself (or others) over how to set up your folders. Should they be activity based, or domain based (items can only live in one folder)? If you’re going to organize your folders by site, then why not just use site based containers to begin with?

Organizing elements in folders by type

Organizing elements in folders by type

Second, and maybe more importantly, are performance issues. When you start to get large lists of triggers and tags, you create a race condition on the page. Under normal conditions, if you page has to process a lot of tags and triggers, it’s possible for the page to move on before Tag Manager has had a chance to verify everything. That’s not to say there isn’t a “solution” to this. This is where the Wait for Tags option on triggers comes into play. That can be combined with a match against relevant Page Hostnames (a built in variable) to help Tag Manager skip over non-applicable pieces.

Creating a hostname limited trigger

Creating a hostname limited trigger

So, why did I put “solution” in quote marks? Well, because it’s still not perfect. You’re required to set a timeout for this function to ensure the page carries on in the case of anything going awry, or it still taking too long (the default is 2 seconds). The other thing is, because this binds a listener to the beforeunload() event, there’s a possibility that this can cause unexpected behavior with things like popup blockers or other plugins that monitor page behavior – this is why Tag Manager warns you about testing this feature on your site before publishing it live. In most cases though, this will work fine. Most containers can fire all tags in well under two seconds, and if you want to use this sitewide, you just set up an Enable When condition similar to “Page Path – starts with – /“. But if we’re talking about a single container, with a hundred triggers and several dozen tags… well, it’s not the page performance you have to worry about so much as the fact that you might get into situations where tags misfire.

Another issue to consider is that since Tag Manager user permissions currently stop at the container level, you cannot restrict someone’s visibility within the container if you need to give them access to information. It would be nice if Google would add in folder level permissions, but alas, we’re not there yet. So whether you have a marketing person wanting in, or maybe a consultant, you get into an all or nothing situation. Basically, it’s very unfriendly to multi-tenant situations.

Finally, when using one single container, it can make keeping up with version publishing and environments much more complicated – if not useless – due to the domain overlap. While you could maintain it all and make sure your environments are adhered to, it becomes a complex operation. Plus, by using environments (which are really offered more as a tool for testing and escalating changes from a development to production state, rather than as a way of separating several production environments), you’re still in a position where you have to deploy slightly different container code to each domain, at which point you might as well use separate containers anyway.

Many-to-Many

In my opinion, this should be your go-to setup. This is the one site, one container approach where you’re basically considering each container to be unofficially domain-bound. It is worth noting, I usually will maintain a “generic container” I can use for covering low-level tags on sites that don’t need special treatment (e.g. pageviews, outbound link tracking, shared 3rd party framework includes, etc). This container can also be copied to create the skeleton of new containers you’re making. More on that in a moment.

Why it Works

Just like running separate Google Analytics profiles for sites, this allows you to keep your sites firewalled from each other without risk of functionality bleeding across them unintentionally. Sites only have to worry about just the tags and triggers that are relevant to them, and you reduce the necessity for enabling the Wait for Tags option on triggers. (Not that I’m trying to imply you should avoid its usage – on the contrary, use it as much as it makes sense. It’s just that it’s almost required in the one-to-many setup, whereas here you can use it just when needed.)

Unlike the One-to-Many approach, if someone needs access to Tag Manager, you can limit them to just the sites’ containers they need to see, limiting the potential for any mistakes. This also keeps you more organized in general. If you use the approach I mentioned above with a common “skeleton” generic container that has the basic tags you use consistently, it can be cloned each time you need a new one, ensuring that each site is based on the same basic layout and structure.

Container Import functionality

Container Import functionality

Last, but not least, you’re also empowered to more successfully use environment options if your web stacks allow you to do so.

Why it Doesn’t Work

There are only a couple “good” reasons this approach isn’t ideal, and I’d argue that they are merely inconveniences that shouldn’t stop you. For instance, if you use a common Custom HTML tag or a Custom JavaScript variable on several sites, and you find that you need to change it, then you’re left in a situation where you need to go to each container that it’s used and update it. I wouldn’t expect this to happen frequently for most people though, and I believe that inconvenience to be far outweighed by the other advantages to the overall setup.

In a similar vein, if you use container copying to set up new containers, and your base container changes over time, then older containers similarly need to be updated if they need the missing or modified pieces. How big a deal these things are somewhat depends on the number of containers you manage though, and just what is changing.

Multiple containers can also make permissioning more complex, since there’s obviously more to deal with. I’ve dealt with this a couple times, but generally find this, again, to be barely more than an annoyance than something that’s an actual problem. This is part of where the simplistic permissions model helps Tag Manager.

Multiple Containers?

So, there’s a third, red-headed step-child of an approach that could be used, which is the use of several containers on a site. I mention it more for the sake of completeness, and not as an endorsement. Google does support it now (they didn’t used to, officially), but only with a shared, common dataLayer. The main reason I discourage this is because it introduces a number of ways you could potentially break or pollute your tags, especially if you are still just getting used to things. Tag Manager will prevent duplication of single-fire events to a degree, but that doesn’t prevent things like duplicate tags themselves from firing if they exist in each container.

“Note that you can use only a single common data layer for all Google Tag Manager containers on a page because using more than one data layer can cause some triggers to stop working and could have other implications. So don’t rename the data layer for a subset of containers on the page. You can, if necessary, rename the data layer for all containers on the page.”Google Tag Manager Web Tracking Guide

The use case where this does make sense is if you have an outside 3rd party helping with your Tag Manager implementation, and want to temporarily give them a container with unlimited access without affecting your current container. Once they are done, the idea would be that you would import their container changes into your production container, and then you’d remove the extra container once done.

Conclusions

If you didn’t notice, I’m pretty biased against the one-to-many approach to containers. I think for most people, in most cases, maintaining the one site, one container should be the rule, and only use the other two options when they are specifically appropriate to the use case. Hopefully this clarifies the use cases for you and helps you decide what’s right (or wrong) about how you’re planning your GTM deployment now. If you have any other questions that weren’t answered, please leave them in the comments below.