Running Server Side GTM in Production: 5 Problems to Review and Fix

Quick Read

Running a server-side Google Tag Manager container is just the start. Challenges are waiting ahead.

It is easy to overlook the following configurations: a current server image, reliable event deduplication, consent rules that are read and acknowledged across the entire tag setup, enough Cloud Run capacity for real traffic, and a controlled way to test and reverse changes.

This article explains what changed, why these failures appear, and what to check before your next campaign discovers the problem for you.

How server-side tagging became a production system

For many years, website measurement was mostly a browser operation.

A visitor loaded a page. GTM JavaScript tags sent data directly to Google Analytics. The Tag System sends data to Google Ads, Meta, LinkedIn, and other platforms. That worked reasonably well until websites collected more vendors, more consent categories, more conversion events, and more pressure to control what data left the page.

The browser controlled several important settings. An ad blocker installed on the browser could restrict storage, block scripts, interrupt requests, or close the page before an event finishes sending.

The server-side tagging changed the way data flowed from the website to GTM to third-party applications. The website can now send events to a client GTM container, where the client pushes the data to the server GTM. The server GTM applies rules and sends approved information to selected destinations.

While this provides more control over data processing, it does not create automatic accuracy.

Server-side tagging does not repair a poorly designed purchase event, make every community template consent-aware, or guarantee sufficient Cloud Run capacity for a traffic spike. Once the setup includes Cloud Run services, transformations, vendor APIs, scaling rules, and deployment revisions, it should be treated as a small production application. It is a good time to deep dive into the pitfalls that you should be aware of as a server-side GTM implementer. While there is a never-ending list of issues that may arise in the tagging environment, the top five are discussed below.

Failure 1: The tagging server image was never updated

Google regularly updates the software that runs your server-side GTM container. This software is packaged in a Docker image.

A Docker image is basically a ready-made software package. It contains the tagging server application, the Node.js runtime it needs, and other supporting files required to run it. When you deploy server-side GTM on Cloud Run, Google uses this image to create the instances that receive and process your tracking requests.

You can think of the Docker image as the installed version of the tagging server. Updating tags inside GTM does not automatically update this underlying server software. These are two separate things.

Google releases new image versions to fix security issues, update supporting software, improve compatibility, and occasionally make larger technical changes. If the image hasn't been updated for a long time, the server may continue to run but miss important fixes, eventually becoming harder to maintain.

For example, as of April 28, 2026, the latest image listed in Google’s release notes is version 4.3.0. An earlier major release, version 4.0.0, moved the tagging server to Node.js 24 and changed the base image used to build the server.

Node.js is the software environment that allows the tagging server application to run. The base image is the lower-level package that provides the operating system files and other essentials beneath Node.js. Most marketers do not need to work with either of these directly. The important point is that a major runtime change can affect server behavior, so image updates should be tested before being applied to live traffic.

Updating the Docker image is therefore closer to updating the operating software of the tagging server than publishing a new GTM container version. It should be handled carefully.

A useful test set usually includes a page view, a lead, a purchase, a consent-denied event, and any event that sends customer information or a conversion value. Confirm that the expected client claims each request, transformations run correctly, and destination tags receive the intended fields.

When something breaks, “we deployed whatever was latest” is not a particularly useful incident note.

Failure 2: Deduplication Failure: Meta counts the browser and server events separately

Many businesses send the same conversion to Meta through two routes.

The browser sends a Meta Pixel event. The server sends a corresponding Conversions API event. Both messages describe the same purchase, but Meta needs a way to recognize that they belong together.

Meta compares two values:

  • the event name,
  • the event identifier.

The event name and identifier must match across the browser and server versions of the event.

There is one small naming complication. Meta uses a different parameter name on each route.

In the browser Pixel call, the parameter is written as eventID:

fbq(

  "track",

  "Purchase",

  {

    value: 99.00,

    currency: "USD"

  },

  {

    eventID: "purchase_12345"

  }

);

In the Conversions API payload, the corresponding field is written as event_id:

