2025-09-04
AWS Fargate 101: When Your Containers Don't Need a Babysitter
A practical guide to AWS Fargate from someone who's managed too many EC2 instances. Learn when serverless containers make sense and when they don't.
There is a gradual realization many teams reach: more time goes into babysitting EC2 instances than building features. It often surfaces during a routine infrastructure review, troubleshooting disk space issues on a production server yet again, when the role has quietly shifted to expensive Linux system administration.
That’s the point where AWS Fargate starts to look appealing.
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 that started last week), 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 (How It Actually Works)
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.
Getting Started With Your First Deployment
Here is a practical Fargate deployment. ECS is a good choice for initial experiments because it’s more straightforward than EKS when you’re learning. Unless you have specific Kubernetes requirements, ECS might be a 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",
"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"
}
}
}
]
}
One thing that caught me off guard initially: the CPU and memory values aren’t 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
One important aspect of Fargate is that it only supports awsvpc network mode. This means each task gets its own elastic network interface (ENI) with a private IP address. While this provides good security isolation, it does require some VPC 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"
}
}
When to Consider Using Fargate
For workloads running on both Fargate and EC2, here’s a useful way to frame the decision:
Fargate tends to work well when:
- You have unpredictable or spiky traffic patterns
- Your team prefers focusing on application code over infrastructure management
- You’re running multiple small, isolated services
- You need strong workload isolation for compliance reasons
- You’re comfortable with containerized thinking
EC2 might be a better fit when:
- You need GPU instances (Fargate doesn’t support them yet)
- You’re running Windows containers with specific requirements
- Cost optimization is a primary concern and you have predictable, high utilization
- You need privileged containers or custom kernel modules
- You want to leverage Spot instances for cost savings
Cost Considerations
To be upfront about pricing: Fargate does cost more per unit of compute than EC2. Here’s a typical comparison from analyzing a real service:
# EC2 (t3.medium, 2 vCPU, 4GB RAM)
Monthly: ~$30 (On-Demand)
Monthly: ~$19 (Reserved Instance)
# Fargate (2 vCPU, 4GB RAM)
Monthly: ~$75 (24/7 usage)
Monthly: ~$52 (with Savings Plans)
Monthly: ~$23 (with Fargate Spot - up to 70% savings)
Note: AWS pricing varies by region and changes over time. These are approximate costs 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 EC2 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
For many teams, the additional cost is worthwhile to reduce operational burden.
Things That Surprised Me
-
Cold Start Delays: The first task launch in a new availability zone can take 30-60 seconds. Worth planning for if you have strict latency requirements.
-
ENI Limitations: Each Fargate task requires an ENI. When you hit your VPC’s ENI limit, tasks simply won’t launch. This tends to bite during a particularly 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" -
Ephemeral Storage Only: Tasks get 20GB of ephemeral storage. Need more? Use EFS, but expect slower I/O.
-
Platform Versions: Fargate has platform versions (1.4.0, 1.3.0, etc.). AWS updates these automatically, which is usually fine, but occasionally breaks things. Always test in staging first.
A Real Production Setup
Here’s a pattern that’s served us well in production:
The key insights from running this in production:
- 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
Fargate isn’t a silver bullet, and it won’t be the right choice for every situation. But for teams that want to run containers without diving deep into infrastructure management, it can be a reasonable option. The cost premium compared to EC2 is real, but the operational simplicity might be worth it.
A sensible default: start with Fargate for new containerized workloads. If AWS costs become a significant concern, that’s usually a good problem to have; it means you have enough scale to justify the engineering investment in more complex infrastructure optimization.
Hopefully your containers stay stateless and your deployments stay smooth.
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 comprehensive technical guide to choosing and implementing AWS edge computing solutions for global applications with practical examples and cost optimization strategies.
A comprehensive technical guide comparing AWS Secrets Manager and Systems Manager Parameter Store, demonstrating when to use each service with real-world implementation patterns.
Practical approaches to managing Lambda Layer versions across dev, staging, and production environments with AWS CDK, including automated deployment pipelines and rollback strategies.
How to deploy Fargate effectively with different IaC tools. Practical patterns, common gotchas, and what works best for each approach.