Latest posts by Winston Ong (see all)
- A Look Back at SEO Predictions - January 1, 2017
- Are you completely misreading time on site in Google Analytics? - July 11, 2016
- Happy Mobile New Year – AMP (Accelerated Mobile Pages) - January 1, 2016
If you’re new to web analytics or GA, you probably don’t realise the number highlighted below doesn’t mean what you think it says:
I’ve found +90% of people I’ve worked with in digital marketing interpret this metric as “On average, the time spent by users per visit session is 2 minutes and 31 seconds (in the selected date period)”
However, most people don’t realise the number is actually an approximation, and a very loose one at that. This is because the way GA measures session duration is to record the time stamp of each pageview and interaction event, and minus the subsequent one from the prior that occurs within an individual session.
This isn’t a secret, Google clearly explains this here with some helpful diagrams:
If no engagement hits (i.e. using pageview timestamps only):
If we have engagement hits, then the timestamps of those are used instead on the last page.
Can you see what the problem is here?
The duration of time AFTER landing on the final page in the visit, or triggering the last interaction event cannot be recorded.
You may now be thinking – so… that means my average session duration is actually higher than what Google Analytics reports?
Correct, but only for multi-page sessions, or if there’s at least one interaction event aside from the first pageviews.
But what about all your single page visits? What happens in this scenario?
There’s nothing past the First Hit at 10:00am that we can use to measure our time spent against. So that means Google Analytics thinks time spent is actually 0 seconds.
In these cases, to calculate the Avg Session Duration metric, GA excludes counting these single page visits.
If you have a very high bounce rate, let’s say 80%, that means only 20% of your total sessions are being used to work out the reported Avg time per session. Further, since single page visits (bounces) are likely to be shorter than multi-page visits, this will have the effect of inflating your true Avg Session Duration.
Not Just a Google Analytics Problem
The ‘time spent’ metric problem is not one solely confined to Google Analytics. Other web analytics programs such as Adobe Site Catalyst also use the same default method of calculating its own duration metrics. Out of the box web analytics simply uses the easiest way to very loosely approximate this a very important and oft-cited metric for engagement, but doesn’t make it clear to its users why it is incorrect.
Session Duration Breakdown
What I find most problematic about all this is the lack of clarity GA provides to beginner users, and arming them with numbers that ‘make sense’ when you understand how they are calculated, but lead to completely wrong insights when the technical context is unknown.
This is particularly true when GA users start poking around the Audience => Behaviour => Engagement Report which purports to show a bucketed breakdown of duration intervals by the number of sessions and pageviews within them.
Basically, the Engagement report that provides the interval breakdown is not excluding those single page visits, rather counting them as 0 seconds spent, which of course makes no sense. The ‘hump’ that occurs for 61-180 seconds and 181-600 seconds are all those multi page visits.
A Solution Using GA Events
The best solution to this problem I’m aware of comes via Mike Sullivan of Analytics Edge who suggests using non interaction events that trigger for your own defined timing buckets.
Add this to each page, or the pages you want to tracking time spent engagement on, and you can ignore your default Engagement report and head on over to your Events report instead. Once your run the code for a sufficient amount of time, you’ll event value populating. The code creates a TimeOnPage Event Category, with the bucketing as Event Labels.
Click on your Event Label option and you’ll get a nice accurate looking report like this: