GTM Server-Side hosting: Cloud Run, AWS, Azure, and managed options compared

Your GTM Server-Side container is configured. Tags fire, events flow, and the preview server shows green checkmarks. The next question is practical: where should this thing actually run in production?

If you followed Google’s automatic provisioning, your container landed on Cloud Run in US Central (Iowa). That works for testing. For production, you need to think about region, reliability, cost, and whether Google Cloud is even the right platform for your organization.

This guide walks through the four main hosting paths: optimizing Cloud Run, deploying on AWS, deploying on Azure, and using a managed provider. Each has clear tradeoffs that depend on your infrastructure, traffic volume, and how much ops work you want to own.

Cloud Run: the default choice, optimized for production

Cloud Run runs the official Google tagging server Docker image (gcr.io/cloud-tagging-10302018/gtm-cloud-image:stable) as a fully managed serverless container. It handles scaling, networking, and SSL automatically.

For most organizations already on GCP, it’s the right starting point. The integration with GTM is native, documentation is extensive, and the operational overhead is minimal compared to self-managing containers.

Production configuration that matters

The automatic provisioning creates your services with default settings that aren’t production-ready. Three changes are needed:

CPU always allocated. By default, Cloud Run throttles CPU between requests. For a tagging server that needs to parse incoming hits and compile outgoing requests quickly, this causes inconsistent latency and occasional timeouts. Set --no-cpu-throttling to keep the CPU warm.

Minimum 2 instances. Cold starts on a tagging server mean lost data. If an instance needs to spin up from zero while a user’s page view event is waiting, that request can timeout before the container is ready. Two always-on instances eliminate this risk and give you basic redundancy.

Disable detailed Cloud Logging. This is the cost trap that catches everyone. Cloud Run logs every incoming request by default at $0.50 per GiB ingested. For a medium-traffic site, that’s $100-$220/month in logging alone, sometimes exceeding your compute costs. Disable request-level logging and rely on error logging and your own monitoring instead.

Google estimates that each instance handles roughly 20 requests per second for typical GA4 setups. With 2-10 instances, that covers 35-350 requests per second. A reasonable starting point for a medium site is 2 minimum, 5-6 maximum instances.

Custom domains: two approaches with different tradeoffs

Direct Cloud Run domain mapping works well for single-region deployments. You create a CNAME record, Google provisions an SSL certificate (allow up to 24 hours), and you’re running. Simple, no extra cost.

An External Application Load Balancer is the better choice if you need multi-region deployment, DDoS protection via Cloud Armor, or a global anycast IP. The load balancer adds roughly $18/month minimum plus per-GB processing charges, but it unlocks enterprise-grade reliability features.

For multi-region, deploy Cloud Run services in each target region (e.g., europe-west1 and us-east1), create a Serverless Network Endpoint Group per region, and add them to a single global backend service behind the load balancer. Users automatically route to the nearest region.

What it actually costs

Traffic levelDaily requestsInstances (min/max)Monthly cost
Free/Test<1K0 / 1$0 (free tier)
Small10K-100K1-2 / 3$45-$135
Medium100K-1M2 / 5-6$90-$270
Large1M-10M3 / 10+$135-$450+

These are compute costs only. Add Cloud Logging (if you haven’t disabled it), network egress ($0.12/GB), and the load balancer ($18+/month) to get your real number. Real-world data from Measurelab shows £30/month for a 7K events/month site and about £402/month (~$500) for a site processing 200M events/month.

AWS: more control, more moving parts

If your organization runs on AWS and doesn’t want to maintain a separate GCP account just for GTM, AWS is a viable alternative. The case for server-side tracking doesn’t change based on your cloud provider. The same Docker image deploys on AWS container services. But the infrastructure setup is meaningfully more complex.

ECS Fargate is the primary option

AWS ECS Fargate runs the tagging server image as managed containers without you managing EC2 instances. The architecture requires several components that Cloud Run handles automatically:

  • A VPC with public and private subnets
  • An Application Load Balancer for HTTPS termination
  • NAT Gateway(s) for outbound internet access
  • Route 53 for DNS management

Lari Haataja published an open-source AWS CDK project that automates this entire infrastructure stack, which saves considerable setup time.

The raw compute is cheaper than Cloud Run. An equivalent Fargate task (1 vCPU, 0.5 GB, always-on) costs about $31/month versus Cloud Run’s ~$49. But infrastructure overhead erodes that advantage quickly:

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

For small deployments, total AWS costs often exceed Cloud Run despite the cheaper compute. AWS’s own Guidance page estimates roughly $1,180.70/month for processing 1M records/day, though that includes more generous infrastructure provisioning.

Where AWS wins: granular networking control, ARM/Graviton2 support (20% cheaper than x86), and Savings Plans offering up to 52% discount on 3-year commitments. For organizations processing high volumes on existing AWS infrastructure, the economics flip in AWS’s favor at scale.

App Runner: simpler but pricier

AWS App Runner is the closest equivalent to Cloud Run. It’s fully managed with auto-scaling and HTTPS by default. You point it at the Docker image and it runs. But App Runner costs 1.5-2x more than Fargate for continuous workloads. For a tagging server that needs to be always-on, that premium adds up.

Lambda doesn’t work

The GTM tagging server image runs a persistent Node.js HTTP server. Lambda’s function model, designed for short-lived invocations, is architecturally incompatible. Don’t try to make it work.

