DEV Community

Slawa Pidgorny
Slawa Pidgorny

Posted on

Your Fargate Tasks Are Probably Bigger Than They Need to Be

How to detect over-provisioned ECS/Fargate services and right-size them to actual load

AWS Fargate made it easy to stop thinking about servers. It also made it easy to stop thinking about task sizing.

Most teams pick a CPU/memory combination once — often copied from a template, a tutorial, or "what worked last time" — and never revisit it. Traffic patterns change, code gets optimized, dependencies get swapped, but the task definition stays the same. Six months later, a service that peaks at 15% CPU is still provisioned as if it were about to get hammered.

That gap between allocated and actual resource use is one of the most common (and most fixable) sources of waste on AWS.

Why Fargate over-provisioning is so easy to miss

A few things make this specific waste pattern sneaky:

  • Billing is per-task, not per-utilization. You pay for the vCPU and memory you reserved, whether the task uses 5% or 95% of it. The bill doesn't nudge you to look.
  • Nothing fails when a task is oversized. Unlike a memory leak or an outage, over-provisioning has no symptom. The service just quietly runs fine — at 3x the cost it needs.
  • CloudWatch has the answer, but no one's watching it. CPUUtilization and MemoryUtilization per ECS service are recorded by default. Almost nobody builds a habit of reviewing 30-day averages across every service in every cluster.
  • Empty clusters accumulate too. Test clusters, deprecated environments, and abandoned proofs-of-concept often keep existing with zero running tasks, adding clutter and occasional accidental cost.

A practical way to detect it

You don't need a full FinOps platform to find this. The core signal is straightforward:

  1. List every ECS cluster and service in the account and region you care about.
  2. Pull 30-day average CPU and memory utilization per service from CloudWatch (GetMetricStatistics, Period: 86400 for daily granularity, Statistics: Average).
  3. Flag services where both CPU and memory averages sit below ~30%. A single low spike day isn't a signal — a sustained 30-day average is.
  4. Estimate the achievable savings conservatively. Don't assume you can cut a service down to exactly its average usage — leave headroom for spikes. A reasonable rule of thumb: take the larger of the CPU or memory waste ratio, apply a 50% haircut for safety margin, and multiply that against the service's current Fargate cost (vCPU price + memory price × 730 hours/month).
  5. Cross-check desiredCount vs runningCount. If a service consistently wants more tasks than it can get running, that's a different problem (constrained capacity or a stuck deployment) worth investigating separately from right-sizing.
  6. Look for clusters with zero running tasks and zero active services. These are candidates for deletion, not right-sizing — but always back up the cluster config first (aws ecs describe-clusters output saved to a file) before deleting anything.

What to do once you've found one

Right-sizing a Fargate task is low-risk compared to most cost optimizations, because you can revert instantly if you get it wrong:

  • Pick the next tier down in vCPU/memory that still comfortably covers your 30-day peak, not just the average.
  • Deploy the change to a canary or a percentage of tasks first if your deployment tooling supports it.
  • Re-check CPUUtilization/MemoryUtilization a week later. If the new allocation still sits comfortably below 70-80% at peak, you're done. If you see throttling or OOM-kills, step back up one tier.
  • Repeat quarterly — traffic and code both drift over time, so a service sized correctly today may not be next year.

The pattern above (CPU/memory averages below 30% over 30 days, checked per service rather than per cluster) is deliberately conservative. It's meant to surface real candidates for review, not to declare every quiet service "wrong." Some services are supposed to run cool — that's headroom for traffic spikes, not waste. Use judgment before resizing anything customer-facing.

Checking this by hand doesn't scale

Doing this manually for one or two clusters is a reasonable afternoon project. Doing it for every cluster, every service, across every region and account your company runs — while also checking EC2, RDS, Lambda, S3, EBS snapshots, and the rest of the surface area where waste hides — is a different problem entirely.

That's exactly the check GreenOps Scan automates. It's a free, read-only CLI that runs the same kind of 30-day CloudWatch analysis described above across ECS/Fargate, along with idle EC2 instances, unused EBS snapshots, S3 buckets without lifecycle policies, underused RDS instances, stale Lambda functions, and more — in one pass, with cost and CO2 estimates attached to each finding.

Run it against a read-only IAM role:

npx greenops-scan
Enter fullscreen mode Exit fullscreen mode

It won't touch anything in your account. Every finding comes with the specific resource, the issue, an estimated monthly cost and carbon impact, and a remediation command or recommendation you can review before acting on it. If your Fargate services are quietly over-provisioned, it'll be near the top of the list.

Learn more about GreenOps Scan →

Top comments (0)