
March 26, 2020
Guide: How To Use Timer Trigger in Google Tag Manager
Updated: March 26th, 2020. Are you looking for ways to fire a specific tracking script or pop-up after 20-second-delay? If your answer is Yes, then hop on board, because I’ll show you how to make use of timer trigger in Google Tag Manager.
Table of Contents
- What is a Timer Trigger in Google Tag Manager?
- Create a Timer Trigger within Google Tag Manager
- What Happens in the Data Layer?
- Use Cases of the Timer Trigger
- Postponing Email Popup
- Adjusting the bounce rate
- Combining with another trigger (via Trigger Group)
- But wait, there’s more! Start a timer trigger after a click
- Google Tag Manager Timer Trigger: Conclusion
What is a Timer Trigger in Google Tag Manager?
Timer Trigger is a type of trigger which fires after a certain duration of time has passed on the web page.
The most common uses for the timer trigger seem to be either to send an event to Google Analytics after X seconds (to lower the Bounce) or to defer a tag from firing until some asynchronous request has completed with certainty. But don’t limit yourself!

Create a Timer Trigger within Google Tag Manager
To get started, you will need to have a Google Tag Manager account and permissions to edit your website’s GTM container. Go to Triggers > New > Trigger Configuration > Timer and enter the following settings.
- Event Name: This lets you customize the event name that GTM pushes to dataLayer. It’s most useful in the case when you want to fire multiple timers on the same page.
- Interval: Here you can specify how many milliseconds should pass between each activation of this trigger. Enter 10000 if you want the time trigger to activate after 10 seconds.
- Limit: This option lets you choose how many times the trigger fires before it is stopped.
- Also, you should delimit the timer to only fire on specific pages by using the Enable When option. You’ll need to provide some condition that is already present when Google Tag Manager is first loaded, such as Page Path equals /home-page/, or something similar. In my blog, I will use the timer on all pages, thus Enable When condition is Page Path contains / (because the Page Path variable will always contain at least one slash)
- Last, you can decide whether you want to fire a tag either on all timers, or only particular ones. I used All timers.
Hit save.
A sample timer trigger could look like this (fires once after 10 seconds on all pages):
What Happens in the Data Layer?
After you created a timer trigger, enable GTM Preview and Debug mode, then refresh the website you’re currently working on (in order to test how the trigger works).
After the preview and debug console appears, wait for the timer trigger to activate.
Pro-tip by Captain Obvious: for testing purposes, create a timer trigger which fires after 10 seconds (or even less). If you set it to fire after 60 seconds (or more), you’ll end up waiting way too long and your debugging session will become super boring.
Anyway, let’s go back to our Preview and Debug mode. After waiting 10 seconds, the gtm.timer event appears on the left side of the pane.
Click it and navigate to Data Layer tab. You should see the array of various parameters.
Every time a timer trigger activates, it pushes a particular set of data to the data layer:
- gtm.timerId – A unique identifier number for the timer. Each timer you have on the page has a different ID.
- gtm.timerEventNumber – The number of timers that have activated on the current page.
- gtm.timerInterval – The value you set in the Interval option when creating the timer.
- gtm.timerStartTime – The timestamp of when the timer first started.
- gtm.timerCurrentTime – The timestamp of the most recent timer activation.
- gtm.timerElapsedTime – The time in milliseconds since the timer started.
The awesome thing about Google Tag Manager is that you can fetch any parameter from the data layer and turn it into a variable.
If you wish to know the event number (which iteration of timer trigger was just completed), you can create a Data Layer variable gtm.timerEventNumber (see the example below). P.S. dlv – stands for Data Layer Variable.
After you create this variable, refresh both P&D Mode and the website that you’re currently working on. Wait for the timer trigger to fire. Then click the event and head over to the Variables tab of Preview and Debug pane. What you’ll see it your newly created variable gtm.timerEventNumber.
What does it mean? Say, that you set the timer to fire every minute which dispatches Universal Analytics Event tag. That tag sends the following data:
- Event Category – Visitor spent some time on a page
- Event Action – {{dlv – gtm.timerEventNumber}} minutes
- Event Label – Page: {{Page Path}}
As a result, the final values of the event could look like this:
- Event Category – Visitor spent some time on a page
- Event Action – 2 minutes
- Event Label – Page: /blog/post/example
If you keep this event set as “non-interaction hit: false”, it will reduce your bounce rate.

