Track session duration conversions in GA4

Contents
    Add a header to begin generating the table of contents

    Google’s Universal Analytics had a built-in session duration goal conversion type, and it was very useful for sites that value user engagement. GA4 does not have similar functionality, but there are several ways to accomplish something similar. In this post, we describe both approaches.

    The first we’ll cover entails setting up an audience based on a session duration target, and then creating an audience trigger to send an event to GA4 each time a user is added to the audience. This approach is the easier of the two, but audience-triggered events have a significant downside: they result in sessions being added to a (not set) row in the Landing page report. 

    That downside is why we recommend the second approach, which uses a custom JavaScript tag in Google Tag Manager to set a cookie to keep track of how long a user has been on the site. This approach is more flexible and doesn’t result in Landing page = (not set), but it is a bit more effort to set up.

    Approach 1: using an audience-triggered event

    Step 1 - create the audience

    Create an audience with the criteria:

    • Include users when Session duration is greater than or equal to your desired threshold. The metric is measured in seconds.
    • It’s fine to leave condition scoping as ‘Across all sessions’, which is the default. The session duration metric is session-scoped, so it won’t actually track duration across sessions.
    • It’s fine to leave the membership duration at the default 30 days, since we are just creating the audience to make use of the audience trigger. 
    • Click ‘Create new’ below AUDIENCE TRIGGER to add the trigger. You can name your event whatever you’d like, but for consistency it’s good to follow GA4’s convention of lowercase letters and underscores instead of spaces. The ‘Log an additional event when audience membership refreshes’ setting is a bit tricky. We want to be able to count the event if a user exceeds the threshold in two different visits, but we don’t really want it to count more than once in a single session. If you select this option, you will overcount the event, because inevitably some users will more than double your threshold in a single session. If you don’t select it, it will undercount, since some users will exceed the threshold across multiple sessions. If both of these possibilities are problematic for you, I recommend using the GTM/JavaScript approach described below.
    Audience dialog - Session duration >= 180 seconds

    Step 2 - flag the event as a conversion

    The event won’t show up in Admin > Events right away. In my experience, it generally won’t show up until the next day. Once it does, you can flip the toggle to the right of the event to count it as a conversion. 

     

    Event conversion toggle

    You can also go to Admin > Conversions and click ‘New conversion event’ and enter the conversion name. This works even if the event hasn’t shown up on the Events tab yet.

    Approach 2: GTM & custom JS

    Step 1: create the custom HTML tag in Google Tag Manager


    Below is the code that goes in the tag. The only thing you may need to change is the value of the sessionDurationThreshold variable. The current value of 120 means that the conversion event will fire if a user is on the site for 120 seconds. A few more things to know about the code:
    • It keeps track of session length by setting a 1st-party cookie
    • The cookie has a duration of 30 minutes – so if the event hasn’t fired after 30 minutes from the start of a session, it will reset the start time.
    • Once the event has fired, the script sets a cookie to indicate that the threshold has been met. This prevents the script from sending multiple events for a given user.
    				
    					<script>
    /*
      set the threshold for the session_duration_conv event here (in seconds)
      if a session passes this threshold, a session_duration_conv event will
      be pushed to the datalayer
    */
    var sessionDurationThreshold = 120;
    
    function gtm_getCookie(name) {
      var cookies = decodeURIComponent(document.cookie);
      var cookiesArray = cookies.split(';');
      var cookie = cookiesArray.find(function (item) {
        return name == item.trim().substring(0, name.length);
      });
      return cookie;
    }
    
    
    (function() {
      var startCookie = gtm_getCookie("gtm_session_start");
      var thresholdCookie = gtm_getCookie("gtm_session_threshold");
      var d1 =  new Date();
      // The getTime() method returns the number of milliseconds from 
      //midnight of January 1, 1970 to the specified date
      var now = d1.getTime();
      // convert the threshold to milliseconds
      var durationThreshold = sessionDurationThreshold*1000-1;
      var cookieExpiry = new Date();
      // Set expiry time of 30 mins (in milliseconds)
      cookieExpiry.setTime(cookieExpiry.getTime() + 30 * 60 * 1000);
      var expires = "expires=" + cookieExpiry.toUTCString();
      // if no session start cookie exists, create it and be done
      if (!startCookie) {
    	  document.cookie = "gtm_session_start" + "=" + now + ";" + expires + ";path=/";
      } else if (!thresholdCookie){
    	  // get the start time - the slice removes the name of the cookie
    	  var startTime = startCookie.trim().slice(18);
    	  var elapsedTime = now - startTime;
    	  if (elapsedTime > durationThreshold) {
    		  window.dataLayer = window.dataLayer || [];
    		  dataLayer.push({ 'event': 'session_duration_conv' });
    		  // once the event has been sent, set a threshold cookie so we
    		  // don't send it again
    		  document.cookie = "gtm_session_threshold=true;" + expires + ";path=/";
    	  }
      }
    })();
    </script>
     
    				
    			

     Special thanks to Jude Onyejekwe’s detailed post on pages per session conversions on Analyticsmania.com, which was the inspiration for this approach.

    Below is the configuration of the tag in Tag Manager. In addition to the All Pages trigger, I added History Change and Scroll Depth triggers. The website I was setting it up for uses history changes rather than full page reloads, hence the History Change trigger. I also added a scroll depth trigger, since a user might spend a while reading a single page, then leave. My scroll depth trigger fires on 25%, 50%, 75% and 100% vertical scrolls. A video commenter also suggested adding a Timer trigger, which is a good way to ensure that the tag always keeps track of how long is on the site. I’m fairly judicious about using Timer triggers, since they add a little bit of overhead to a page, but depending on your circumstance you may want to add that too.

    screenshot cHTML tag

    Step 2: add the Custom Event trigger to fire on the session_duration_conv dataLayer event

    It should look like this.

    Screenshot of GTM UI for adding a custom event

    Step 3: create the GA4 Event tag in Tag Manager


    I kept things simple and just used the same event name all the way through. Fire the tag on the trigger you just created.
    gtm session duration conv event

    That’s it for Tag Manager and you’re nearly done! I always recommend testing changes in Tag Assistant before publishing. When you do, you should see the Custom HTML tag firing on page views and whatever other triggers you added. Then, after your duration threshold is met, you should see the GA4 event tag fire.

    Step 4: flag the event as a conversion in GA4

    In GA4, go to Admin > Events and mark the event you created as a conversion. You may have to wait until the next day for it to show up.
    flagging session duration conv

    If you’d like help with this or any other analytics projects or tasks, reach out! We also do training.

    3 Comments
    Oldest
    Newest Most Voted
    Inline Feedbacks
    View all comments
    Gonçalo Albuquerque
    Gonçalo Albuquerque
    6 months ago

    Nice solution! Thank you for sharing this 🙂

    Stanley
    Stanley
    4 months ago

    Great solution!

    When I use the tag with 120 seconds it works fine, but when I want to use the tag with 60 seconds I don’t get the event. Do I have to make more changes in HTML than only the threshold?

    GA4 Path Analysis with BigQuery

    This article details the process of building two BigQuery tables for path analysis, with a focus on creating Looker Studio reports that visualize user journeys through page views and events. It accompanies a GitHub repository featuring code for automating these transformations using Google Dataform. I’m often frustrated by GA4’s limited ability to visualize user journeys

    ➔ Read more

    Don't Miss a Beat

    Marketing analytics insights, delivered to you.

    Two monthly emails featuring our latest guides and discoveries.

    have you registered?

    Our next free digital marketing seminar is coming soon!

    [MEC id="946"]