Skip to main content
Multi-CloudServerlessintermediate

Serverless Containers

Comparison of serverless container platforms: AWS Fargate, Azure Container Apps, Google Cloud Run, and OCI Container Instances covering scaling, pricing, networking, and deployment workflows.

CloudToolStack Team22 min readPublished Mar 14, 2026

Prerequisites

  • Basic containerization knowledge (Docker)
  • Understanding of web application deployment concepts

Serverless Containers Across Clouds

Serverless container platforms let you run containerized applications without managing servers, clusters, or infrastructure. You provide a container image, configure scaling parameters, and the platform handles provisioning, autoscaling (including scaling to zero), load balancing, and infrastructure maintenance. This guide compares the four major serverless container platforms: AWS Fargate, Azure Container Apps, Google Cloud Run, and OCI Container Instances.

These services occupy a sweet spot between Functions-as-a-Service (Lambda, Azure Functions, Cloud Functions) and full container orchestration (EKS, AKS, GKE). They give you the packaging flexibility of containers (any language, any framework, any binary) with the operational simplicity of serverless (no servers to patch, automatic scaling, pay-per-use pricing). For many web applications, APIs, and background processors, serverless containers are the optimal deployment model.

This guide covers architecture differences, pricing comparisons, deployment workflows, scaling behavior, networking options, and practical guidance on choosing the right platform for your workload.

Platform Overview

FeatureAWS FargateAzure Container AppsGoogle Cloud RunOCI Container Instances
Underlying TechECS/EKS on Firecracker VMsKubernetes (AKS) + Dapr + KEDAKnative on GKEOCI Compute (bare metal)
Scale to ZeroNo (minimum 1 task)YesYesNo (always running)
Max InstancesService quotas (thousands)300 replicas per revision1000 instances per serviceManual scaling
Max vCPU per Instance16 vCPU4 vCPU8 vCPU64 vCPU (Flex shape)
Max Memory per Instance120 GB8 GB32 GB1024 GB
GPU SupportNoYes (preview)Yes (L4, H100)Yes (A10, A100)
Request TimeoutUnlimitedUnlimited60 minutesUnlimited
Concurrency Model1 request per containerConfigurable concurrencyUp to 1000 concurrent per instanceSelf-managed

Scale to Zero

Scale to zero is a key differentiator. Cloud Run and Azure Container Apps can scale your application to zero instances when there is no traffic, meaning you pay nothing during idle periods. AWS Fargate always runs at least one task, so you pay 24/7 even with zero traffic. For applications with intermittent traffic (internal tools, development environments, webhook handlers), scale-to-zero can reduce costs by 80-95%.

Pricing Comparison

Pricing models vary significantly. Some platforms charge per-second for running containers, others charge per-request plus compute time. The most cost-effective choice depends heavily on your traffic pattern.

ComponentAWS FargateAzure Container AppsGoogle Cloud RunOCI Container Instances
vCPU per second$0.000011244$0.000024$0.000024$0.0000225
GB Memory per second$0.000001235$0.000003$0.0000025$0.0000025
1 vCPU + 2 GB, 24/7/month~$36~$78~$69~$65
Per RequestN/AN/A (consumption plan)$0.40/millionN/A
Free TierNone180K vCPU-sec + 360K GB-sec/mo2M requests + 360K vCPU-sec/moNone
Spot/PreemptibleFargate Spot (up to 70% off)Not availableNot availablePreemptible (50% off)

Fargate is Cheapest for Always-On

For services that run 24/7 with consistent load, AWS Fargate offers the lowest per-second compute cost. However, for services with variable or intermittent traffic, Cloud Run and Azure Container Apps are significantly cheaper due to scale-to-zero and per-request pricing. A service handling 100K requests/day (averaging 100ms each) costs approximately $3/month on Cloud Run versus $36/month on Fargate.

Deployment Workflows

AWS Fargate (via ECS)

bash
# Create an ECS cluster
aws ecs create-cluster --cluster-name my-cluster