Use Cases of the Timer Trigger
If you’re still looking for ideas where timer trigger might come in handy, here is some food for thought.
Postponing Email Popup
As I have already mentioned, I use this type of trigger myself (in this blog) in order to delay my email popup AND blue widget which ask my visitors to subscribe.
Adjusting the bounce rate
Although I really don’t like this tactic, I’ll mention it anyway. Some digital marketers use a timer trigger to fire a Google Analytics event (even though they shouldn’t)
If a visitor stays on a page for more than 60 seconds, a timer trigger activates and GA event called “Visitor Stayed for 60 seconds” fires. It’s important to mention that the GA event must use non-interaction:false setting (which is a default in Google Tag Manager).
Such an event might dramatically lower your bounce rate because a visitor not only landed on your page (1st interaction) but also stayed for more than a minute (which is considered as another interaction).
Visitors who make the 2nd interaction are not counted as bounced visitors on that page.
Although this sounds very appealing, there’s a reason I don’t use this tactic. A timer trigger activates even if the visitor isn’t actually looking at your page. He/she might simply have opened tens of browser tabs (with your site among them) and currently browse a totally different website.
Even if the visitor isn’t interacting with your website, it will count as an interaction in Google Analytics (because you just sent an event after a page is opened for more than 60 seconds).
That’s why I prefer other ways of lowering the bounce rate (which I describe in the nearest future).
Combining with another trigger (via Trigger Group)
Google Tag Manager also lets you combine multiple triggers into a mega-trigger. If ALL triggers’ conditions are met on the same page, the trigger group will be activated and the associated tags will fire.
For example, you might want to fire a tag when a visitor spends at least 60 seconds on your page AND scrolls at least 50% of the page height. You can learn more about this tactic here.
But wait, there’s more! Start a timer trigger after a click
This idea came from Simo Ahava. In case you want a timer to start when the user does something (e.g. click), you’ll need to use a Custom HTML tag with custom code. Here’s the code:
<script> (function() { // CHANGE THESE THREE: var eventName = 'custom.timer'; // The event name that is pushed into dataLayer var interval = 5000; // The interval in milliseconds var limit = 1; // The number of times the timer fires // OTHER SETTINGS: var timerNumber = 1; var startTime = new Date().getTime(); var fireTimer = function() { var timeNow = new Date().getTime(); window.dataLayer.push({ 'event' : eventName, 'custom.timerCurrentTime' : timeNow, 'custom.timerElapsedTime' : timeNow - startTime, 'custom.timerStartTime' : startTime, 'custom.timerEventNumber' : timerNumber, 'custom.timerId' : timerId, 'custom.timerInterval' : interval, 'custom.timerLimit' : limit }); timerNumber += 1; if (limit < timerNumber) { window.clearInterval(timerId); } }; var timerId = window.setInterval(fireTimer, interval); })(); </script>
It does pretty much the same thing as the timer trigger. The difference is that you can use any trigger you want to fire this custom HTML tag, for example, form submission, etc.
Example: Show a popup 10 seconds after a visitor clicks the SHARE under your article.
And don’t forget to edit the timer interval (var interval) and limit (var limit) in the script above to match your needs.
Also, the keys pushed into dataLayer differ in that the prefix is not gtm. but custom.. So gtm.timerId becomes custom.timerId, etc.
Google Tag Manager Timer Trigger: Conclusion
Although the timer trigger is pretty basic, it’s one of those must-have weapons in your Google Tag Manager arsenal. It’s fairly easy to use and allows you to postpone a certain tag for a particular period of time.
I use it to postpone email pop-up (on this blog), while others might utilize it in order to lower the bounce rate in their Google Analytics report. But don’t limit yourself just to these examples. Be creative!
Got questions? The comments section below is at your service.

23 COMMENTS
I've started using time triggers to get some insights into how long people stay on landing pages that don't need a click.
The situation you mention with tabs opened in the background is however really a problem. Could you track if the user has scrolled at all and only then start the timer somehow?
Yes, you can. To achieve this, you'll need to do several things here:
1. Import Scroll tracking to your GTM container.
2. Create a Custom HTML tag with the script I've mentioned here. Edit the script according to your needs.
3. Fire this Custom HTML tag only when a visitor scrolls more than 25 or 50 percent (you'll need to create a Custom Event Trigger for that).
Hope that makes sense.
Is it possible to retrieve only the last value of the tag v.s. creating an event for every time the event fires.
For example say 10 people visit my website. Instead of getting the following report.
10 people stayed for 10 seconds.
5 people stayed for 20 seconds.
1 person stayed for 30 seconds.
I would get the following report:
5 people stayed for 10 seconds.
4 people stayed for 20 seconds.
1 person stayed for 30 seconds.
Hello, yes, but this requires Advanced JavaScript knowledge. I could not write this listener by myself so I should ask one of my colleagues. This should take at least 2-3 weeks because the developers are now really busy.
Hi again!
Do you know how to do it on AMP site? When I create tag, I choose track type TIMING but then there are some variables to fill out. I have no idea got to fill out the first one (var)
Timer trigger is not related to Universal Analytics Tag's Track Type (it does not matter whether it's AMP, or a regular Web GTM container). If you want to learn more about the GA Timing, check the analytics.js documentation here https://developers.google.com/analytics/devguides/collection/analyticsjs/user-timings
I have created a timer for two events.1 for 3 secs and another for 4 secs.only one timer works.which I kept for higher time limit(4 secs).why ?
Both timers are separate. I suggest you take a look at timer's conditions. Maybe 3s timer is using a particular variable that is undefined at that moment?
Hello,
I have to say, this is cool.
But can you help me with this one ?
I have implemented tab visibility tag, and my pageview is firing when tab state is visible, but i want to measure the time when tab from hidden states transform to visible.
Hey, you can adapt the method used here https://www.analyticsmania.com/post/track-the-timing-of-form-submission-with-google-tag-manager/
Hey! What if I want to track people who stayed on the entire website for more than 30 seconds? Is it possible or I'll always get the data by page.
I see that the same question was recently asked in our Facebook community. Even though it is possible, the solution will not be precise and your data will be inaccurate. So I'd not recommend you do this. At least that's what I think right now :)
Wonderful article Julius, one question though, if I wanted to use the timer trigger but also needed to use a Custom Event trigger (the custom event trigger is linked to a cookie law consent solution I'm using that stops cookies firing until user consent it given), where the Custom Event trigger needs to fire first and then the Timer Trigger, how would I go about it? Any help is greatly appreciate, can't wrap my head around it. Thank you
Hey, this is mentioned in the last chapter of this blog post (before the conclusion). You can create your own custom timer by implementing it via Custom HTML tag. And you can fire that tag after the custom event occurred.
Worked by your guide - Thanks!
Only comment is to emphasis creating the Tag. Missed it in first read.
Again thanks!
Is it possible to have >120s timer trigger across multiple pages? I mean if user lands on homepage, spends 20s goes to another page and then spends 100s on another page and only then trigger fires. And only once per that session.
Not out of the box. This would require custom JavaScript development and storing time in a cookie.
Thank you for getting back to me. And how much time do you think such development would take?
You should ask a developer who is going to do this.
Hi Julius, thank you for the article.
Do I understand correctly that I can delay third-party loading scripts such as Facebook Pixel, HotJar, etc., on the desired interval with this approach?
Thank you in advance.
You could use timer for that, yet
I am trying to delay Zopim chatbot(custom HTML) by 5 seconds after windows load as it is impacting the website load time. Any help or help articles to refer please.
I've been searching for a way to measure the load time of a page in a SPA app. I'm looking to replicate the following stopTimer code from a GA-UA implementation;
self.$nuxt.$ga.time({
timingCategory: category,
timingVar: variable,
timingValue: nowTime - startTime,
timingLabel: label,
location: window.location.href
});
In this case we've recorded the start time of an event in our app, then we call this GA function with the elapsed time.
How can I achieve this in GTM.
NOTE: I see the example of something similar but it seems overly complex for this use case.