# Azure Container Apps vs AWS ECS on Fargate: a thorough serverless-container comparison (scale-to-zero, GPU, cost, migration)

> A thorough comparison of Azure Container Apps and AWS ECS on Fargate from a production-operations standpoint. From the knowledge of Microsoft Learn official docs and Fargate production operation, it explains, with a judgment axis of which to choose when: scale-to-zero, KEDA event-driven, serverless GPU, automatic HTTPS, Jobs, deployment/rollback, the cost model (free tier, idle rate vs. Spot, Graviton), networking, and identity.

- Published: 2026-06-26
- Author: 友田 陽大
- Tags: Azure, Container Apps, AWS, Fargate, コンテナ, サーバーレス, アーキテクチャ設計, コスト最適化
- URL: https://tomodahinata.com/en/blog/azure-container-apps-vs-aws-ecs-fargate-serverless-container-comparison-guide
- Category: Azure Container Apps in production
- Pillar guide: https://tomodahinata.com/en/blog/azure-container-apps-production-guide

## Key points

- The two are astonishingly the same shape: the philosophy of 'run containers without server management,' fixed CPU/memory pairs, SIGTERM graceful shutdown, identity-based auth, and traffic-splitting deployment. By default, choosing by 'the cloud you're on' is fine.
- Azure Container Apps is clearly advantageous: HTTP/event-driven 'scale-to-zero,' diverse event-driven autoscaling via KEDA, scalable serverless GPU, automatic HTTPS (no LB/cert needed), first-class Jobs, built-in Dapr, and a generous free tier at small scale.
- AWS ECS on Fargate is advantageous: large sizes up to 16 vCPU per task, the steep discount of Fargate Spot, strong per-task ENI isolation, tight coupling with the AWS ecosystem like ALB/IAM/ECS, and CodeDeploy's native Blue/Green.
- Scale-to-zero is ACA's structural strength. An ECS service has no standard mechanism to wake from 0 on an HTTP request, so for spiky/low-traffic uses ACA tends to win on cost.
- For GPU, ACA can serverless-scale-to-zero (NC/T4, A100); Fargate doesn't support it. To intermittently run AI inference cheaply in containers, ACA becomes an option.

---

"To run containers serverless, which is better — AWS Fargate or Azure Container Apps?" — when considering a multi-cloud setup, when migrating from AWS to Azure, or when choosing a cloud for a new project, this question always comes up.

I've [run AWS ECS on Fargate in production](/blog/aws-ecs-fargate-production-guide). The [lumber-distribution B2B SaaS that won the METI Minister's Award](/case-studies/lumber-industry-dx) (221 APIs) and the worker fleet of the [payment platform with 0 double charges in production](/case-studies/payment-platform-reliability) both run on Fargate. From that experience, I can say: **Azure Container Apps (ACA) is astonishingly the same shape as Fargate, and the key points port over almost as-is.** On top of that, there are decisive differences too.

