AWS Fargate

6 min read index source

AWS Fargate

Serverless container compute. Run ECS or EKS workloads without managing EC2 nodes. AWS provisions the underlying hosts; you pay per task vCPU/RAM per second.

What problem it solves

Without Fargate, running ECS/EKS means:

  • Provisioning EC2 nodes.
  • Patching them.
  • Scaling them up/down (Cluster Autoscaler or Karpenter).
  • Sizing them to match your pod shapes (and dealing with bin-packing inefficiency).
  • Paying for idle node capacity.

Fargate removes all of this. You declare a task with cpu: 512, memory: 1024; AWS runs it. When the task stops, you stop paying.

Cost model

  • Per-vCPU per second + per-GB-RAM per second.
  • ~20-30% premium over equivalent EC2 (the trade for no ops).
  • No idle node cost.
  • ARM (Graviton) ~20% cheaper.
  • Spot pricing available (~70% off, with 2-min eviction warning).
Example: 3 tasks at 0.5 vCPU + 1GB, 24/7
  3 × 0.5 × 730h × $0.04048/vCPU-h  = $44/mo
  3 × 1.0 × 730h × $0.004445/GB-h   = $10/mo
  total ≈ $54/mo

Vs an EC2 c6g.large (2 vCPU, 4 GB) Reserved instance at ~$45/mo running the same 3 tasks plus headroom. Fargate is slightly more but no patching, no Cluster Autoscaler, no idle.

When Fargate wins

  • Spiky workloads — pay only for runtime, no idle nodes.
  • Dev / CI / batch — fire up a task, run, stop.
  • Small teams — no platform engineer to babysit nodes.
  • Strict isolation — every task runs on a dedicated VM behind the scenes (Firecracker microVMs).
  • Per-task IAM — task role pattern is cleaner with no shared host.

When EC2 (Karpenter/managed nodes) wins

  • Steady high-volume workloads — EC2 reserved/spot is cheaper at sustained load.
  • GPU / large instance types — Fargate doesn’t offer GPUs (use ECS-on-EC2 or SageMaker).
  • DaemonSets (EKS) — Fargate doesn’t run DaemonSets.
  • privileged containers, host network mode, sysctls — Fargate restricts these.
  • docker exec for debugging — limited on Fargate; use ECS Exec (works on Fargate too, but slower iteration).

Networking

Fargate tasks always use awsvpc networking mode — each task gets its own ENI + private IP from your VPC subnet. Implications:

  • You need subnet IP capacity. Tasks consume IPs from /27 or larger subnets quickly. Plan CIDR accordingly.
  • Security groups per task — Fargate ENIs are first-class; attach SGs as needed.
  • Egress to internet requires a NAT Gateway (private subnets) or public subnet + assignPublicIp: ENABLED.
  • VPC Endpoints for ECR / Secrets Manager / S3 are recommended to avoid NAT egress costs.

Ephemeral storage

Default 20 GB per task. Raise to up to 200 GB with ephemeralStorage.sizeInGiB. No persistent storage — Fargate tasks are immutable per run. For persistent data, mount EFS:

"volumes": [{
  "name": "shared",
  "efsVolumeConfiguration": {
    "fileSystemId": "fs-xxx",
    "transitEncryption": "ENABLED"
  }
}],
"containerDefinitions": [{
  "mountPoints": [{"containerPath": "/data", "sourceVolume": "shared"}]
}]

EBS is also supported (2024+) for ECS Fargate — each task gets its own volume, useful for stateful tasks that don’t need pod identity.

Sizes

CPU/RAM combinations are fixed:

vCPU Memory range
0.25 0.5, 1, 2 GB
0.5 1-4 GB
1 2-8 GB
2 4-16 GB
4 8-30 GB
8 16-60 GB
16 32-120 GB

If your app fits a non-standard shape, you pay for the next-up. CPU = sustained, not bursty (no shared-pool burst credits like t-class EC2).

Cold start

Launching a fresh Fargate task takes ~30-60s typically:

  • Image pull (ECR cached at the host level — second tasks of the same image start faster).
  • ENI attach.
  • Container start.

For traffic spikes, service autoscaling lags by ~1-2 min. Either pre-warm with higher base count, or use Lambda for the truly bursty workloads.

Spot Fargate