# Register a task definition
aws ecs register-task-definition --cli-input-json '{
  "family": "my-app",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "256",
  "memory": "512",
  "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
  "containerDefinitions": [{
    "name": "app",
    "image": "123456789012.dkr.ecr.us-east-1.amazonaws.com/my-app:latest",
    "portMappings": [{"containerPort": 8080, "protocol": "tcp"}],
    "logConfiguration": {
      "logDriver": "awslogs",
      "options": {
        "awslogs-group": "/ecs/my-app",
        "awslogs-region": "us-east-1",
        "awslogs-stream-prefix": "ecs"
      }
    }
  }]
}'

# Create a service with ALB
aws ecs create-service \
  --cluster my-cluster \
  --service-name my-app-service \
  --task-definition my-app \
  --desired-count 2 \
  --launch-type FARGATE \
  --network-configuration "awsvpcConfiguration={subnets=[subnet-xxx],securityGroups=[sg-xxx],assignPublicIp=ENABLED}" \
  --load-balancers "targetGroupArn=arn:aws:elasticloadbalancing:...,containerName=app,containerPort=8080"

Azure Container Apps

bash
# Create an environment
az containerapp env create \
  --name my-environment \
  --resource-group my-rg \
  --location eastus

# Deploy a container app
az containerapp create \
  --name my-app \
  --resource-group my-rg \
  --environment my-environment \
  --image myregistry.azurecr.io/my-app:latest \
  --target-port 8080 \
  --ingress external \
  --cpu 0.5 \
  --memory 1.0Gi \
  --min-replicas 0 \
  --max-replicas 10 \
  --registry-server myregistry.azurecr.io

# Update with a new revision
az containerapp update \
  --name my-app \
  --resource-group my-rg \
  --image myregistry.azurecr.io/my-app:v2 \
  --revision-suffix v2

Google Cloud Run

bash
# Deploy a container to Cloud Run
gcloud run deploy my-app \
  --image=us-central1-docker.pkg.dev/MY_PROJECT/docker-repo/my-app:latest \
  --region=us-central1 \
  --port=8080 \
  --memory=512Mi \
  --cpu=1 \
  --min-instances=0 \
  --max-instances=100 \
  --concurrency=80 \
  --allow-unauthenticated

# Deploy from source code (Cloud Build + Cloud Run)
gcloud run deploy my-app \
  --source=. \
  --region=us-central1

# Traffic splitting for canary
gcloud run services update-traffic my-app \
  --region=us-central1 \
  --to-revisions=my-app-v2=10,my-app-v1=90

OCI Container Instances

bash
# Create a container instance
oci container-instances container-instance create \
  --compartment-id COMPARTMENT_OCID \
  --availability-domain "US-ASHBURN-AD-1" \
  --display-name my-app \
  --shape CI.Standard.E4.Flex \
  --shape-config '{"ocpus": 1, "memoryInGBs": 4}' \
  --containers '[{
    "displayName": "app",
    "imageUrl": "iad.ocir.io/mynamespace/my-app:latest",
    "resourceConfig": {"vcpusLimit": 1, "memoryLimitInGBs": 4}
  }]' \
  --vnics '[{"subnetId": "SUBNET_OCID"}]'

Scaling Behavior

Scaling behavior is one of the most important differentiators between these platforms. How quickly they scale, what triggers scaling, and how they handle cold starts directly impacts user experience and cost.

BehaviorFargateContainer AppsCloud RunOCI CI
Scale TriggerCPU/Memory metrics, target trackingHTTP, KEDA scalers (queue length, etc.)Concurrent requestsManual only
Cold Start30-60 seconds5-30 seconds1-10 seconds60-120 seconds
Scale-Up SpeedMinutesSecondsSecondsManual
Scale-Down DelayConfigurable (5-15 min)30 seconds to 5 minutes15 minutes idleManual
Warm InstancesAlways (min task count)min-replicas settingmin-instances settingAlways on

Cold Starts Matter

