Google Analytics Performance Tuning: "True" Direct

December 4, 2017

Howdy y’all; me here again to talk to you about “Direct” traffic. A few quick bullet points:

  • Direct or (direct) / (none) traffic isn’t “bookmark” traffic, it’s traffic whose source we cannot identify.
  • Many sessions that are actually Direct are re-labeled to the user’s previous session referring information instead.
  • … except in the Multichannel Funnel (MCF) reports, where they’ll be labeled as “Direct” instead, but sometimes these are not Direct.
  • And additionally, sometimes UTM parameters can rain on your parade, too.

This blog is a part of our Attribution series, so we’ll be sprinkling links to other posts throughout.

A Very Important Warning

This post covers tweaks and code necessary to overhaul attribution in the reports to something a bit more straightforward. Whether or not you should implement these changes will be a decision for you and your company. Even Analytics experts are divided are this topic; it is really a personal decision that depends largely on how you use the data or plan on using it.

Be warned: the changes I’m going to suggest are not for everyone; they’ll irreversibly change your Google Analytics reporting and data collection in very fundamental ways. Do not make these changes with properly considering the implications and discussing with your team. You’ve been warned.

1) Identifying Direct Traffic That Isn’t

Use campaign parameters, duh. If you don’t know what these are, this post isn’t for you. Seriously, get out of here. Here’s a blog post I wrote. Get it together.

2) Stop Campaign Inheritance

Campaign inheritance is what I call the session re-labeling “feature”. This is how Google Analytics handles figuring out traffic sources, something called “last non-direct click attribution,” Not familiar? Say a user clicks your AdWords ad and has a nice visit on your site. Later on, they’re feeling nostalgic (“Oh, honey, remember that parallax scrolling background! Yeah, with the scroll hijacking.”), so they come back, typing in the URL by hand.

You might expect their second session to be labeled as “(direct) / (none)” – nope, it’s “google / cpc”. Google Analytics figures that it’s more helpful to you as a marketer to attribute that session to the last non-direct attribution session they’ve got; that might have had something to do with this second session, after all, whereas “(direct) / (none)” is just a black hole.

For more information, head over to Becky’s post which goes into full detail about last non-direct click attribution.

If you’d prefer the session be labeled “(direct) / (none)” instead of “google / cpc”, you need to change the Campaign Timeout setting in the Property Settings to 0. This will tell Google Analytics to attribute each session independently of the last.

You can expect to see a greater percentage of your traffic attributed to the Direct channel after this change is made.

3) Fix Non-Direct Direct in the MCF Reports

As previously mentioned, MCF reports will attribute “Direct” traffic a little different. At first brush, it appears that sessions that were really direct (no referral/UTM parameters) are marked and treated as such in these reports, even as they’re attributed to their most recent non-direct attribution in the standard reports. This turns out to not be the case.

The reality is that sessions are marked as “Direct” when the session would have been attributed to the same campaign information as the most recent session for the user (remember: direct sessions are set to the most recent values, per above). isTrueDirect and the “Direct Session” dimension behave the same way. If someone comes via Google Search to your site twice in a row, the second session will be marked as Direct in the MCF reports, even though they used a search engine each time.

Good news! This is taken care of by changing the Campaign Timeout. Once set to zero, these reports will also show the real campaign information or Direct. Dust off your hands, you badass, you.

4) Fixing Errant UTM Parameters

UTM parameters are great, but sometimes they do undesirable things. For example, if I came to your site via a tagged link and bookmarked that page, every time I’d come back I’d register a new session attributed to that campaign. I might share that URL with a bunch of friends, who now all end up being attributed to that campaign, too (this might be desirable, from your perspective).

Add a hitCallback that will scrub campaign parameters from the URL after the user’s first page view.

function () {

  if (!window.history) return;
  var path = document.location.pathname;
  var search = scrub('?', ''));
  var hash = scrub(document.location.hash.replace('#', ''));
  var newPath = path + (search ? '?' + search : '') + (hash ? '#' + hash : '');

  window.history.replaceState('','', newPath);
  function scrub(s) {

    if (!s) return;
    s = '&' + s;

    var params = ['medium', 'source', 'campaign', 'content', 'term'];
    var b,

    for (i = 0; i < 5; i++) {
      b = s.indexOf('&utm_' + params[i] + '=');
      if (b > -1) s = s.slice(0, b) + s.slice(s.indexOf('&', b + 1), s.length);
    return s.slice(1);



Once the first page view has been recorded in Google Analytics, the callback here will clean those parameters out of the URL. This will keep the user from gunking up your data with them later on.

With all of these changes in place, you’ll get reports that are more literal in their interpretation of Direct traffic, with hopefully fewer visits marked as Direct, too.

Have questions? Sound off below.