{

  event_name: "Purchase",

  event_id: "purchase_12345"

}

The names are different, but the value must be identical.

In a Google Tag Manager setup, the value is transported from the web container to the server container using an event parameter called event_id.

The complete flow may therefore look like this:

Data layer or GA4 parameter: event_id = purchase_12345

Meta Pixel field:            eventID = purchase_12345

Meta CAPI field:             event_id = purchase_12345

How can you generate these IDs?

Option 1: Use the order ID for purchases

For a purchase event, the order or transaction ID is unique to each purchase, making it suitable as a unique event ID.

window.dataLayer = window.dataLayer || [];

window.dataLayer.push({

  event: "purchase",

  event_id: "purchase_12345",

  ecommerce: {

    transaction_id: "12345",

    value: 99.00,

    currency: "USD"

  }

});

The web Meta tag reads the value of event_id and sends it to the Pixel as eventID.

The GA4 or transport tag also sends event_id to the server container. The server Meta tag then maps that value to the Conversions API field called event_id.

This is usually the clearest approach for purchases because the identifier is tied to a real business record.

Option 2: Generate the ID on the website or application

For events without an order number, the website or application can generate an identifier when the event occurs.

The important part is that the ID is created once and pushed into the data layer with the event. All tags triggered by that data layer event should read the stored value.

For example:

window.dataLayer = window.dataLayer || [];

window.dataLayer.push({

  event: "generate_lead",

  event_id: crypto.randomUUID()

});

The browser Meta tag and the tag sending the event to the server must both read the same event_id value from that data layer event.

The ID should not be generated separately inside each tag. If one tag creates abc123, and the other creates xyz789.Meta will see two unrelated events.

Option 3: Use a GTM community variable

Google Tag Manager’s Community Template Gallery includes third-party variables that can generate event identifiers.

One example is the Unique Event ID variable created by Stape. It combines browser, page load, and GTM event information to create an identifier for the current GTM event.

After adding the variable template, you can create a variable such as:

{{Unique Event ID}}

Use that same variable in:

  • the Event ID field of the browser Meta tag,
  • The event_id parameter is sent to the server container via GA4 or the transport tag.

Both tags must fire from the same GTM event. If they fire from different data layer events, the variable may produce different identifiers, and Meta will not deduplicate them.

Community variables are convenient, but they are not built into Google Tag Manager variables. Review the permissions it requires to run and whether it is maintained regularly before adding it to a production container.

Avoid using the Random Number variable directly.

A standard Random Number variable may return a new value each time GTM evaluates it.

That means the browser Meta tag could receive one number while the tag sending data to the server receives another. Both numbers may be unique, but they are not useful because they do not match.

The event ID should be generated once for one event, stored, and reused.

During testing, inspect both routes separately. Confirm that:

  • The browser event uses eventID,
  • The server event uses event_id,
  • Both contain the same value,
  • The event names also match.

This check applies only to events that are deliberately sent through both the browser and the server. Server-only and offline events do not have a browser copy and should not be expected to show browser-server deduplication.

Failure 4: Cloud Run capacity was copied from the test setup

Cloud Run can scale the tagging service as traffic changes, but the starting configuration still matters.

Google’s dedicated Cloud Run setup guide recommends at least two instances to reduce the risk of data loss during an outage. In the documented configuration, each instance uses 1 vCPU and 0.5 GB of memory, and Google estimates about $45 per month for each instance. The guide says that autoscaling from 2 to 10 instances can handle roughly 35 to 350 requests per second, depending on the tags being run.

For a low traffic but business-critical deployment, two is a sensible starting point when the additional cost is acceptable. Two remains an officially documented minimum. Neither number is a capacity plan for a large launch.

There are several factors that govern the capacity. Request volumes may matter, tag execution time, and concurrency may have a role.

Before expected traffic spikes, Google recommends increasing minimum instances toward forecast usage, ideally toward the peak, reviewing maximum instance limits, checking quotas, and updating to the latest server image before the event.