Cold start latency directly impacts user experience. Cloud Run has the fastest cold starts (often under 2 seconds for optimized containers) thanks to Knative's efficient container scheduling. Fargate cold starts are the slowest (30-60 seconds) because it provisions a full Firecracker microVM. To eliminate cold starts, set minimum instance counts, but this negates the cost benefit of scale-to-zero. Optimize your container startup time regardless of platform: use smaller base images, minimize dependencies, and defer heavy initialization.

Networking Options

FeatureFargateContainer AppsCloud RunOCI CI
VPC IntegrationNative (runs in VPC)VNet integrationVPC connector / Direct VPCNative (runs in VCN)
Private EndpointsVia ALB in private subnetInternal ingressInternal service with IAMPrivate IP only
Custom DomainsVia ALB + ACMBuilt-in custom domainBuilt-in domain mappingVia Load Balancer
Service MeshApp Mesh / Service ConnectBuilt-in Dapr sidecarService-to-service authManual (Consul/Istio)

When to Use Each Platform

ScenarioBest ChoiceWhy
REST API with variable trafficCloud RunScale to zero, fast cold starts, per-request pricing
Always-on microservice (24/7)FargateLowest per-second cost for always-running workloads
Event-driven with queue processingAzure Container AppsKEDA scalers for queue-based autoscaling
GPU inferenceCloud Run (GPU)Serverless GPU with scale-to-zero
Long-running batch processingFargate / OCI CINo request timeout, higher resource limits
Lowest egress costOCI Container Instances10 TB free egress, $0.0085/GB after
Multi-container sidecar patternsContainer Apps / FargateNative multi-container pods with Dapr sidecars

Multi-Cloud Container Strategy

Because all these platforms run standard OCI containers, your application images are portable across providers. Build your container once and deploy to any platform. Use environment variables for configuration and avoid provider-specific SDKs in your application code (or abstract them behind interfaces). This gives you the freedom to choose the best platform per workload without rewriting application code.

Cloud Run for ProductionCloud Functions vs Cloud RunAWS ECS vs EKS Decision Guide

Key Takeaways

  1. 1Cloud Run and Azure Container Apps support scale-to-zero; Fargate always runs at least one task.
  2. 2Fargate has the lowest per-second cost for always-on workloads (~$36/month for 1 vCPU + 2 GB).
  3. 3Cloud Run has the fastest cold starts (1-10 seconds) and supports up to 1000 concurrent requests per instance.
  4. 4Azure Container Apps provides built-in Dapr sidecar support and KEDA-based queue-driven autoscaling.
  5. 5OCI Container Instances offer the highest per-instance resources (64 vCPU, 1 TB RAM) with lowest egress costs.
  6. 6Standard OCI container images are portable across all four platforms without application code changes.

Frequently Asked Questions

Which serverless container platform should I use?
For variable-traffic APIs: Cloud Run (scale-to-zero, fast cold starts). For always-on microservices: Fargate (lowest per-second cost). For event-driven queue processing: Azure Container Apps (KEDA scalers). For GPU inference: Cloud Run (serverless GPU). For batch processing: Fargate or OCI CI (no timeout limits).
How do cold starts compare across platforms?
Cloud Run: 1-10 seconds (fastest). Azure Container Apps: 5-30 seconds. Fargate: 30-60 seconds (slowest, provisions a full microVM). OCI Container Instances: 60-120 seconds (not designed for dynamic scaling). Optimize by using smaller base images and setting minimum instance counts for latency-sensitive services.
Can I avoid vendor lock-in with serverless containers?
Yes, more so than with FaaS (Lambda, Functions). All platforms run standard OCI containers, so your application images are portable. Use environment variables for configuration and abstract provider-specific SDKs. The deployment configuration differs per platform but the application code remains the same.

Written by CloudToolStack Team

Cloud engineers and architects with hands-on experience across AWS, Azure, and GCP. We write guides based on real-world production patterns, not just documentation rewrites.

Disclaimer: This guide is for educational purposes. Cloud services change frequently; always refer to official documentation for the latest information. AWS, Azure, and GCP are trademarks of their respective owners.