Blog
A misbehaving page can fire the same event 50 times. A small quota in your container catches the runaway loops.
Most sites have at least one bug somewhere in their JavaScript that occasionally fires an event in a loop. Maybe a click handler attached twice. Maybe a useEffect that retriggers. The result: a single user session sends the same event 20, 50, or 200 times. A simple quota in your sGTM catches these without changing anything else.
For each event type you want to limit, increment a counter in a session cookie. If the counter exceeds the threshold, drop the event.
const cookieName = '_event_count_purchase';
const current = parseInt(getCookieValues(cookieName)[0] || '0');
if (current >= 5) {
log('Purchase event quota exceeded for session, dropping');
return false;
}
setCookie(cookieName, String(current + 1), {
domain: 'auto',
path: '/',
'max-age': 1800
});
return true;
Use as an exception trigger on the relevant tag. The tag fires only if the variable returns true.
| Event type | Per session |
|---|---|
| page_view | 100 (real users with deep navigation) |
| view_item | 50 |
| add_to_cart | 10 |
| purchase | 5 (legitimate cases: subscription renewal modals, multi-step checkouts) |
| form_submit | 10 |
Before applying a quota, query your warehouse for the 99th percentile of events-per-session per event name. Set the quota slightly above that. The point is to catch runaway loops, not to limit power users.
When an event is dropped due to the quota, log it (with the user_id or session_id) so you can investigate. A spike in quota-drop logs is an early warning that someone shipped a bug. The pattern fits well with the broader tag audit habit.
Engagement events (scroll, time spent, video play) where 50 fires per session is normal for legitimate use. Quotas on these will cap real engagement and skew your reports. Reserve quotas for transactional events where the upper bound is known.