# AWS vs Azure vs GCP Compute Services — EC2, ECS, EKS, Lambda, and When to Use What
Choosing the right compute service is one of the most consequential architectural decisions you will make. Pick wrong and you end up either over-engineering your infrastructure with Kubernetes when a simple Lambda would suffice, or under-engineering with serverless when your workload demands persistent compute with full OS control.
This guide provides a structured decision framework, a deep dive into every major compute service across AWS, Azure, and GCP, and real-world architecture patterns that map to different stages of company growth.
---
1. The Decision Framework — Servers vs Containers vs Serverless
Before diving into specific services, you need a mental model for categorizing your workload. The compute spectrum runs from full control (virtual machines) to zero management (serverless functions), with containers occupying the middle ground.
Decision Tree Based on Key Factors
Team Size and Operational Maturity
- Team of 1-5 engineers with no dedicated ops: Serverless (Lambda, Cloud Functions) or managed containers (App Runner, Cloud Run)
- Team of 5-15 with some ops capability: Managed containers (ECS Fargate, Azure Container Apps)
- Team of 15+ with dedicated platform engineering: Kubernetes (EKS, AKS, GKE) or VMs for specialized workloads
Traffic Pattern
- Bursty with quiet periods (webhook processors, scheduled jobs, event handlers): Serverless scales to zero and you pay nothing during idle time
- Steady baseline with occasional spikes (web applications, APIs): Containers with auto-scaling provide predictable performance with burst capacity
- Consistently high throughput (streaming processors, real-time bidding): VMs or containers with reserved capacity give you the best price-performance ratio
State Requirements
- Stateless request-response (APIs, web servers, data transformations): Any compute model works; prefer serverless or containers for simplicity
- In-memory state (WebSocket connections, game servers, caching): VMs or long-running containers; serverless is a poor fit
- Local disk state (databases, search indices, ML model serving): VMs with attached storage or StatefulSets in Kubernetes
Cold Start Tolerance
- Sub-100ms response required (real-time trading, user-facing APIs with strict SLAs): VMs or always-warm containers
- 100ms-1s acceptable (most web APIs, internal services): Containers with minimum replica count
- 1-10s acceptable (background processing, async workflows): Serverless with cold starts is fine
- Seconds to minutes acceptable (batch jobs, data pipelines): Serverless or spot instances
Cost Sensitivity
- Optimizing for lowest possible cost: Spot instances for fault-tolerant workloads, serverless for low-traffic workloads, reserved instances for predictable steady-state
- Optimizing for operational simplicity over raw cost: Managed services (Fargate, App Runner, Cloud Run) trade higher per-unit cost for zero cluster management
- Optimizing for performance at scale: Reserved VMs or Savings Plans with right-sizing
---
2. AWS Compute Services Deep Dive
EC2 (Elastic Compute Cloud)
EC2 is the foundational compute service — a virtual machine in the cloud with full OS-level control. Despite the rise of containers and serverless, EC2 remains the right choice for specific workloads.
When to Use EC2:
- GPU workloads: ML training and inference (P4d, P5 instances with NVIDIA GPUs), video encoding, scientific computing
- Legacy applications: Software that requires specific OS configurations, kernel modules, or cannot be containerized
- Full OS control: Custom networking configurations, specialized kernel parameters, direct hardware access
- High-performance computing: Instances with placement groups for low-latency inter-node communication
- Licensing requirements: Software with per-socket or per-core licensing that requires dedicated hosts
Instance Family Guide:
| Family | Optimized For | Example Use Case | Instance Example |
|---|---|---|---|
| M (General) | Balanced CPU/Memory | Web servers, app servers | m6i.xlarge |
| C (Compute) | High CPU-to-memory ratio | Batch processing, encoding | c6i.2xlarge |
| R (Memory) | High memory-to-CPU ratio | In-memory databases, caching | r6i.4xlarge |
| P/G (Accelerated) | GPU compute | ML training, rendering | p4d.24xlarge |
| I (Storage) | High IOPS local storage | Databases, data warehouses | i3.2xlarge |
| T (Burstable) | Variable CPU with credits | Dev/test, low-traffic web | t3.medium |
Pricing Models:
- On-Demand: Pay by the second with no commitment. Best for unpredictable workloads or short-term needs. Most expensive per-hour rate.
- Reserved Instances (1 or 3 year): Up to 72% discount for committing to a specific instance type in a specific region. Best for steady-state production workloads you know you will run continuously.
- Savings Plans: More flexible than Reserved — commit to a dollar amount per hour of compute usage. Applies across instance families and even across services (EC2, Fargate, Lambda).
- Spot Instances: Up to 90% discount for using spare capacity. Can be interrupted with 2-minute notice. Best for fault-tolerant batch processing, CI/CD runners, and stateless workers with checkpointing.
ECS (Elastic Container Service)
ECS is AWS's proprietary container orchestration service. It runs Docker containers without the complexity of Kubernetes. You define your application as task definitions (essentially Docker Compose for the cloud) and ECS handles scheduling, health checks, and scaling.
Two Launch Types:
Fargate (Serverless Containers):
- No EC2 instances to manage — AWS handles the underlying infrastructure
- You specify CPU and memory for each task, and AWS provisions compute automatically
- Pay per vCPU and GB of memory per second of task runtime
- Best for: Teams that want containers without cluster management, variable workloads, microservices
EC2 Launch Type:
- You manage a cluster of EC2 instances that ECS schedules containers onto
- More control over instance types, GPU access, and local storage
- Can use Spot Instances for the underlying cluster to reduce costs
- Best for: GPU workloads in containers, workloads needing specific instance types, cost optimization at scale
Key ECS Concepts:
- Task Definition: The blueprint — container image, CPU/memory, ports, environment variables, IAM role
- Service: Maintains a desired count of tasks, handles load balancer registration, rolling deployments
- Service Auto-Scaling: Scale based on CPU, memory, or custom CloudWatch metrics. Target tracking (maintain 70% CPU) or step scaling (if CPU > 80%, add 2 tasks)
When ECS Over EKS:
- Your team does not have Kubernetes expertise and does not want to invest in learning it
- You do not need the Kubernetes ecosystem (Helm charts, service mesh, GitOps with ArgoCD)
- You want simpler IAM integration (ECS task roles are more straightforward than EKS IRSA)
- You are running a small to medium number of services (under 50)
EKS (Elastic Kubernetes Service)
EKS is AWS's managed Kubernetes service. AWS manages the control plane (API server, etcd, scheduler), while you manage worker nodes (or use Fargate for serverless pods).
When to Use EKS:
- You need the Kubernetes ecosystem: Helm for packaging, Istio or Linkerd for service mesh, ArgoCD or Flux for GitOps, Prometheus for monitoring
- Multi-cloud portability: Kubernetes abstractions work across AWS, Azure, GCP, and on-premises
- Large microservices architectures: Kubernetes excels at managing hundreds of services with complex networking, service discovery, and traffic management
- Team already knows Kubernetes: If your engineers are Kubernetes-fluent, EKS lets them use familiar tools
Worker Node Options:
- Managed Node Groups: AWS handles node provisioning, AMI updates, and draining during upgrades. You pick instance types and scaling policies.
- Self-Managed Nodes: Full control over the AMI, bootstrap scripts, and node configuration. More work but needed for custom kernels or specialized hardware.
- Fargate Profiles: Serverless pods — no nodes to manage. Best for batch jobs, dev/test environments, or services with highly variable traffic. Limited by Fargate constraints (no DaemonSets, no privileged containers).
Cost Considerations:
- EKS control plane: $0.10/hour ($73/month) regardless of cluster size
- Worker nodes: EC2 costs plus EKS does not add a premium on node compute
- Fargate pods: Same Fargate pricing as ECS (premium over EC2 for the convenience)
- Hidden costs: Load balancers, NAT gateways, cross-AZ traffic, EBS volumes for persistent storage
EKS is NOT Worth It If:
- You have fewer than 10 services
- Your team has no Kubernetes experience and does not want to invest 3-6 months in learning
- You do not need service mesh, GitOps, or complex traffic management
- Cost is a primary concern and your workloads are simple
Lambda (Serverless Functions)
Lambda runs code in response to events without provisioning or managing servers. You upload your function code, configure a trigger, and AWS handles everything else.
Key Characteristics:
- Sub-second billing: Charged per millisecond of execution time
- Maximum execution time: 15 minutes per invocation
- Memory: 128MB to 10,240MB (CPU scales proportionally with memory)
- Concurrent executions: 1,000 per region by default (can be increased)
- Deployment package: 50MB zipped, 250MB unzipped (container image support up to 10GB)
Ideal Use Cases:
- Event-driven processing: S3 uploads trigger image processing, DynamoDB streams trigger downstream updates
- API backends: API Gateway + Lambda for request-response APIs with low to moderate traffic
- Scheduled tasks: CloudWatch Events trigger periodic jobs (cheaper than running an EC2 24/7 for a cron job)
- Data transformation: Kinesis or SQS event processing in real-time
- Webhooks and integrations: Receive and process webhooks from third-party services
Cold Start Implications:
- Java and .NET: 1-5 seconds cold start (JVM initialization)
- Python and Node.js: 100-500ms cold start
- Provisioned Concurrency: Pre-warms function instances to eliminate cold starts ($$$)
- SnapStart (Java): Reduces Java cold starts to ~200ms by snapshotting initialized state
When NOT to Use Lambda:
- Long-running processes (>15 minutes): Use ECS tasks or Step Functions for orchestration
- Stateful applications: No persistent local storage between invocations
- High-throughput steady state: At consistent high volume, a container is cheaper per-request
- WebSocket connections: Lambda is request-response; use API Gateway WebSocket or EC2/ECS
- Large dependency trees: 250MB limit makes large ML models or complex applications impractical (unless using container images)
Elastic Beanstalk
Elastic Beanstalk is a PaaS layer on top of EC2, ECS, and other AWS services. You upload your application code and Beanstalk handles provisioning, load balancing, auto-scaling, and health monitoring.
When to Use:
- Developers who want to deploy web applications without learning AWS infrastructure deeply
- Standard web applications (Java, .NET, Node.js, Python, Ruby, Go, Docker)
- Teams transitioning from Heroku or similar PaaS providers
- Proof of concept or MVP development where time-to-deploy matters more than fine-grained control
Limitations at Scale:
- Opinionated defaults that are hard to override without custom .ebextensions
- Blue/green deployments are clunky compared to ECS rolling updates
- Limited to specific application patterns (web server + worker)
- Debugging infrastructure issues requires understanding the underlying EC2/ELB/ASG anyway
- Most teams outgrow Beanstalk and migrate to ECS or EKS within 1-2 years
App Runner
App Runner is the simplest path from a container image (or source code) to a running, load-balanced, auto-scaling web service. It is effectively Fargate with all the networking and scaling pre-configured.
When to Use:
- Container image to public HTTPS URL in minutes
- Web services and APIs that do not need complex networking (private VPC connectivity was added later)
- Teams that find Fargate task definitions, services, target groups, and listeners too much configuration
- Internal tools, dashboards, and simple microservices
Comparison with Fargate:
- App Runner: Less configuration, less control, slightly higher cost, faster to deploy
- Fargate (via ECS): More configuration options, VPC-native, service mesh compatible, slightly cheaper at scale
---
3. Azure Equivalents
Azure provides comparable compute services with different naming and some architectural differences.
Azure Virtual Machines = EC2
- Same concept: Choose VM size, OS, disk, networking
- Unique advantage: Azure Hybrid Benefit — use existing Windows Server or SQL Server licenses for up to 85% savings
- VM Scale Sets equivalent to EC2 Auto Scaling Groups
- Azure Spot VMs equivalent to EC2 Spot Instances
Azure Container Instances (ACI) = Fargate Tasks
- Run containers without managing VMs
- Best for: Burst compute, CI/CD jobs, simple containerized tasks
- Difference: ACI is more "run a container" than "run a service" — no built-in load balancing or service discovery
- For service patterns, use Azure Container Apps instead
Azure Kubernetes Service (AKS) = EKS
- Managed Kubernetes with free control plane (EKS charges $73/month)
- Virtual Nodes integrate ACI for serverless burst capacity
- Strong integration with Azure Active Directory for RBAC
- Unique: AKS has better Windows container support than EKS
Azure Functions = Lambda
- Event-driven serverless compute
- Unique advantages: Durable Functions for stateful orchestration (equivalent to Step Functions but built into the programming model)
- Consumption plan (pay-per-execution) or Premium plan (pre-warmed, VNet connected)
- Longer maximum execution time on Premium plan (unlimited vs Lambda's 15 minutes)
Azure App Service = Elastic Beanstalk
- PaaS for web applications with built-in CI/CD, SSL, custom domains
- More mature and feature-rich than Beanstalk
- Deployment slots for blue/green deployments
- Better developer experience with tight Visual Studio integration
Azure Container Apps = App Runner
- Serverless containers built on Kubernetes (uses KEDA for scaling)
- Dapr integration for microservices communication
- Scale-to-zero capability
- More features than App Runner, positioned between App Runner and full AKS
---
4. GCP Equivalents
GCP takes a more opinionated approach, often having fewer services that cover more ground per service.
Compute Engine = EC2
- Standard IaaS virtual machines
- Unique: Live migration — GCP moves your VM to another host during maintenance without downtime
- Sustained Use Discounts: Automatic discounts (up to 30%) for VMs running more than 25% of the month — no commitment required
- Committed Use Discounts: 1 or 3 year commitments for additional savings (similar to Reserved Instances)
Cloud Run = Fargate + App Runner (Best Serverless Container Platform)
- The simplest and most capable serverless container platform available today
- Container-to-URL with automatic HTTPS, scaling, and scale-to-zero
- Pay per request + compute time (100ms granularity)
- Supports WebSockets, gRPC, streaming responses
- Minimum instances for eliminating cold starts
- Unique advantages over AWS equivalents: simpler pricing, scale-to-zero by default, faster cold starts, better developer experience
- Can handle both simple APIs and complex workloads up to 60 minutes execution time
GKE (Google Kubernetes Engine) = EKS (Most Mature Managed K8s)
- Google invented Kubernetes, and GKE shows it
- GKE Autopilot: Fully managed nodes — you just deploy pods, Google manages everything else (similar to Fargate on EKS but with better Kubernetes compatibility)
- Faster cluster creation and upgrades than EKS
- Better default security configuration
- Multi-cluster management with GKE Enterprise (formerly Anthos)
- Free control plane for Autopilot clusters (standard charges $0.10/hour like EKS)
Cloud Functions = Lambda
- Event-driven serverless functions
- Gen 2 is built on Cloud Run (longer execution time, concurrency, Cloud Run features)
- Slightly better cold start times than Lambda for most runtimes
- Simpler deployment model
App Engine = Elastic Beanstalk
- One of the oldest PaaS platforms (predates Beanstalk)
- Standard Environment: Sandbox with fast scaling, limited languages
- Flexible Environment: Docker containers with more control
- Being gradually superseded by Cloud Run for new projects
---
5. Which Cloud to Choose
Existing Team Skills
| Team Background | Recommended Cloud | Reasoning |
|---|---|---|
| Microsoft/.NET shop | Azure | Native .NET support, Azure AD integration, Visual Studio tooling |
| Startup / general web | AWS | Largest community, most tutorials, broadest service catalog |
| Data/ML focused | GCP | BigQuery, Vertex AI, TensorFlow ecosystem |
| No preference | AWS or GCP | AWS for breadth, GCP for simplicity and developer experience |
Pricing Comparison
- AWS: Reserved Instances (1/3 year) or Savings Plans for steady-state discounts. Complex pricing with many line items.
- Azure: Hybrid Benefit for existing Microsoft licenses. Reserved VM Instances. Generally comparable to AWS pricing.
- GCP: Sustained Use Discounts apply automatically (no commitment needed). Committed Use Discounts for additional savings. Per-second billing was a GCP innovation (AWS followed). Generally 5-15% cheaper than AWS for equivalent compute.
Service Breadth
AWS has the broadest service catalog with 200+ services. Azure is second with strong enterprise and hybrid offerings. GCP has fewer services but each tends to be more polished and developer-friendly. For most workloads, all three clouds have equivalent services. The difference shows in niche requirements.
Kubernetes
- GKE: Most mature, fastest upgrades, best autopilot mode, invented by Google
- EKS: Largest ecosystem of third-party integrations, most Helm charts tested on EKS
- AKS: Free control plane, best Windows container support, tight Azure AD integration
AI and ML
- GCP: Vertex AI, BigQuery ML, TPUs, TensorFlow. Best for ML-native workloads.
- AWS: SageMaker, Bedrock (LLM hosting), broadest selection of foundation models. Best for enterprises wanting managed ML infrastructure.
- Azure: Azure OpenAI Service (exclusive GPT-4 access for enterprise), Azure AI Studio. Best for organizations wanting OpenAI models with enterprise governance.
Compliance and Government
- AWS GovCloud: Isolated regions for US government workloads (FedRAMP High, ITAR)
- Azure Government: Separate datacenters for US government, strong DoD certifications
- GCP: Assured Workloads for regulated industries, fewer government-specific regions
The Multi-Cloud Reality
Most enterprises end up using multiple clouds. Common patterns:
- AWS for primary infrastructure + GCP for BigQuery and AI/ML
- Azure for corporate IT (Office 365, Active Directory) + AWS for product engineering
- Primary cloud for compute + secondary for specific best-in-class services
Do not architect for multi-cloud from day one unless you have a specific requirement. The abstraction cost is real. Use cloud-agnostic technologies (Kubernetes, Terraform, PostgreSQL) to keep options open without paying the multi-cloud tax upfront.
---
6. Three Architecture Examples
Architecture 1: Startup MVP (Zero Ops, Pay-Per-Use)
Profile: 2-3 engineers, building an MVP, traffic is unpredictable (could be 10 users or 10,000), budget is tight.
Stack:
API Gateway → Lambda → DynamoDB
↓
CloudFront → S3 (static frontend)
↓
Cognito (authentication)
↓
SES (transactional email)
Why This Works:
- Zero operational overhead — no servers to patch, no clusters to manage
- Scales to zero: if nobody uses your app, you pay essentially nothing
- Scales up: Lambda handles thousands of concurrent requests automatically
- DynamoDB on-demand pricing: pay per read/write, no provisioned capacity to get wrong
- Total cost at low traffic: $5-20/month
- Total cost at moderate traffic (100K requests/day): $50-150/month
When to Migrate Away:
- Response time requirements below 50ms (Lambda cold starts)
- Monthly Lambda bill exceeds $500-1000 (containers become cheaper)
- Need WebSocket connections or long-running processes
- Team grows and wants more control over deployment patterns
Architecture 2: Growing SaaS (Container Simplicity Without K8s)
Profile: 10-15 engineers, 50K+ users, predictable growth, need reliability without Kubernetes complexity.
Stack:
ALB → ECS Fargate Services (3-10 services)
↓
RDS PostgreSQL (Multi-AZ)
↓
ElastiCache Redis (session store, caching)
↓
SQS → Fargate Workers (async processing)
↓
CloudFront → S3 (static assets)
Why This Works:
- ECS is simpler to operate than Kubernetes — task definitions are straightforward
- Fargate means no EC2 instances to manage, patch, or right-size
- ALB handles TLS termination, health checks, and traffic distribution
- SQS decouples async work from request-response path
- RDS Multi-AZ gives you automated failover without managing replication
- Monthly cost for moderate SaaS: $2,000-5,000
When to Migrate Away:
- Need service mesh for complex traffic routing (canary, circuit breaking)
- Operating 30+ microservices and deployment coordination becomes painful
- Need multi-cluster for DR or multi-region deployment
- Team has grown to 30+ engineers and wants platform engineering capabilities
Architecture 3: Enterprise Platform (Full Control, Team Maturity Required)
Profile: 30+ engineers, dedicated platform team, hundreds of microservices, strict compliance requirements.
Stack:
Istio Ingress Gateway → EKS Cluster (Multi-AZ)
↓
ArgoCD (GitOps deployments)
↓
Istio Service Mesh (mTLS, traffic management)
↓
RDS Aurora PostgreSQL (Multi-AZ, read replicas)
↓
Amazon MSK (Kafka for event streaming)
↓
Prometheus + Grafana (observability)
↓
Vault (secrets management)
Why This Works:
- Kubernetes provides a consistent deployment target for all teams
- Istio handles mTLS between services (zero-trust networking), canary deployments, circuit breaking
- ArgoCD enables GitOps: all deployments are git commits, full audit trail
- Platform team manages the cluster; product teams just write Dockerfiles and Kubernetes manifests
- Can support hundreds of services with complex interdependencies
- Monthly cost: $15,000-50,000+ depending on scale
Prerequisites:
- Dedicated platform engineering team (3-5 people minimum)
- Investment in developer tooling (internal developer platform, service templates)
- Mature CI/CD pipelines and testing practices
- Incident response processes and on-call rotations
---
Comparison Table: Use Cases to Recommended Services
| Use Case | AWS | Azure | GCP | Key Consideration |
|---|---|---|---|---|
| Simple API backend | Lambda + API GW | Azure Functions | Cloud Run | Serverless simplicity |
| Web application | ECS Fargate | App Service | Cloud Run | Managed containers |
| ML training | EC2 P4d/P5 | NC-series VMs | Compute Engine + TPU | GPU availability |
| ML inference | SageMaker Endpoints | Azure ML | Vertex AI Predictions | Managed ML serving |
| Batch processing | Lambda or Spot EC2 | Azure Batch | Cloud Run Jobs | Cost optimization |
| Real-time streaming | ECS + Kinesis | AKS + Event Hubs | GKE + Pub/Sub | Throughput requirements |
| Microservices (< 20) | ECS Fargate | Container Apps | Cloud Run | Container simplicity |
| Microservices (50+) | EKS | AKS | GKE | Kubernetes ecosystem |
| Static website | S3 + CloudFront | Static Web Apps | Cloud Storage + CDN | CDN and caching |
| Cron jobs | Lambda + EventBridge | Functions + Timer | Cloud Scheduler + Run | Serverless scheduling |
| WebSocket server | ECS or EC2 | App Service | Cloud Run (native) | Persistent connections |
| Game server | EC2 + GameLift | EC2 Spot Fleet | Compute Engine | Low latency, stateful |
---
Key Takeaways
---
Frequently Asked Questions
What is the difference between IaaS, PaaS, and SaaS?
IaaS (Infrastructure as a Service) provides virtual machines and networking where you manage the OS and up. PaaS (Platform as a Service) like Heroku or App Engine manages the runtime so you just deploy code. SaaS (Software as a Service) is fully managed applications like Gmail. Choose based on how much operational control you need versus want to offload.
How do I choose between AWS EC2, Azure VMs, and Google Compute Engine?
All three offer similar compute capabilities. Choose based on your existing ecosystem — AWS for broadest service catalog, Azure for Microsoft stack integration, GCP for data/ML workloads and per-second billing. Price differences are typically under 10% for equivalent instances, so the decision usually comes down to team expertise and other services you use.
What is the difference between on-demand and spot instances?
On-demand instances charge a fixed hourly rate with no commitment and no interruption risk. Spot instances offer 60-90% discounts but can be terminated with 2 minutes notice when capacity is needed. Use spot for fault-tolerant workloads like batch processing, CI/CD builds, and stateless web servers behind auto-scaling groups.
When should I use serverless versus containers?
Use serverless (Lambda, Cloud Functions) for event-driven workloads with variable traffic, sub-15-minute execution times, and when you want zero infrastructure management. Use containers for long-running services, workloads needing persistent connections, applications with specific runtime requirements, or when you need predictable performance without cold starts.
---
Related Resources
- Cloud Region Selection Guide — How to choose the right region for latency, compliance, and cost
- SMS and Email Notifications Architecture — Building cost-effective notification systems
- Docker Production Best Practices — Container hardening for production deployments
- Kubernetes Pod Troubleshooting — Debugging common pod issues in EKS, AKS, and GKE