Serverless Containers in 2026: Fargate vs Cloud Run vs Azure Container Apps
You want the operational simplicity of serverless — no servers to manage, automatic scaling, pay-per-use pricing — but your application needs containers. Maybe it is a Java app that does not fit into a Lambda's constraints, or a Python ML model that needs specific system libraries, or simply a Docker image you have already built and tested. Serverless containers give you both worlds. Here is how the three major platforms compare in 2026.
What Are Serverless Containers
Serverless containers run your Docker images without requiring you to provision, patch, or manage the underlying infrastructure. You push a container image, configure scaling rules, and the platform handles the rest — including scaling to zero when there is no traffic.
Traditional: Code → Docker Image → EC2/VM → Load Balancer → Users
Serverless: Code → Docker Image → Platform → Users
(scaling, networking, TLS, monitoring = handled)
Platform Comparison at a Glance
| Feature | AWS Fargate | Google Cloud Run | Azure Container Apps |
|---|---|---|---|
| Scale to zero | No (ECS) / Yes (Lambda containers) | Yes | Yes |
| Cold start | 30-60s (ECS) | 1-5s | 2-10s |
| Max timeout | Unlimited (ECS) | 60 min | 30 min |
| Max memory | 120 GB | 32 GB | 4 GB |
| Max vCPUs | 16 | 8 | 4 |
| GPU support | Yes (limited) | Yes (L4, A100) | No |
| Min instances | 1+ (ECS) | 0 | 0 |
| Pricing model | Per vCPU-second + memory | Per request + vCPU/memory | Per vCPU-second + memory |
| Free tier | None | 2M requests/month | 180K vCPU-s/month |
AWS Fargate: The Enterprise Workhorse
Fargate is AWS's serverless compute engine for containers, running on either ECS (Elastic Container Service) or EKS (Elastic Kubernetes Service). It is the most mature and feature-rich option, but also the most complex.
# ECS Task Definition for Fargate
AWSTemplateFormatVersion: "2010-09-09"
Resources:
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: my-api
RequiresCompatibilities: [FARGATE]
NetworkMode: awsvpc
Cpu: "1024" # 1 vCPU
Memory: "2048" # 2 GB
ExecutionRoleArn: !GetAtt ExecutionRole.Arn
TaskRoleArn: !GetAtt TaskRole.Arn
ContainerDefinitions:
- Name: api
Image: !Sub "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/my-api:latest"
PortMappings:
- ContainerPort: 8080
Protocol: tcp
Environment:
- Name: SPRING_PROFILES_ACTIVE
Value: production
Secrets:
- Name: DATABASE_URL
ValueFrom: !Ref DatabaseSecret
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: /ecs/my-api
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: api
HealthCheck:
Command: ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"]
Interval: 30
Timeout: 5
Retries: 3
Service:
Type: AWS::ECS::Service
Properties:
Cluster: !Ref Cluster
ServiceName: my-api
TaskDefinition: !Ref TaskDefinition
DesiredCount: 2
LaunchType: FARGATE
NetworkConfiguration:
AwsvpcConfiguration:
Subnets: [!Ref PrivateSubnet1, !Ref PrivateSubnet2]
SecurityGroups: [!Ref ServiceSG]
LoadBalancers:
- ContainerName: api
ContainerPort: 8080
TargetGroupArn: !Ref TargetGroup
Fargate strengths:
Deep AWS ecosystem integration (ALB, VPC, IAM, CloudWatch, Secrets Manager)
EKS support for Kubernetes-native workflows
Best for long-running services that need consistent capacity
Up to 120 GB memory and 16 vCPUs per task
Fargate weaknesses:
No scale-to-zero on ECS (minimum 1 task always running)
Complex networking setup (VPC, subnets, security groups required)
Slow cold starts (30–60 seconds for ECS tasks)
Pricing can be expensive for bursty workloads
Google Cloud Run: The Developer Favorite
Cloud Run takes the opposite approach to Fargate — radical simplicity. Deploy a container with a single command:
# Build and deploy in one step
gcloud run deploy my-api \
--source . \
--region us-central1 \
--allow-unauthenticated \
--min-instances 0 \
--max-instances 100 \
--memory 512Mi \
--cpu 1 \
--timeout 300 \
--set-env-vars "NODE_ENV=production"
That is it. Cloud Run builds the container, pushes to Artifact Registry, deploys the service, provisions HTTPS with a custom domain, and configures auto-scaling. No VPC, no load balancer configuration, no IAM roles to set up.
// A minimal Cloud Run service (any HTTP server works)
import express from "express";
const app = express();
app.use(express.json());
app.get("/api/health", (req, res) => {
res.json({ status: "healthy", region: process.env.CLOUD_RUN_REGION });
});
app.post("/api/process", async (req, res) => {
const result = await heavyComputation(req.body);
res.json(result);
});
// Cloud Run sets the PORT environment variable
const port = process.env.PORT || 8080;
app.listen(port, () => console.log(`Listening on port ${port}`));
Cloud Run strengths:
True scale-to-zero (zero cost when idle)
Fast cold starts (1–5 seconds, sub-second with min instances)
Simplest developer experience of all three
Built-in HTTPS, custom domains, traffic splitting
GPU support for ML inference workloads (L4 and A100)
Generous free tier (2 million requests/month)
Cloud Run weaknesses:
60-minute maximum request timeout
Limited to 32 GB memory, 8 vCPUs
No persistent volumes (stateless only)
Less granular networking controls compared to Fargate
Azure Container Apps: The Kubernetes-Powered Middle Ground
Azure Container Apps (ACA) runs on Kubernetes (via KEDA and Envoy) but hides the complexity:
# Deploy with Azure CLI
az containerapp create \
--name my-api \
--resource-group my-rg \
--environment my-env \
--image myregistry.azurecr.io/my-api:latest \
--target-port 8080 \
--ingress external \
--min-replicas 0 \
--max-replicas 30 \
--cpu 1.0 \
--memory 2.0Gi \
--env-vars "ASPNETCORE_ENVIRONMENT=Production" \
--secrets "db-conn=keyvaultref:https://my-vault.vault.azure.net/secrets/db-conn"
ACA's killer feature is built-in Dapr integration for microservices patterns:
# Container App with Dapr sidecar
properties:
configuration:
dapr:
enabled: true
appId: order-service
appPort: 8080
secrets:
- name: db-connection
keyVaultUrl: https://my-vault.vault.azure.net
identity: system
ingress:
external: true
targetPort: 8080
traffic:
- latestRevision: true
weight: 80
- revisionName: order-service--v2
weight: 20 # Canary deployment
template:
scale:
minReplicas: 0
maxReplicas: 30
rules:
- name: http-scaling
http:
metadata:
concurrentRequests: "50"
- name: queue-scaling
azureQueue:
queueName: orders
queueLength: 10
auth:
- secretRef: queue-connection
triggerParameter: connection
ACA strengths:
Scale-to-zero with KEDA-based scaling (HTTP, queue, custom metrics)
Dapr integration for service invocation, pub/sub, state management
Traffic splitting for canary/blue-green deployments built in
Azure Key Vault integration for secrets
Job support for batch processing
ACA weaknesses:
Limited to 4 vCPUs, 4 GB memory per container (lowest of the three)
No GPU support
Younger platform with smaller community
Azure ecosystem lock-in
Cost Comparison: Real-World Scenarios
Scenario 1: API with steady traffic (100 req/s, 24/7)
| Platform | Monthly Cost | Notes |
|---|---|---|
| Fargate (1 vCPU, 2GB) | ~$75 | Always-on, no scale-to-zero |
| Cloud Run (1 vCPU, 512MB) | ~$45 | Scales to match traffic |
| Container Apps (1 vCPU, 2GB) | ~$55 | Scales to match traffic |
Scenario 2: Bursty API (0-500 req/s, active 8h/day)
| Platform | Monthly Cost | Notes |
|---|---|---|
| Fargate (1 vCPU, 2GB) | ~$75 | Pays full price 24/7 |
| Cloud Run (auto-scale) | ~$18 | Scales to zero overnight |
| Container Apps (auto-scale) | ~$22 | Scales to zero overnight |
Scenario 3: Background job (runs 2h/day, needs 4 vCPU, 8GB)
| Platform | Monthly Cost | Notes |
|---|---|---|
| Fargate (scheduled task) | ~$35 | EventBridge schedule + Fargate |
| Cloud Run Jobs | ~$12 | Built-in job scheduler |
| Container Apps Jobs | ~$14 | Built-in job support |
Cloud Run wins on cost for bursty and intermittent workloads due to true scale-to-zero and per-request billing. Fargate is most cost-effective for steady, always-on services where you need predictable capacity.
Decision Framework
Choose Fargate when:
You are already invested in the AWS ecosystem
You need more than 32 GB memory or 8 vCPUs
Your service must be always-on with consistent capacity
You need deep VPC integration and private networking
You want Kubernetes (EKS on Fargate)
Choose Cloud Run when:
You want the simplest possible deployment experience
Your traffic is bursty or unpredictable
Cost optimization is a priority (scale-to-zero)
You need GPU inference capabilities
You are a startup or small team that values speed over customization
Choose Container Apps when:
You need microservices patterns (Dapr, pub/sub, state management)
You want KEDA-based scaling on queues and custom metrics
You are building on Azure and want tight ecosystem integration
You need canary deployments and traffic splitting out of the box
All three platforms have matured significantly by 2026. The best choice depends less on technical capability and more on your team's existing cloud expertise and the specific operational requirements of your workload. Pick the platform that matches your ecosystem, and you will have a production-ready serverless container deployment in hours, not weeks.