This article cross-checks **the ACA spec faithful to the [Microsoft Learn official documentation](https://learn.microsoft.com/en-us/azure/container-apps/overview)** with **Fargate production-operation knowledge** and shows "which to choose when" by a judgment axis. For ACA alone in production, see the [Azure Container Apps production-operations guide](/blog/azure-container-apps-production-guide), and for Fargate alone, the [AWS ECS on Fargate production-operations guide](/blog/aws-ecs-fargate-production-guide). This piece concentrates on **"the differences between the two."**

---

## The conclusion first, in 3 lines

- **By default, choose by "the cloud you're on."** The two build production quality (scale, resilience, security) in almost the same shape, and there's little reason to switch over deliberately.
- If you need **scale-to-zero, event-driven, serverless GPU, automatic HTTPS, or first-class Jobs**, **ACA** is one notch clearer.
- If you need **larger task sizes, the steep Fargate Spot discount, tight AWS ecosystem coupling, or per-task ENI isolation**, **Fargate**.

| Aspect | Azure Container Apps | AWS ECS on Fargate | Which is advantageous |
|------|---------------------|--------------------|:---------:|
| Scale-to-zero | **Can drop to 0** by HTTP/event | The service **won't wake from 0 by HTTP** | **ACA** |
| Event-driven scale | **KEDA built-in** (many scalers) | App Auto Scaling + custom | **ACA** |
| GPU | **Serverless GPU** (scale-to-zero possible) | **Unsupported** | **ACA** |
| Automatic HTTPS | **Automatic** with Ingress (no LB/cert needed) | **Wire** ALB + ACM cert yourself | **ACA** |
| Jobs (batch/cron/event) | **First-class feature** | RunTask + EventBridge / Batch | **ACA** |
| Max task size | 4 vCPU (Consumption) / 32 (Dedicated) | **Up to 16 vCPU** (standard) | **Fargate** |
| Spot discount | idle rate + scale-to-zero | **Fargate Spot (steep discount)** | **Fargate** |
| Isolation boundary | Environment VNet | **Per-task ENI** | Fargate |
| Ecosystem coupling | Azure (Entra/Key Vault/Service Bus) | AWS (IAM/ALB/SQS/ECR) | Draw |

---

## The same philosophy: what the two share

First grasping "the same" makes migration and comparison far easier. The two are implementations of the same **serverless container** philosophy, and the following are almost common.

- **Server management disappears**: OS patching, node scaling, and capacity management are handled by the platform. You write only the container definition.
- **CPU/memory are fixed pairs**: both choose from prescribed combinations, not free combinations. ACA has a fixed ratio of `memory = vCPU × 2`, and Fargate also has a fixed memory range selectable per vCPU tier.
- **Horizontal scale only**: handle with count, not vertical scale (making one machine bigger). ACA states `Vertical scaling isn't supported.`, and Fargate also scales horizontally by task count.
- **Graceful shutdown on SIGTERM**: both, on scale-in, do `SIGTERM` → grace → `SIGKILL`. ACA is **30 seconds** (extendable with `terminationGracePeriodSeconds`), and Fargate is `stopTimeout` (default 30 seconds, max 120 seconds). The premise of **idempotent worker design** is the same too.
- **Identity-based authentication**: hold no password, access Azure/AWS resources by role/identity. ACA is **managed identity (Entra)**, Fargate is a **task role (IAM).** The concept is the same.
- **Secret injection**: ACA is Key Vault references, Fargate is `valueFrom` from Secrets Manager/SSM. Neither bakes secrets into the image.
- **Staged deployment**: split traffic by % for canary/Blue-Green. ACA is **revisions + traffic splitting**, Fargate is **CodeDeploy's Blue/Green** or rolling + circuit breaker.

> In other words, **the discipline of "how to build for production" you gained with Fargate — right-sizing, idempotency, graceful shutdown, least privilege, keyless CI/CD — works as-is on ACA.** It's not relearning but a substitution of vocabulary.

---

## The architectural difference: how the orchestrator is hidden

The biggest structural difference is **the distance from Kubernetes.**

- **Fargate**: ultimately the **"capacity" of ECS (or EKS).** You operate with the vocabulary of ECS task definitions, services, and clusters, and choose Fargate as their execution foundation. ECS's API is plainly visible.
- **ACA**: **a managed layer built on Kubernetes, KEDA, Dapr, and Envoy**, but `Azure Container Apps doesn't provide direct access to the underlying Kubernetes APIs.` ([official](https://learn.microsoft.com/en-us/azure/container-apps/compare-options)) — **the Kubernetes API is not visible at all.** No kubectl, no CRDs.

This difference shows in "where you can step down to." When Fargate isn't enough, go to **ECS → EKS (raw Kubernetes)**; when ACA isn't enough, go to **AKS.** Both prepare a path to "graduate from managed and grasp the Kubernetes control plane." At that boundary, ACA adopts OSS (KEDA/Dapr/Envoy), so there's the reassurance that **its settings and concepts are contiguous with Kubernetes.**

| Layer | AWS | Azure |
|------|-----|-------|
| Serverless container | **ECS on Fargate** | **Azure Container Apps** |
| Managed Kubernetes | EKS / EKS Auto Mode | AKS / AKS Automatic |
| Low-level one-off container | ECS RunTask | Azure Container Instances |
| FaaS (functions) | Lambda | Azure Functions |

---

## Scale: scale-to-zero and event-driven

This is ACA's **structural winning path.**

### Scale-to-zero: ACA's clear advantage

ACA states `Most applications can scale to zero.` ([official](https://learn.microsoft.com/en-us/azure/container-apps/overview)) — if HTTP or event-driven, it makes replicas **0** when idle and wakes them when a request arrives. No billing during that time.

On the other hand, **an ECS service has no standard mechanism to wake from 0 on an HTTP request.** You can set `desiredCount` to 0, but it won't wake automatically even when a request arrives. To drop a spiky/low-traffic use to zero on Fargate, you need to build a Lambda + α or another contraption.

> **This directly affects cost.** For **intermittent workloads** like "an internal tool used only on weekday afternoons," "an API with a few thousand requests a month," or "an irregular webhook receiver," with ACA the unused time is effectively free. With Fargate, keeping at least 1 task always running (= billed 24 hours) is the realistic compromise.

### Event-driven: KEDA built-in vs. your own metrics

ACA `uses KEDA (Kubernetes Event-driven Autoscaling)` ([official](https://learn.microsoft.com/en-us/azure/container-apps/scale-app)). It can **straightforwardly scale many event sources from "queue length"** — Service Bus, Event Hubs, Kafka, Redis, Queue Storage, etc. The scaling algorithm is also published: `desiredReplicas = ceil(currentMetricValue / targetMetricValue)`.

Fargate is basically **Application Auto Scaling's target tracking.** To scale on an SQS backlog, the standard is to **emit "queue length ÷ task count" as a custom metric to CloudWatch yourself** ([Fargate autoscaling design](/blog/aws-ecs-fargate-auto-scaling-target-tracking-sqs-worker-guide)). It works, but **ACA's event-driven is more "standard-equipped"** and clearer.

| Scale | ACA | Fargate |
|---------|-----|---------|
| HTTP concurrency | Scale rule (`concurrentRequests`) | Target tracking of ALB request count |
| Queue length | **Directly with a KEDA scaler** | A custom metric (backlog/tasks) yourself |
| CPU/memory | Custom rule (**can't be zero**) | Target tracking |
| Scale-to-zero | **Possible (HTTP/event)** | The service can't, by default |
| Upper limit | 1,000 replicas | Within the account limit |

---

## Resources and GPU: size is Fargate, GPU is ACA

### Task size

- **ACA (Consumption)**: `0.25–4 vCPU` / memory is `vCPU × 2` (max 8 GiB). For larger / dedicated hardware, **Dedicated** up to `D32` (32 vCPU/128 GiB), `E32` (32 vCPU/256 GiB).
- **Fargate**: `0.25–16 vCPU` per task / memory up to 120 GB. **Being able to take a lot in a single task** is Fargate's strength.

For "I want to put heavy processing for one request in one container," Fargate's 16 vCPU matters. For "slice it small and handle with count," no difference appears.

### GPU: ACA's serverless GPU vs. Fargate's lack of support

This is clear.

- **ACA**: provides **serverless GPU.** `Consumption-GPU-NC24-A100, Consumption-GPU-NC8as-T4` (NVIDIA T4 / A100) are `per replica` and moreover **scale-to-zero possible** ([Workload profiles](https://learn.microsoft.com/en-us/azure/container-apps/workload-profiles-overview)). You can also choose Dedicated's `NC24/48/96-A100`.
- **Fargate**: **no GPU support.** If you need a GPU, you have to go to ECS's EC2 launch type, AWS Batch, or SageMaker.

> If you **want to run AI inference cheaply and intermittently in containers**, ACA's serverless GPU is a powerful option. You can drop the whole GPU to zero during request-free time — a feat Fargate doesn't have, greatly lowering cost for uses like [self-hosting a quantized LLM](/blog/llm-quantization-serving-economics-awq-fp8-kv-cache-vram-budget).

---

## Ingress / HTTPS: ACA "doesn't assemble it yourself"

ACA states `When you enable ingress, you don't need to create an Azure Load Balancer, public IP address, or any other Azure resources` ([official](https://learn.microsoft.com/en-us/azure/container-apps/ingress-overview)). **HTTPS, FQDN, certificate, HTTP/2, gRPC, and WebSocket are automatic**, and HTTPS is always TLS 1.2/1.3. The request timeout is 240 seconds.

With Fargate, you **wire `ALB (target type=ip) + ACM cert + target group + listener rules` yourself** ([Fargate networking](/blog/aws-ecs-fargate-networking-alb-service-connect-vpc-guide)). Flexible but many steps. For "just publish an HTTPS API in the shortest time," ACA is overwhelmingly faster.

| Ingress | ACA | Fargate |
|---------|-----|---------|
| HTTPS/cert | **Automatic (managed)** | ALB + ACM yourself |
| LB construction | Not needed | Create ALB/NLB |
| HTTP/2, gRPC, WebSocket | **Standard** | Depends on ALB settings |
| Internal exposure | Easy with Internal Ingress | Internal ALB + SG configuration |
| Timeout | Fixed at 240 seconds | Variable with ALB (default 60 seconds, etc.) |

---

## Jobs: ACA is first-class, AWS is assembly

"Processing that runs and finishes" can be handled in ACA as **first-class Jobs** with `Manual / Schedule (cron, UTC) / Event (KEDA)` ([Jobs](https://learn.microsoft.com/en-us/azure/container-apps/jobs)). You can declaratively set retries, parallelism, completion count, and timeout, and an event-driven job can even be a **self-hosted GitHub Actions Runner.**

In AWS, you assemble the same thing with **ECS RunTask + EventBridge Scheduler** or **AWS Batch.** What you can do is equivalent, but **ACA can handle "apps and jobs in the same environment, the same vocabulary,"** so the cognitive load is lower.

| Batch/job | ACA | AWS |
|-------------|-----|-----|
| Scheduled | Schedule Job (cron) | EventBridge Scheduler + RunTask |
| Event-driven | Event Job (KEDA) | EventBridge/SQS + Lambda/RunTask |
| Large-scale parallel batch | parallelism setting | AWS Batch |
| CI Runner | **Standard support with Event Job** | Self-assembled |

---

## Deployment and rollback: the same philosophy, different vocabulary

Both provide a safe-side deployment of "don't switch over if it fails."

- **ACA**: **revisions** (immutable snapshots). Single mode auto-switches fully after the new revision **passes all probes + scales to the old count** (zero downtime). Multiple mode **splits traffic by %** for canary/Blue-Green/A-B, and a **label** gives a stable URL to a specific revision.
- **Fargate**: rolling update + a **deployment circuit breaker** for auto-rollback, or **CodeDeploy's native Blue/Green** (with bake time) ([Fargate CI/CD](/blog/aws-ecs-fargate-cicd-blue-green-codedeploy-github-actions-guide)).

Both are production-quality. ACA's **revisions + traffic splitting** gives the impression that the operation of allocating traffic numerically is intuitive and the canary implementation is somewhat lighter. On the other hand, Fargate + CodeDeploy can be built out to include **automatic metric monitoring during bake time → auto-rollback.**

Keyless CI/CD (OIDC) is **common to both** — Azure with Entra federated credentials, AWS with the IAM OIDC provider. It's the same "trust a short-lived token" design ([throw away keys with GitHub Actions OIDC](/blog/github-actions-oidc-keyless-cicd-aws-gcp-guide)).

---

## Cost model: free tier, idle vs. Spot, Graviton

The skeleton of billing is the same (allocated vCPU-seconds + memory-seconds), but **the optimization levers differ.**

### ACA's weapons: free tier + idle rate + scale-to-zero

Per subscription per month, `The first 180,000 vCPU-seconds`, `The first 360,000 GiB-seconds`, and `The first 2 million HTTP requests` are **free** ([Billing](https://learn.microsoft.com/en-us/azure/container-apps/billing)). Furthermore:

- **No billing when scaled to zero** (`When a revision is scaled to zero replicas, no resource consumption charges are incurred.`)
- An **idle-rate discount** while waiting at minimum replicas
- Service-to-service communication and health probes within an environment are **not subject to request billing**

→ **ACA is overwhelmingly cheaper for small/intermittent workloads.** A small service runs on the free tier alone.

### Fargate's weapons: Spot + Graviton + Savings Plans

- **Fargate Spot**: interruption-tolerant workloads (batch, stateless workers) at a **steep discount.** A `SIGTERM` warning 2 minutes prior.
- **Graviton (ARM64)**: cheaper than x86 and power-efficient.
- **Compute Savings Plans**: a reservation discount for always-on.

→ **Always-high-load, large-scale batch is strong with Fargate Spot + Graviton** ([Fargate cost optimization](/blog/aws-ecs-fargate-cost-optimization-spot-graviton-savings-plans-guide)). ACA has no direct equivalent of Fargate Spot, and instead attacks with "scale-to-zero + idle."

| Cost optimization | ACA | Fargate |
|------------|-----|---------|
| Intermittent/low traffic | **Scale-to-zero + free tier** | At least 1 always resident is realistic |
| Resident, minimum count | idle-rate discount | Savings Plans |
| Interruption-tolerant batch | Scale-to-zero | **Fargate Spot (steep discount)** |
| CPU arch | x86-centric | **Cheaper with Graviton (ARM)** |

---

## Networking and security: the granularity of isolation differs

- **Isolation**: Fargate has `each task with an independent ENI (awsvpc)`, with strong isolation not sharing kernel/CPU/memory/ENI per task. ACA has apps share the **environment's VNet** (the environment = the security boundary). For **strict per-task network isolation**, Fargate is finer-grained.
- **VNet/subnet**: ACA is `/27` in a workload-profile environment, with UDR, NAT Gateway, and Private Endpoint support. Fargate fully controls VPC/subnet/SG. **Both can do egress lockdown (via a firewall).**
- **Identity**: ACA is **managed identity (Entra)** + least privilege via `identitySettings` lifecycle. Fargate separates pull permission and app permission with **separate execution and task roles.** The philosophy is the same "least privilege."
- **Secrets**: ACA is Key Vault references (auto-rotation within 30 minutes + auto-restart of the referencing revision), Fargate is `valueFrom` of Secrets Manager/SSM.

---

## Which to choose: a decision flow

```text
Q1. すでにAWS / Azure に寄っている？
    → YES：素直にそのクラウドの基盤（Fargate / ACA）を選ぶ。差分は本記事で埋まる。

Q2. ワークロードが「間欠・低トラフィック・スパイク」？
    → YES：ACA（ゼロスケール＋無料枠で原価が劇的に下がる）

Q3. キュー/イベント駆動が中心？
    → YES：ACA（KEDAが標準装備で素直）

Q4. GPU推論をコンテナで安く間欠運用したい？
    → YES：ACA（サーバーレスGPU・ゼロスケール）。Fargateは非対応。

Q5. 1タスクで大きいサイズ（〜16 vCPU）or 中断耐性バッチを大幅割引で？
    → YES：Fargate（大きいタスク＋Fargate Spot）

Q6. タスク単位の厳格なネットワーク分離が要件？
    → YES：Fargate（タスク単位ENI）

それ以外：迷ったら「今いるクラウド」。両者の本番運用は同型。
```

### Conclusion

It's **not "which is superior" but "which fits your constraints."** If the cloud is already decided, choose that foundation and fill the key points with this article's difference tables — that's enough. If cloud-free for a new project — emphasize **intermittent workloads, event-driven, serverless GPU, shortest HTTPS publishing** → ACA; emphasize **larger tasks, Spot's deep discount, tight AWS ecosystem coupling** → Fargate.

I've run Fargate in production, but I feel ACA's **scale-to-zero / serverless GPU / first-class Jobs / automatic HTTPS** are clearly a better experience for specific uses. Conversely, the cost-efficiency of hitting large-scale batch with Fargate Spot and the per-task ENI isolation are Fargate-specific. **Knowing both lets you choose the optimal one per project** — that's the value of handling multi-cloud with one person × generative AI.

For either AWS or Azure serverless container platform, from production-quality design to migration and cost optimization — fast, cheap, and safe. For consultation, go to [contact](/contact); for production-operation details, see the [Azure Container Apps production-operations guide](/blog/azure-container-apps-production-guide) and the [AWS ECS on Fargate production-operations guide](/blog/aws-ecs-fargate-production-guide).
