Fargate is the default answer in a lot of architecture reviews. No AMIs. No capacity providers. No "who patched the node." You define CPU and memory, ship a task, and AWS runs it.
That is the right product for a lot of work. It is the wrong product for a lot of always-on work. The bill makes that clear after a few months of steady 24/7 traffic.
This is the same cost habit that shows up with NAT Gateways and other managed conveniences: you pay a premium for not owning a box. The premium is fine when utilization is lumpy. It is expensive when utilization is flat.
What you are actually buying
| Model | You pay for | You own |
|---|---|---|
| Fargate | vCPU-hour + GB-hour for every running task | Task definition, networking, IAM, logging |
| ECS on EC2 | The instance (On-Demand, Spot, or Savings Plan) | Capacity, packing, AMI/OS, more failure modes |
| Raw EC2 + Docker/systemd | The instance | Almost everything |
Fargate prices the reserved slice of each task. If a task asks for 1 vCPU and uses 15% of a core most of the night, you still pay for 1 vCPU all night. On EC2, that idle headroom can be shared with other tasks on the same host, or you right-size the host down.
AWS has published this for years in their own ECS cost write-ups: at low packing density, Fargate can look cheaper than a half-empty EC2. At high, steady utilization, EC2 usually wins on pure compute dollars.
Rough monthly math (us-east-1, order of magnitude)
Numbers move with Savings Plans and region. Use these as a shape, not a quote.
| Workload | Fargate (always on) | Close EC2 equivalent | Notes |
|---|---|---|---|
| 0.5 vCPU / 1 GB, 1 task | ~$18/month | t3.micro / t4g.micro class |
Fargate still wins on ops simplicity for one tiny service |
| 1 vCPU / 2 GB, 2 tasks (HA) | ~$70/month | One small multi-vCPU host or two micros | Break-even depends on how hard you pack |
| 2 vCPU / 4 GB, 4 tasks | ~$280/month | t3.large / m7i-class packing |
EC2 starts to pull ahead if hosts stay busy |
| 4 vCPU / 16 GB, steady fleet | Hundreds+/month | m7i.xlarge + friends |
Steady state + 1-year commitments favor EC2 harder |
Rules of thumb that hold up in practice:
- One small always-on API with rare deploys: Fargate is often worth the tax.
- A fleet of workers and APIs that run all day, every day: pack them on ECS/EC2 or EKS nodes and buy a Compute Savings Plan.
- Spiky batch (train jobs, nightly ETL, preview envs): Fargate or Fargate Spot keeps you from paying for idle metal.
If your average CPU on Fargate tasks sits under ~30% for months, you are not "efficient." You are renting reserved capacity you do not use, at a higher unit price than EC2.
Ops is the real second price
Pure dollars are only half the decision.
Fargate wins when:
- You do not want a node upgrade story
- Teams ship many small services and hate capacity planning
- Scale-to-zero or near-zero matters (combined with good min task counts)
- Compliance is easier when AWS owns the runtime host
EC2 (with ECS or EKS) wins when:
- You already run a platform team that patches and monitors nodes
- You need DaemonSets, custom kernel modules, or host-level agents that Fargate blocks or complicates
- GPU, high network throughput, or dense bin-packing matters
- You can keep bin packing high enough that the Fargate premium is pure waste
The trap is pretending you have a platform team when you do not. A poorly run EC2 cluster is more expensive than Fargate once you count pages, failed deploys, and "why is the disk full" weekends.
A simple decision path
Is the service idle most of the day or highly bursty?
yes -> Fargate (or Lambda if the runtime fits)
no -> continue
Do you already operate container nodes well?
no -> stay on Fargate until the monthly bill hurts more than hiring ops time
yes -> model EC2 with real packing %
Can you keep average host utilization healthy (roughly >50-60% of what you pay for)?
yes -> ECS on EC2 or EKS with Savings Plans
no -> Fargate is still cheaper than empty instances
Measure packing with real metrics: CPU, memory, and network (people forget network). Right-size task reservations before you migrate. Moving an over-reserved Fargate task onto EC2 without fixing requests/limits just moves waste to a different line item.
Migration pattern that does not blow up prod
If you are already on Fargate and the bill hurts:
- Export 30 days of CloudWatch for CPU, memory, and task count. Find the floor, not the peak marketing slide.
- Cut task CPU/memory where headroom is fantasy. Many teams discover 50% of the Fargate bill is over-reservation, not Fargate itself.
- Pick one service that is always on and boring (internal API, queue worker). Move that first.
- Run dual capacity briefly: Fargate service + EC2 capacity provider, shift traffic with weight or a feature flag.
- Buy commitment only after the shape stabilizes. Savings Plans on the wrong size are a second tax.
Also check the rest of the bill while you are there. It is common to "optimize compute" and still bleed on NAT data processing, multi-AZ idle load balancers, and verbose logging. Compute is rarely the only idle tax.
Bottom line
Fargate is not a scam. It is a convenience premium. Pay it for bursty work, small teams, and services where host management is the real risk.
For always-on fleets with predictable floors, EC2 capacity (ECS or EKS) plus honest packing and a Savings Plan is usually the adult move. Do the math on your reservation rates and your ops cost, not a conference slide that assumes perfect bin packing or zero engineer time.
If your January cloud bill already feels like a hangover, start with one always-on service, thirty days of metrics, and a spreadsheet. The architecture review can wait until the numbers are boring.