Azure: the smoothest non-Google setup

If you’re already in the Azure ecosystem, you have two good options. Simo Ahava, the most recognized voice in the GTM community, called Azure App Service’s setup “the smoothest and the fastest” among the three major cloud providers.

App Service

Two App Service instances (one for the tagging server, one for preview) deploy with Docker container configuration using the same environment variables as Cloud Run. Azure managed SSL certificates work with CNAME-mapped subdomains, though apex domain SSL requires additional configuration.

Pricing varies by tier:

TierMonthly costBest for
B1 (Basic)~$13Testing/development
S1 (Standard)~$69Production
P1V3 (Premium)~$124Auto-scaling workloads

The production-grade S1 tier at ~$69/month for a single instance is competitive with Cloud Run, and the setup process is genuinely simpler if Azure is already your cloud platform.

Container Apps

Azure Container Apps offers a Cloud Run-like experience with consumption-based pricing and auto-scaling based on HTTP traffic. If you prefer the serverless container model over managing App Service plans, Container Apps is the better fit.

Functions doesn’t work

Same reason as Lambda: Azure Functions is designed for event-driven, short-lived workloads. The persistent HTTP server in the GTM image isn’t compatible.

Managed hosting: trading control for simplicity

Managed providers host the GTM Server-Side infrastructure for you. You give up infrastructure control and gain setup speed, monitoring, and compliance certifications you’d otherwise need to manage yourself.

Stape.io

Stape leads the managed hosting market and is often cheaper than self-hosted Cloud Run. Their pricing model counts only incoming requests, not the outgoing forwards to GA4, Meta, and other vendors. For a typical setup that forwards each hit to 3-4 endpoints, that’s a significant difference.

PlanMonthly costRequests included
Free$010K
Pro$20500K
Business$40+2M+
EnterpriseCustomCustom

Beyond hosting, Stape includes features you’d need to build or buy separately:

  • Cookie Keeper: Extends cookie lifetimes against Safari ITP restrictions to 90 days or 13 months
  • Custom Loader: Renames the GTM script to resist ad blocker detection
  • Global CDN: Multi-region routing included, no load balancer configuration needed
  • Monitoring dashboard: Request volume, error rates, and tag performance
  • Certifications: SOC2, HIPAA, and ISO 27001 compliance

For organizations without dedicated DevOps or cloud infrastructure teams, Stape removes the operational burden entirely.

Addingwell

Addingwell, recently acquired by consent management platform Didomi, positions as the premium managed option. Starting at around €90/month, it’s more expensive than Stape but includes a 99.99% uptime SLA, real-time tag health monitoring, and an EU-first data residency approach.

The Didomi acquisition is worth noting for organizations that want their consent management and server-side hosting under one vendor. Whether that integration delivers practical value beyond marketing synergy remains to be seen.

TAGGRS

TAGGRS starts at €19/month with a focus on the European market. ISO 27001 certified with EU data residency, it’s a solid option for EU-based organizations looking for a cost-effective managed provider.

Cloudflare Zaraz

Zaraz takes a fundamentally different approach. Instead of running a separate server container, it processes tracking at Cloudflare’s CDN edge. Your tags execute at the nearest Cloudflare point of presence, not in a centralized container.

It offers near-zero latency impact on page load, free coverage for up to 1 million events monthly, and no infrastructure to manage at all. But Zaraz is not GTM Server-Side. It is Cloudflare’s own tag management system. If you’re committed to the GTM ecosystem and its Community Template Gallery, Zaraz won’t be a direct replacement. But if your primary goal is getting tracking off the main thread and improving page performance, it’s worth evaluating.

Choosing the right option

The decision comes down to three factors: your existing cloud infrastructure, your operational capacity, and your budget.

FactorCloud RunAWS FargateAzure App ServiceStapeAddingwell
Setup complexityMediumHighLow-MediumVery lowLow
Monthly cost (medium)$90-$270$100-$300+$70-$200$20-$100€90+
Infrastructure controlFullFullFullNoneLimited
Multi-regionLoad balancer setupComplexRegion pairsIncludedIncluded
MonitoringBuild yourselfBuild yourselfBuild yourselfIncludedIncluded
GTM integrationNativeManualManualNativeNative

If you’re already on GCP: Cloud Run is the obvious choice. Native GTM integration, extensive documentation, and the simplest path from automatic provisioning to production.

If you’re on AWS with significant existing infrastructure: ECS Fargate makes sense at scale, especially with Savings Plans. For smaller implementations, the infrastructure overhead tips the cost equation toward Cloud Run or a managed provider.

If you’re on Azure: App Service offers the fastest path to production. The setup is genuinely straightforward, and the S1 tier at ~$69/month is competitive.

If you don’t have cloud infrastructure expertise: Start with Stape. The $20/month Pro plan covers most small-to-medium sites, includes features you’d spend weeks building on your own, and lets your team focus on tag configuration rather than container orchestration.

If you need EU data residency and compliance certifications: Both Stape (ISO 27001, SOC2) and TAGGRS (ISO 27001) offer this out of the box. Self-hosting achieves the same result but requires you to manage the IAM and compliance documentation yourself.

The hosting decision isn’t permanent. The GTM Server-Side container image is the same Docker image regardless of where it runs. Migrating from one platform to another means redeploying the same container with the same environment variables and updating your DNS records. Pick the option that fits your current constraints, and know that switching later is a matter of hours, not weeks.