Use Cloud Run reports to review request count, HTTP response categories, instance count, and CPU utilization.

Google’s monitoring guidance notes that sustained CPU usage near or above the scaling target can indicate that the minimum instance count is too low.

The consensus seems to go towards using two as the documented minimum, three as the safer production baseline. Of course, a periodic monitoring is necessary to confirm the choice.

The test environment that is enabled by default when you start a cloud run should be switched to production and recommended servers once the server-side implementation is made live.

Failure 5: Nobody can clearly explain what changed in production

A server side GTM setup can change in several places.

Someone may update the tagging server software in Cloud Run. Another person may change a tag or template inside GTM. Someone else may adjust the number of Cloud Run instances available to handle traffic.

Each change may be reasonable on its own. The problem begins when these changes are made without a clear record.

A few months later, the setup may still be working, but the team may not know which server image is running, which GTM version is live, why a scaling setting was changed, or how to return to the previous working setup.

This makes even a small problem difficult to investigate.

Keep a record of infrastructure changes

The settings used to run the tagging server should be stored in version control, such as Git.

This includes the server image version, Cloud Run scaling settings, and other configuration values that are safe to store. Passwords, API keys, and other secrets should be kept in a secure secret management system instead.

GTM changes need a record as well. Every published server container version should have a clear name and description. The notes should explain what changed, why it changed, who tested it, and who approved it for publication.

This gives the team a timeline of the production setup rather than a collection of changes that depend on someone’s memory.

Test a new version before sending all traffic to it

Cloud Run allows you to create a new revision of the tagging service. A revision is simply a new version of the service with its own server image and configuration.

The new revision can be deployed without immediately sending all live traffic to it. This gives the team an opportunity to test it first.

The test should use several important events, such as a page view, lead, purchase, and consent denied event. The team should confirm that the server container receives the request, understands the event correctly, applies the expected transformations, and sends the correct information to each vendor.

A successful server response is not enough on its own.

The server may return a successful response even when a Meta or Google Ads request is rejected later. A consent condition may prevent a tag from firing. The wrong server client may process the incoming request. An important parameter may also be removed before the event reaches its destination.

The complete journey needs to be checked, not only the initial server response.

Keep the previous working version available

Cloud Run keeps earlier revisions of the service. If a new revision creates a problem, traffic can be moved back to the previous working version.

This is called a rollback.

A rollback should not happen automatically every time event volume falls. A reduction in events may be caused by the website, the web GTM container, the consent platform, a DNS problem, or even a campaign that has ended.

The team should first identify whether the problem began with the new server revision. If it did, a temporary rollback can be initiated.

The overall process does not need to be complicated. Every production change should have a clear owner, a written record, a test, a version number, and a practical way to return to the previous working setup.

Monitor the route, not only the server.

Cloud Run can show request volume, response codes, instance count, CPU utilization, and logs. It is not meant for analytics or measurement data.

A vendor API can reject an outgoing event while the tagging endpoint returns a successful response. A transformation can remove a required field. A consent condition can prevent a tag from firing. A browser change can reduce incoming traffic without producing a server error.

Monitoring should answer three questions:

  • Did the event reach the server?
  • Did the server process it as intended?
  • Did the destination accept it?

Next steps

Begin with a real purchase or an important event from your production setup and follow it from start to finish. Check what enters the data layer, how the server container processes it. Also, what data finally reaches Meta, Google Ads, or any other destination. Pay particular attention to the event identifier. The browser and server versions of the same conversion must carry the same value.

Run the same test again after rejecting marketing consent. This time, look at which tags remain inactive and what information is still passed to the tags that are allowed to run. This is often where an implementation that looked correct in the browser starts showing gaps on the server side.

After that, check the version of the tagging server image currently running in Cloud Run and compare it with Google’s latest release notes. Review the minimum and maximum instance settings at the same time. A production service running on one instance needs attention. Google’s documentation refers to two instances as the Cloud Run minimum and three as the broader production recommendation, but the final number should reflect your actual traffic and expected campaign peaks.