~70% cheaper, but tasks can be reclaimed with 2-minute notice. Good for:

  • Stateless workers consuming a queue (re-deliver gracefully).
  • CI / batch jobs that can restart.

Bad for:

  • Long-running stateful tasks.
  • Latency-sensitive (eviction = brief unavailability of capacity).
"capacityProviderStrategy": [
  {"capacityProvider": "FARGATE",      "weight": 1, "base": 2},
  {"capacityProvider": "FARGATE_SPOT", "weight": 3}
]

“Always 2 on-demand; everything beyond is 3:1 ratio Spot:on-demand.”

Logs & monitoring

awslogs driver writes container stdout to CloudWatch Logs. Each task gets its own log stream. For high volume, use awsfirelens to ship to cheaper storage (S3 via Firehose, OpenSearch).

CPU/memory metrics in CloudWatch Container Insights. Per-task granularity costs a bit; enable selectively.

ECS Exec — kubectl exec for ECS

aws ecs execute-command \
  --cluster prod --task abc123 \
  --container app --interactive --command "/bin/sh"

Requires:

  • Task role with ssmmessages:* permission.
  • Task definition enableExecuteCommand: true.
  • ECS Exec installed in the image (or AWS-provided ones).

Critical for debugging Fargate where you can’t SSH to the host.

Common gotchas

  • assignPublicIp: ENABLED for ECR pulls. A task in a private subnet without NAT or VPC Endpoint can’t reach ECR. Cryptic “CannotPullContainerError”. Fix: add VPC Endpoint for ECR + S3 (image layers live in S3), or assign public IP, or NAT.
  • Default 20 GB ephemeral fills up. Tasks that download big files fail mid-run. Bump it or use EFS.
  • Stop timeout default 30s. SIGTERM → 30s → SIGKILL. Long-running shutdowns get cut off; raise stopTimeout (max 120s).
  • No DaemonSet equivalent. Per-host agents (log forwarders, metric collectors) don’t fit. Use sidecars in every task or move that workload to ECS-on-EC2.
  • Cost surprise on chatty internal services. Per-vCPU-second is fine for medium workloads; very large fleets with lots of low-utilization tasks cost more than equivalent EC2.

Fargate vs Lambda

Lambda Fargate
Max duration 15 min unlimited
Cold start seconds (or sub-ms with Provisioned) 30-60s
Compute model per-invocation per-task
Local disk 10 GB ephemeral 20-200 GB ephemeral + EFS/EBS
HTTP layer API Gateway / ALB ALB / NLB directly
Best for event-driven, spiky, short long-running services, batch

Rule of thumb: short event handlers → Lambda. Long-running web service or worker → Fargate.

Interview angle

  • “Fargate vs ECS-on-EC2?” — Fargate: no node management, pay per task, ~20-30% premium, faster for small/bursty workloads. EC2: lower per-CPU cost especially with Spot + Reserved, but you manage capacity. Mix is common: Fargate for CI/dev/bursty; EC2 for steady production.
  • “Fargate vs Lambda — when each?” — Lambda: short-lived event handlers, sub-second to minutes, per-invocation pricing. Fargate: long-running services or workers, per-second pricing over the whole lifetime. If it’d be a Celery worker or a FastAPI service, Fargate. If it’s a SQS-triggered handler, Lambda.
  • “How do Fargate tasks talk to other AWS services without keys?” — task role: an IAM role attached to the task; SDK calls in the container assume it automatically. Equivalent to IRSA on EKS or instance profile on EC2.
  • “What’s Fargate Spot and when do you use it?” — Spot pricing for Fargate (~70% off), 2-min eviction warning. Good for stateless workers consuming queues (the next task picks up). Bad for latency-sensitive or stateful.
  • “Why is your Fargate task in a private subnet failing to pull from ECR?” — no internet egress and no VPC Endpoint for ECR/S3. Add VPC Endpoint for ecr.api, ecr.dkr, and s3 (image layers); or add NAT (expensive); or move to public subnet with assignPublicIp: ENABLED.
  • “How do you debug a running Fargate task?” — ECS Exec: aws ecs execute-command --cluster ... --task ... --interactive --command /bin/sh. Requires the task role to have ssmmessages:* and enableExecuteCommand: true on the task definition.