AWS Server-Side GTM Setup Guide for First-Party Tracking
Setting up server-side Google Tag Manager (sGTM) on Amazon Web Services (AWS) allows enterprise organizations to bypass third-party cookie restrictions, improve page load speeds, and maintain absolute control over user data. By running the official sGTM Docker image on AWS Elastic Beanstalk or Elastic Container Service (ECS), you establish a dedicated, first-party tracking endpoint under your own corporate domain. This cloud-based architecture shifts the heavy lifting of processing marketing tags from the user's browser to your secure cloud infrastructure, shielding your data pipeline from ad blockers and browser privacy protections.
Key Takeaways
- First-Party Cookie Ownership: Routing tracking requests through a custom subdomain (e.g.,
metrics.yourdomain.com) on AWS extends cookie lifespans up to two years, bypassing Safari's Intelligent Tracking Prevention (ITP) limits. - Production-Ready Sizing: A highly available production setup requires a minimum of two
t3.mediuminstances behind an Application Load Balancer (ALB) to handle traffic spikes and ensure 99.9% uptime. - Predictable Cloud Costs: Running sGTM on AWS Elastic Beanstalk typically costs between $120 and $300 per month, offering a highly customizable alternative to Google Cloud Platform's default App Engine setup.
- Strict Data Governance: Deploying sGTM inside your own Virtual Private Cloud (VPC) allows you to filter and redact personally identifiable information (PII) before it is sent to third-party ad networks.
Why Choose AWS for Server-Side GTM?
While Google Cloud Platform (GCP) provides a one-click deployment path for sGTM, enterprise IT security policies and existing infrastructure commitments frequently mandate AWS. Deploying sGTM on AWS keeps your tracking pipeline under the same governance, billing, and security controls as your core application services.
Furthermore, AWS offers granular control over networking and scaling. By utilizing Elastic Beanstalk or ECS Fargate, you can configure precise autoscaling thresholds based on CPU utilization or request count, preventing the runaway costs that can occur with GCP App Engine's default scaling configurations. It also allows you to integrate your tracking data directly with AWS-native data warehouses and analytics pipelines, such as Amazon Redshift or Athena.
Architecture Overview
A resilient, production-grade sGTM deployment on AWS relies on four core components:
- Route 53 (DNS): Directs traffic from your custom subdomain (e.g.,
collect.example.com) to your load balancer. - Application Load Balancer (ALB): Terminates SSL certificates, handles HTTPS handshakes, and distributes incoming requests across healthy container instances.
- AWS Elastic Beanstalk (Docker Platform): Manages the underlying EC2 instances, auto-scaling groups, and deploys the official Google sGTM container image.
- AWS Certificate Manager (ACM): Provisions and automatically renews the SSL/TLS certificate for your custom subdomain.
Step 1: Create the Server-Side GTM Container
Before launching AWS resources, you must set up your container in Google Tag Manager:
- Navigate to your Google Tag Manager Account and click Create Container.
- Select Server as the target platform and click Create.
- In the provisioning dialog, choose Manually provision tagging server.
- Copy the long Container Config string. This is a Base64-encoded string containing your container credentials, which you will inject as an environment variable in AWS. Keep this string secure.
Step 2: Prepare the AWS Deployment Manifest
AWS Elastic Beanstalk uses a configuration file named Dockerrun.aws.json to determine which Docker image to pull and how to map ports. Create a file named Dockerrun.aws.json on your local machine and paste the following code:
{
"AWSEBDockerrunVersion": "1",
"Image": {
"Name": "gcr.io/cloud-tagging-103020/gtm-cloud-image:stable",
"Update": "true"
},
"Ports": [
{
"ContainerPort": "8080"
}
]
}
This manifest instructs Elastic Beanstalk to pull the official, stable Google GTM cloud tagging image and expose port 8080, which is the default port the sGTM container uses to listen for incoming tracking events.
Step 3: Deploy to AWS Elastic Beanstalk
With your manifest file ready, proceed to the AWS Management Console to deploy your environment:
- Open the Elastic Beanstalk console and click Create Application.
- Enter an application name (e.g.,
sgtm-production). - Under Platform, select Docker. Leave the platform branch on the default recommended version.
- Under Application code, select Upload your code, choose Local file, and upload the
Dockerrun.aws.jsonfile you created in Step 2. - Click Configure more options to customize your environment for production. Do not use the "Single instance" default for live tracking.
Configuring Environment Variables
In the Elastic Beanstalk configuration screen, navigate to the Software category and add the following environment properties:
CONTAINER_CONFIG: Paste the Base64-encoded container configuration string you copied from GTM in Step 1.PORT: Set this to8080.RUNNING_IN_AWS: Set this totrue.
Configuring High Availability and Scaling
To prevent tracking gaps during traffic surges, configure the environment for high availability:
- Under the Capacity configuration card, change the Environment Type from "Single instance" to Load balanced.
- Set the minimum instance count to 2 and the maximum to 4 or more, depending on your average monthly traffic.
- Select t3.medium or t3.small instances. Avoid
t3.nanoort3.microfor production workloads, as these instances can easily run out of memory during intense traffic spikes, leading to dropped tracking events. - Under Scaling triggers, set the trigger metric to CPUUtilization, with a scale-up threshold of 70% and a scale-down threshold of 30%.
Step 4: Configure Load Balancing and SSL
Server-side tracking endpoints must operate over HTTPS. Browsers will block unencrypted HTTP tracking requests, and modern browsers require secure connections to set first-party cookies.
- Go to the AWS Certificate Manager (ACM) console.
- Request a public certificate for your tracking subdomain (e.g.,
metrics.yourdomain.com). - Validate ownership of the domain using DNS validation by adding the generated CNAME record to your DNS provider (such as Route 53 or Cloudflare).
- Return to your Elastic Beanstalk configuration and edit the Load Balancer settings.
- Add a listener on port 443 (HTTPS). Select the SSL certificate you just provisioned in ACM.
- Ensure the listener routes traffic to the default process on port 80 (which maps to the container's port
8080). - Save your changes and click Create Environment. AWS will take 5 to 10 minutes to provision the EC2 instances, Application Load Balancer, and security groups.
Step 5: Configure Custom DNS Routing
Once Elastic Beanstalk has successfully deployed, copy the URL of your Application Load Balancer (e.g., awseb-e-m-awsebloa-xxxxxxxx.us-east-1.elb.amazonaws.com).
- Open your DNS hosting provider (e.g., Route 53).
- Create a new record for your subdomain (e.g.,
metrics.yourdomain.com). - Choose record type CNAME. If using Route 53, you can use an A Record with an Alias pointing directly to your Elastic Beanstalk environment.
- Paste your ALB DNS name as the target/value. Set the TTL to 300 seconds.
Step 6: Verify and Connect to downstream APIs
With DNS resolved, test your endpoint by navigating to https://metrics.yourdomain.com/healthy in your browser. If your configuration is correct, the page will display a simple ok response. If you see a timeout or an SSL error, double-check your ACM validation status and ALB listener paths.
Now, update your web-based Google Tag Manager container to route GA4 requests through your new AWS tagging server. In your web GTM container, edit your Google Tag (GA4 Configuration tag) and check the option to "Send to server container." Input your custom URL: https://metrics.yourdomain.com.
When running GA4 through your new server-side environment, you may run into initial debugging issues where UTM campaign parameters fail to populate correctly in your reporting. To resolve this, consult our detailed troubleshooting guide on how to fix utm_source=undefined in GA4 and Server-Side GTM.
With server-side GTM fully operational on AWS, you can now activate server-to-server tracking APIs like the Meta Conversions API. When configuring these pipelines, remember that sending duplicate browser and server events will corrupt your attribution data unless you implement proper deduplication. You can learn how to handle this by reading our walkthrough on Server-Side GTM Setup for Meta CAPI and Deduplication.
Additionally, you must ensure that your server-side setup respects global privacy regulations. Deploying a server-side endpoint does not bypass the legal requirement to collect user consent. You must configure your sGTM tags to read consent signals from the browser; learn more about managing this by reviewing our guide to fixing Consent Mode v2 signal missing in Google Ads & GA4.
Frequently Asked Questions
How much does it cost to run server-side GTM on AWS?
A production setup with two t3.medium instances and an Application Load Balancer generally costs between $120 and $200 per month. This cost scales based on data egress and regional bandwidth fees if you process tens of millions of events monthly.
Why does my AWS sGTM endpoint return a 400 Bad Request error?
A 400 Bad Request error typically indicates that your sGTM container has received a request that does not match any active client configurations. Ensure your web-based GTM container is correctly sending valid GA4 payloads to your subdomain, and verify that your sGTM container is fully published.
Can I use ECS Fargate instead of Elastic Beanstalk?
Yes, you can run the same gcr.io/cloud-tagging-103020/gtm-cloud-image:stable Docker image on AWS ECS Fargate. Fargate is highly scalable and removes the need to manage EC2 instances directly, making it an excellent choice for teams with dedicated DevOps resources.
How do I test my AWS server-side GTM setup in real time?
Open your server-side GTM container and click "Preview". In the debug console, verify that incoming requests are visible when you navigate your website. Ensure your browser's console shows outgoing GA4 network requests hitting your custom subdomain instead of Google's default endpoints.