Using Google Analytics in Multi-tenant applications

Google Analytics can provide insight into how people use your site/service. In multi-tenant/SAAS applications we can use it to calculate metrics such as cost/resource utilisation per tenant.

The standard Google Analytics tracking code (suitable for most sites) looks like this:

<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-XXXXXXXX-X', 'yourdomain.com');
  ga('send', 'pageview');

</script>

With the new Universal Analytics tracking code you can send events to multiple Google Analytics accounts; useful if you want to allow your customers to provide their own tracking code in addition to your own.

To enable this scenario you should create one "master" property in the Google Analytics dashboard for your application. This will track events for all tenants.

Assuming a customer/tenant has also provided their own tracking code, the script below shows how to track page views for multiple properties/accounts:

<script>
      (function (i, s, o, g, r, a, m) {
        i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
          (i[r].q = i[r].q || []).push(arguments)
        }, i[r].l = 1 * new Date(); a = s.createElement(o),
        m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
      })(window, document, 'script', '//www.google-analytics.com/analytics.js', '_ga');

         // tenant tracking code
        _ga('create', 'UA-XXXXXXXX-X', 'auto');
        _ga('send', 'pageview');

        // service tracking code
        _ga('create', 'UA-XXXXXXXX-X', 'auto', 'myservice');
        _ga('myservice.send', 'pageview');
</script> 

There are a few differences from the default tracking code.

First we've renamed the Google Analytics object to _ga. This ensures that our tracking script does not conflict with any other services using GA, and won't stop working if someone happens to paste in their own tracking code:

(window, document, 'script', '//www.google-analytics.com/analytics.js', /* here -> */ '_ga');

Next we track the page view event using the tenant's tracking code:

 // tenant tracking code
_ga('create', 'UA-XXXXXXXX-X', 'auto');
_ga('send', 'pageview');

The auto parameter means the cookie domain is detected automatically from the URL.

Finally we create a named tracker that points to our "master" Google Analytics property. Note that we namespace the send command with our tracker name:

// service tracking code
_ga('create', 'UA-XXXXXXXX-X', 'auto', 'myservice');
_ga('myservice.send', 'pageview');

Reporting

In order to display the domain name in your site content reports you'll need to create a new view that uses a custom filter, otherwise you'll only see the relative path to the content.

Full details can be found on the Google Analytics Help Site (below "Next Steps"). I've posted the filter configuration below for convenience:

Filter Type: Custom filter > Advanced
Field A: Hostname Extract A: (.*)
Field B: Request URI Extract: (.*)
Output To: Request URI Constructor: $A1$B1

Once done you'll be able to see the domain names in your reports:

Google Analytics for Multi-tenant applications


Ben Foster

About Me

I'm a software engineer and aspiring entrepreneur with 12+ years experience in the tech industry and have worked with startups and SMB’s in areas such as healthcare, recruitment and e-commerce (I even worked in enterprise, once). I founded my first startup Fabrik in 2011.

I now head up the engineering team at Checkout.com. If you're interested in working in an exciting fin-tech company, drop me a message on Twitter.

Creative Commons Licence