AWS Fargate 101: Serverless Containers Explained
A practical guide to AWS Fargate: task definitions, awsvpc networking, cost trade-offs, and when serverless containers beat managing EC2 hosts yourself.
Running containers on EC2 means managing OS patches, cluster capacity, and host-level failures. That work scales with the number of hosts, not with application complexity. AWS Fargate takes the layer away: you hand AWS a container image and a CPU/memory pair, and it runs the task on infrastructure you never log into.
For new containerized workloads, Fargate is the sensible default. You pay a premium per unit of compute and stop maintaining hosts in exchange. The cases where that trade goes the wrong way are specific: GPU workloads, privileged containers, and steady high utilization that Reserved Instances or Spot already cover. Knowing which side of that line a workload falls on is most of the decision.
How to Think About Fargate
In practice, Fargate is essentially the “I just want to run my containers” option. You provide AWS with your Docker image, specify your CPU and memory requirements, and it takes care of the underlying infrastructure. No EC2 instances to patch, no cluster capacity planning, and no late-night alerts about disk space issues.
A useful mental model: if EC2 is like owning a car (oil changes, tire rotations, that weird noise it keeps making), then Fargate is more like using a ride service. You specify your destination (run this container), and someone else handles the vehicle maintenance.
The Architecture
The elegant part of this approach is the isolation model. Each Fargate task runs in its own environment with dedicated kernel, CPU resources, memory, and network interface. It’s similar to having a dedicated micro-VM for each container, but without the operational overhead that usually comes with VM management.
Your First Deployment
Here is a practical Fargate deployment on ECS. For a first deployment, ECS has fewer moving parts than EKS; unless you have a specific Kubernetes requirement, it is the simpler starting point.
The first step is creating a task definition, which is essentially telling AWS what resources your container needs:
{
"family": "my-app",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "256",
"memory": "512",
"executionRoleArn": "arn:aws:iam::111122223333:role/ecsTaskExecutionRole",
"containerDefinitions": [
{
"name": "my-app",
"image": "nginx:latest",
"portMappings": [
{
"containerPort": 80,
"protocol": "tcp"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/my-app",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "ecs"
}
}
}
]
}
The execution role is easy to forget. Without it the task cannot pull the image or write to CloudWatch Logs, and it fails before your code runs.
A second detail that trips people up: the CPU and memory values are not arbitrary. Fargate supports specific combinations:
| CPU (vCPU) | Memory Values (GB) |
|---|---|
| 0.25 | 0.5, 1, 2 |
| 0.5 | 1, 2, 3, 4 |
| 1 | 2, 3, 4, 5, 6, 7, 8 |
| 2 | 4-16 (1GB increments) |
| 4 | 8-30 (1GB increments) |
| 8 | 16-60 (4GB increments) |
| 16 | 32-120 (8GB increments) |
If you pick an invalid combination, AWS will let you know and ask you to adjust. This often surfaces when a task definition is copied from an EC2 setup and the tasks won’t start.
Networking Considerations
Fargate only supports awsvpc network mode. Each task gets its own elastic network interface (ENI) with a private IP address. That is good for security isolation, but it means subnet sizing and ENI quotas become part of your capacity planning.
Here’s an example using Terraform (which is more manageable than console clicking for anything beyond initial experiments):
resource "aws_ecs_service" "my_app" {
name = "my-app-service"
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.my_app.arn
desired_count = 2
launch_type = "FARGATE"
network_configuration {
subnets = aws_subnet.private[*].id
security_groups = [aws_security_group.ecs_tasks.id]
assign_public_ip = false
}
load_balancer {
target_group_arn = aws_lb_target_group.my_app.arn
container_name = "my-app"
container_port = 80
}
}
# Important: Fargate requires 'ip' target type, not 'instance'
resource "aws_lb_target_group" "my_app" {
name = "my-app-tg"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.main.id
target_type = "ip" # <-- This is crucial for Fargate
health_check {
enabled = true
healthy_threshold = 2
unhealthy_threshold = 2
timeout = 5
interval = 30
path = "/health"
matcher = "200"
}
}
Fargate vs EC2: Decision Criteria
A quick way to frame the choice:
Where Fargate Fits
- Unpredictable or spiky traffic
- A team that would rather spend its time on application code than on hosts
- Many small, isolated services
- Compliance requirements that call for strong workload isolation
- An existing container workflow
Where EC2 Fits
- GPU workloads (Fargate has no GPU support)
- Windows containers with specific host requirements
- Predictable, high utilization where Reserved Instances or Spot cut the bill
- Privileged containers or custom kernel modules
- Anything that needs host-level access, such as node-level monitoring agents
Cost Considerations
Fargate costs more per unit of compute than EC2. For a service sized at 2 vCPU and 4 GB running around the clock in us-east-1, list prices land roughly here:
| Option (2 vCPU, 4 GB) | Monthly, running 24/7 |
|---|---|
| EC2 t3.medium, On-Demand | ~$30 |
| EC2 t3.medium, 1-year Reserved | ~$19 |
| Fargate, On-Demand | ~$72 |
| Fargate Spot | ~$22 |
Compute Savings Plans cover Fargate too, and the discount depends on the term and payment option you commit to.
Note: AWS pricing varies by region and changes over time. These are approximate list prices for illustration; check current pricing in your region.
Fargate Spot deserves special mention here. It offers up to 70% cost savings by running tasks on spare capacity, though tasks can be interrupted with 2-minute notice. For fault-tolerant workloads, it can make Fargate surprisingly cost-competitive.
What these numbers don’t capture is the operational overhead saved:
- No OS patching and updates
- No cluster capacity planning
- No auto-scaling group management
- No instance health monitoring
- No capacity shortage emergencies
None of that shows up on an invoice, which is why the hourly comparison on its own overstates the gap.
Common Surprises
-
Startup is not instant: image pull, ENI attachment, and the first health checks all happen before a task takes traffic. Plan for that gap in deployment and scale-out windows rather than assuming a task is live the moment it is scheduled.
-
ENI limits: each Fargate task consumes an ENI and a subnet IP address. Hitting the network interface quota, or running out of addresses in a small subnet, stops tasks from launching. This tends to bite during a busy deployment day.
-
No SSH Access: You can’t SSH into Fargate containers the traditional way. ECS Exec provides debugging access:
aws ecs execute-command \ --cluster my-cluster \ --task abc123 \ --container my-app \ --interactive \ --command "/bin/sh"This only works if the service was created with
enableExecuteCommandand the task role can talk to SSM. -
Ephemeral storage: tasks get 20 GB of ephemeral storage by default and can be configured up to 200 GB. Past that, mount EFS and expect slower I/O than local disk.
-
Platform Versions: Fargate pins each task to a platform version, and
LATESTresolves to 1.4.0 on Linux. AWS moves these forward for you, which is usually fine and occasionally changes behavior. Test in staging first.
A Reference Architecture
A common production shape for a web service on Fargate:
What matters in this layout:
- Use ALB for load balancing - It integrates seamlessly with Fargate’s IP-based targets
- Put Fargate tasks in private subnets - Use NAT gateways for outbound internet
- Use Parameter Store or Secrets Manager - Don’t bake secrets into images
- Set up proper logging - CloudWatch Logs is fine to start, but consider Datadog or similar for production
- Monitor ENI allocation - It’s the resource you’ll run out of first
The Bottom Line
Start with Fargate for new containerized workloads and stay there until a specific constraint pushes you off: GPU access, privileged containers, custom kernel modules, or a steady load where Reserved Instances or EC2 Spot clearly win on price. If Fargate spend becomes the thing you argue about in planning, that is usually a good problem; it means the workload is predictable enough to justify the engineering time that cluster management costs.
A reasonable next step: size one non-critical service at 0.5 vCPU / 1 GB, run it behind an ALB with ip targets, and compare the bill against the EC2 host it would have replaced plus the maintenance that host needs.
References
- Architect for AWS Fargate for Amazon ECS - Official ECS Developer Guide overview of AWS Fargate architecture, launch types, and when to choose Fargate over EC2.
- Amazon ECS task definition parameters for Fargate - Reference for all task definition parameters including CPU, memory, network mode, and storage for Fargate tasks.
- Fargate platform versions for Amazon ECS - Explanation of Fargate platform versions, their kernel and runtime combinations, and upgrade considerations.
- Amazon ECS task networking options for Fargate - How awsvpc network mode works with Fargate, ENI allocation, and security group assignment per task.
- AWS Fargate Pricing - Official per-vCPU and per-GB memory pricing for Fargate on ECS and EKS, including Fargate Spot discounts.
- Automatically scale your Amazon ECS service - ECS Service Auto Scaling options including target tracking, step scaling, and scheduled scaling for Fargate workloads.
AWS Fargate Deep Dive Series
Complete guide to AWS Fargate from basics to production. Learn serverless containers, cost optimization, debugging techniques, and Infrastructure-as-Code deployment patterns through real-world experience.
All Posts in This Series
Related posts
Advanced Fargate patterns learned from running production workloads. From cost optimization to stateful containers, here's what the docs won't tell you.
A technical guide to choosing and implementing AWS edge computing for global apps, with practical examples and cost optimization strategies.
A technical guide comparing AWS Secrets Manager and Parameter Store, showing when to use each service with real-world implementation patterns and CDK examples.
Practical approaches to managing Lambda Layer versions across dev, staging, and production with AWS CDK, automated deployment pipelines, and rollbacks.
How to deploy Fargate effectively with different IaC tools. Practical patterns, common gotchas, and what works best for each approach.