If you have worked with Google Tag Manager for more than a week, you have typed dataLayer.push(). But what actually happens after you hit enter? In this post we open the hood and look at the message queue, the internal data model and the moment triggers get evaluated.
What the dataLayer really is
The dataLayer is a plain JavaScript array that GTM turns into a message bus. Every object you push becomes a message; GTM processes messages one by one, first in, first out.
// always initialise before the GTM snippet
window.dataLayer = window.dataLayer || [];
dataLayer.push({
event: 'add_to_cart',
ecommerce: {
currency: 'USD',
value: 95.00,
items: [{ item_id: 'gtm-beginners', quantity: 1 }]
}
});
What happens on push()
GTM overrides the array’s native push method. When a message arrives, three things happen in strict order:
- The message is merged into GTM’s internal data model.
- If the message has an
eventkey, all triggers are evaluated. - Tags attached to matching triggers fire, respecting priority and sequencing.
Note. A push without an event key updates the data model but fires nothing. The values simply wait for the next event.
Why order matters
Because messages are processed sequentially, a variable only has the value you expect if the push that sets it happened before the event that reads it. This is the root cause of most “my purchase tag has no value” tickets.
Three silent mistakes
1. Re-declaring the array
Writing dataLayer = [] after GTM has loaded replaces the instrumented array with a dumb one. Nothing breaks visibly — events just stop arriving.
2. Pushing strings instead of objects
GTM ignores anything that is not an object or a function. No error, no warning.
3. Forgetting to clear ecommerce
Nested objects are merged recursively, so stale items can leak into the next event.
Download the test container
dataLayer debugging container
Enter your email and I'll send you the download link. You'll also get new tutorials — one email per week, max.
GTM-datalayer-debug.json · 187 B
Summary
The dataLayer is a queue, not a bag of variables. Push objects, include an event when you want something to fire, and mind the order.