AWS vs Google Cloud vs Azure compute: choosing VMs, containers, and serverless
Compare EC2, Compute Engine, Azure VMs, ECS on Fargate, Cloud Run, Container Apps, EKS, GKE, and AKS by control, startup latency, scaling, database connections, and cost. Use an order API to decide which responsibilities to delegate and what to test.
Start with the order API and the work you want to delegate
An order API already runs in a container and receives more traffic during the day than at night. It is stateless and stores orders in an external PostgreSQL database. If the team wants less OS and cluster maintenance, managed container execution is a useful starting point. Requirements for a custom Kubernetes Operator or guest OS changes move the comparison to another level.
Map VMs, Kubernetes, and managed containers before comparing
| Required control | AWS | Google Cloud | Azure |
|---|---|---|---|
| VM with guest OS administration | Amazon EC2 | Compute Engine | Azure Virtual Machines |
| Kubernetes APIs and resources | Amazon EKS | Google Kubernetes Engine (GKE) | Azure Kubernetes Service (AKS) |
| Container execution without node administration | Amazon ECS on AWS Fargate | Cloud Run | Azure Container Apps |
| Event-triggered functions | AWS Lambda | Cloud Run functions | Azure Functions |
The table starts the investigation. Fargate provides container compute; the row uses it with ECS. Cloud Run and Container Apps also provide application ingress and execution modes. The serverless label alone does not establish equivalent HTTP exposure or recovery from zero instances.
Delegation also varies within Kubernetes. EKS Standard versus Auto Mode and GKE Standard versus Autopilot change node responsibilities and constraints. Check ownership of application permissions, resource settings, releases, and monitoring in every mode. A shared container image does not make IAM and networking portable without changes.
Compare ECS on Fargate, Cloud Run, and Container Apps
| Candidate | Selection-relevant features | Validate before adoption |
|---|---|---|
| ECS on Fargate | Run tasks with specified CPU, memory, networking, and IAM | Load balancer for the public API, service scaling, startup time |
| Cloud Run | HTTPS ingress and request-based service scaling; separate execution modes include jobs | Service, job, or worker pool; concurrent requests and CPU allocation mode |
| Container Apps | KEDA-based scaling using HTTP or queues, revisions, and jobs | Selected scaling rules, minimum replicas, environment networking, and plan |
Run the actual order API container on each candidate with equivalent authentication, timeouts, and dependencies. Evaluate a suitable execution mode separately if continuous background work or long batches are added. Container Apps uses Kubernetes internally but does not expose the Kubernetes API directly. Compare AKS or another Kubernetes service when that control is required.
For sparse traffic and bursts, examine cold starts and scaling delay
With a configuration that scales to zero at night, the first request may wait for startup. Keeping execution environments ready reduces this wait but retains capacity costs. When comparing Cloud Run minimum instances and Container Apps minimum replicas, determine how much capacity is ready and what happens when demand exceeds it.
- Test the first request after inactivity, bursts, and fresh deployments as well as steady traffic. Measure startup and initialization duration and frequency alongside overall p95 and p99.
- Consider preparing capacity before a predictable midday peak. Reactive scaling on CPU or queue depth acts after demand arrives.
- Separate configured concurrency from measured processing capacity. Accepting more requests in one container can still increase CPU, memory, or database contention.
Set scaling limits together with the database connection budget
Assume two processes per instance and a database pool limit of 10 per process. Twenty instances can open 20 × 2 × 10 = 400 connections; 50 can open 1,000. These are aggregate configuration limits if the pools fill, not measurements of active connections or throughput.
- Normal: 20 instances: 400 connections
- Deploy: 30 instances: 600 connections
- Scaled: 50 instances: 1,000 connections
If the database allocates 500 connections to the application, normal operation fits but deployment does not. Sum old and new revisions and all services; with a proxy, count client-side and database-side connections separately. Combine pool limits, global concurrency control, and bounded waits instead of relying solely on a maximum instance setting.
Compare costs across both idle periods and continuous utilization
| Workload characteristic | Costs to include | What changes the decision |
|---|---|---|
| Sparse, highly variable traffic | Active compute, requests, minimum capacity | Can latency targets be met without warm capacity? |
| High utilization all day | Continuous capacity, commitments, operations labor | Does the option remain attractive with headroom and maintenance included? |
| Private networking and heavy communication | Load balancing, NAT or other paths, transfer, logs | Do surrounding services change the total for equivalent CPU? |
Align region requirements, runtime, HA, transfer volume, and log retention in each estimate. Container compute prices alone do not establish the cheapest system. For this API, maintenance time saved is a valid reason to adopt managed execution if requirements are met. A team already operating Kubernetes effectively and using its specific capabilities may reach another conclusion.
Validate the candidate and record a conditional decision
- Use the real container to verify public and private access, application authorization, and required protocols. Check for dependencies on durable local state.
- Reproduce sparse traffic, bursts, and deployments. Measure startup, errors, latency, and database connection waits together.
- Vary minimum capacity and scaling limits, then estimate the cost of configurations that meet latency and database capacity requirements.
- Record the reasoning: this HTTP API fits the execution contract, and tests establish latency and connection behavior. Reevaluate if Kubernetes-specific control becomes necessary.
Primary sources for product scope and settings
- Google Cloud — AWS / Azure / Google Cloud service comparison
- AWS — Fargate for Amazon ECS
- AWS — What is Amazon EKS?
- Google Cloud — What is Cloud Run?
- Google Cloud Run — Maximum concurrent requests
- Google Cloud Run — Minimum instances
- Microsoft Learn — Container options compared
- Microsoft Learn — Container Apps scaling rules