ServicesAboutNotesContact Get in touch →
EN FR
Note

GTM Server-Side Hosting on AWS

How to host the GTM Server-Side tagging container on AWS using ECS Fargate, why App Runner costs more, and why Lambda is architecturally incompatible.

Planted
gtmanalyticscost optimization

Running GTM Server-Side on AWS applies to organizations already invested in AWS that don’t want to maintain a separate GCP account for a tagging container. The Docker image — gcr.io/cloud-tagging-10302018/gtm-cloud-image:stable — deploys on AWS container services without modification.

AWS compute is cheaper than Cloud Run, but AWS requires building infrastructure that Cloud Run includes by default (networking, HTTPS, scaling). For small deployments, total costs often exceed Cloud Run despite lower vCPU rates. For large deployments on existing AWS infrastructure with Savings Plans, the economics can favor AWS.

ECS Fargate: The Primary Option

AWS ECS Fargate runs the tagging server image as managed containers without you managing EC2 instances directly. It’s the closest AWS equivalent to Cloud Run’s serverless container model.

The architectural difference from Cloud Run becomes clear quickly. Where Cloud Run handles networking, HTTPS, and scaling automatically, Fargate requires you to build:

  • A VPC with public and private subnets (the tagging server sits in the private subnet, reachable only through the load balancer)
  • An Application Load Balancer for HTTPS termination and routing traffic to the Fargate tasks
  • NAT Gateway(s) for outbound internet access from the private subnet (the container needs to forward events to GA4, Meta, and other vendor endpoints)
  • Route 53 for DNS management and certificate validation via ACM

None of these are optional. The tagging server needs outbound internet access (NAT Gateway), HTTPS termination (ALB), and DNS (Route 53). You’re not choosing whether to build this infrastructure; you’re choosing how much effort to invest in it.

Lari Haataja published an open-source AWS CDK project that automates this entire stack. If you’re going the Fargate route, using a CDK project rather than building from scratch saves considerable time and reduces the chance of misconfiguration.

Task Configuration

For the tagging server task, a reasonable starting configuration:

{
"family": "gtm-tagging-server",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "1024",
"memory": "512",
"containerDefinitions": [
{
"name": "gtm-tagging-server",
"image": "gcr.io/cloud-tagging-10302018/gtm-cloud-image:stable",
"portMappings": [
{
"containerPort": 8080,
"protocol": "tcp"
}
],
"environment": [
{
"name": "CONTAINER_CONFIG",
"value": "YOUR_GTM_CONTAINER_CONFIG_STRING"
},
{
"name": "PREVIEW_SERVER_URL",
"value": "https://preview.gtm.yourdomain.com"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/gtm-tagging-server",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "ecs"
}
}
}
]
}

The CONTAINER_CONFIG value comes from GTM — it’s the base64-encoded string that identifies your server container. The same string you’d use in the Cloud Run deployment.

Real Cost Profile

Fargate compute pricing is genuinely cheaper than Cloud Run. An always-on task with 1 vCPU and 0.5 GB runs at approximately $31/month. Cloud Run’s equivalent costs around $49/month.

But the surrounding infrastructure erodes that advantage fast:

ComponentMonthly cost
Fargate task (1 vCPU, 0.5 GB, always-on)~$31
Application Load Balancer~$16
NAT Gateway (per gateway)~$32 + data transfer charges
Minimum realistic total~$79+

The NAT Gateway is the surprise cost. At ~$32/month per gateway plus $0.045/GB data processed, it often exceeds the compute cost for small deployments. A tagging server forwarding events to 3-4 vendor endpoints generates meaningful outbound data.

For comparison, Cloud Run at the same configuration costs $49-90/month total — no ALB, no NAT Gateway, HTTPS and scaling included.

Where AWS Wins

The economics flip in AWS’s favor at two points:

Existing infrastructure reuse. If you already have a VPC, ALB, and NAT Gateways running for other workloads, adding a Fargate service to the existing infrastructure incurs only compute costs. The $79+ floor only applies if you’re building dedicated infrastructure.

Graviton2/ARM tasks. Fargate supports ARM64 containers (building the GTM image for ARM requires a multi-stage build or cross-compilation). ARM Graviton2 Fargate tasks are approximately 20% cheaper than x86 at equivalent resource allocation.

Savings Plans. AWS Compute Savings Plans offer up to 52% discount over on-demand pricing on 1 or 3-year commitments. For organizations with significant existing AWS commitments, a tagging server fits into existing Savings Plans coverage. Cloud Run’s committed use discounts exist but are typically less aggressive.

For high-traffic sites processing tens of millions of events per month, the Savings Plan discount on Fargate compute can meaningfully undercut Cloud Run’s pricing — especially if ARM tasks are viable.

App Runner: Simpler but More Expensive

AWS App Runner is the closest AWS equivalent to Cloud Run’s developer experience. It’s fully managed, auto-scaling, with HTTPS by default. You point it at the Docker image and it runs. No VPC configuration, no ALB, no NAT Gateway.

The catch: App Runner costs approximately 1.5-2x more than Fargate for continuous workloads. For a tagging server that needs to be always-on (to avoid lost events from cold starts), that premium adds up.

App Runner makes sense for teams that want a quick evaluation without infrastructure investment. For production deployments where cost matters, Fargate with existing infrastructure is more economical.

Lambda Doesn’t Work

Lambda is a common first instinct for “running something serverless on AWS.” For the GTM tagging server, it won’t work.

The GTM tagging server image runs a persistent Node.js HTTP server that binds to a port and listens for connections. Lambda’s execution model is designed for short-lived function invocations — a request comes in, the function executes, it terminates. Lambda does not support long-running HTTP servers.

There are workarounds like Lambda Web Adapter or custom runtimes that shim HTTP servers into Lambda’s invocation model, but they introduce reliability and performance problems for a workload that needs consistent low latency. Don’t pursue this path.

If you need serverless execution on AWS without the Fargate infrastructure overhead, App Runner is the correct choice.

Multi-Region on AWS

Multi-region GTM Server-Side on AWS requires significantly more infrastructure than on GCP. The typical pattern:

  1. Deploy Fargate services in each target region (e.g., us-east-1 and eu-west-1)
  2. Create ALBs in each region
  3. Use AWS Global Accelerator or Route 53 latency-based routing to direct users to the nearest region
  4. If using Global Accelerator, configure endpoint groups pointing to each regional ALB

Each regional stack requires its own VPC, ALB, NAT Gateway, and Fargate service. The infrastructure cost compounds per region.

For multi-region deployments without existing multi-region AWS infrastructure, Cloud Run behind a Global External Application Load Balancer or a managed provider like Stape is almost always more cost-effective.

The Decision Point

Choose AWS hosting when:

  • Your organization runs primarily on AWS and political or contractual reasons prevent maintaining a separate GCP account
  • You’re processing high enough volume that Savings Plan discounts make Fargate cheaper than Cloud Run
  • You already have VPC, ALB, and NAT Gateway infrastructure for other workloads

Accept Cloud Run or a managed provider when:

  • You’re starting fresh without existing AWS infrastructure
  • Your traffic volume doesn’t justify Savings Plans
  • You want multi-region without building multi-region AWS infrastructure

The GTM tagging server image is cloud-agnostic. Migrating between hosting platforms means redeploying the same container with the same environment variables and updating DNS. The decision isn’t permanent.