Skip to content
Urnish Tech logo
Back to blog
AWSDevOpsFinOps

Cutting AWS Bills 40%: ECS Fargate Cost Patterns That Worked

Urnish Tech·Mar 28, 2026· 11 min read

Right-sizing tasks, capacity providers, savings plans, and image slimming - the playbook we use across client clusters.

Most ECS Fargate bills can be cut 30-50% without hurting performance. The pattern is consistent across the engagements we have run: teams provision conservatively for peak, never revisit, and pay for headroom they never use. The fix is methodical right-sizing, capacity-provider design, and a few hygiene practices most operators skip. Done together, our typical FinOps engagement returns 6-9 months of savings within the first quarter.

1. Right-size against actuals, not specs

Pull 30 days of CloudWatch Container Insights data and compute the P95 utilization per task definition. Most teams discover their tasks run at 15-25% CPU and 30-40% memory - meaning they over-provisioned by 3-4x. Adjust task sizes to P95 + 20% buffer. The savings are immediate and require no architectural change; only redeployment with new task definition revisions. This single step typically delivers 10-15% reduction.

2. Adopt Fargate Spot for stateless workloads

For stateless workloads with retry logic - most web tier and async workers - Fargate Spot delivers 70% off on-demand pricing with the trade-off that AWS can reclaim instances with two minutes notice. ECS handles graceful task replacement transparently when you configure capacity providers correctly. Mixed strategies work too: 70% Spot for normal load, 30% on-demand for guaranteed minimum capacity, with autoscaling rules favoring Spot for new tasks.

3. Slim container images aggressively

Container image size hits both bandwidth and cold-start time. Most Node.js images we audit weigh 800MB to 1.2GB; we routinely cut them to 200-300MB through multi-stage builds and Alpine base images. The recipe:

  1. 1Build stage uses full Node image with build tools
  2. 2Runtime stage uses node:20-alpine, copies only production node_modules and built artifacts
  3. 3Add a strict .dockerignore to keep tests, docs, and dev dependencies out
  4. 4Use distroless images for static binaries (Go, Rust) - even smaller

Cold starts drop, ECR storage costs drop, deploy times drop. The wins compound across every service.

4. Compute Savings Plans for the floor

Compute Savings Plans are the structural lever once your usage stabilizes. After 60-90 days of steady-state, baseline your minimum compute commitment - the floor below which you never go - and buy a 1-year No Upfront Savings Plan for that amount at ~30% off. The plan covers Fargate, EC2, and Lambda, so it is forgiving if you migrate workloads. Match the commitment to your floor, not your average; over-committing hurts more than missing savings.

5. Consolidate Application Load Balancers

Each ALB costs around $25/month plus per-LCU charges. Teams often spin up one ALB per service in development - which adds up fast. Consolidate using path-based or host-based routing rules: a single ALB can front 50+ services with target groups switched by Host header or path prefix. We routinely cut LB spend 70% via consolidation alone.

6. Tag everything, then watch the dashboards

Cost-allocation tagging is the foundation for everything else. Tag every task definition, ALB, RDS instance, and S3 bucket with env, service, team, and cost-center. Activate the tags in Cost Explorer (Billing console > Cost allocation tags) and you can slice spend per service per environment in minutes. Without this, FinOps reviews are guesswork; with it, you know exactly which service is driving the curve.

7. Tame CloudWatch Logs and NAT Gateway

CloudWatch Logs costs surprise teams more than any other line item. Default log retention is "Never expire" and DEBUG-level logs in production cluster aggregate to terabytes monthly. Set explicit retention (7-30 days for app logs, 90 days for audit logs) and ship to S3 + Athena for long-term query if needed. Filter at the source - structured logging libraries can drop low-value log lines before they hit CloudWatch entirely.

NAT Gateway charges sneak up. At $0.045/hour plus $0.045/GB, a single NAT Gateway costs ~$33/month idle and balloons fast under traffic. Use VPC endpoints (Gateway endpoints for S3/DynamoDB are free; Interface endpoints are cheap) to keep traffic on the AWS backbone. Audit which AWS services your tasks call from private subnets - half the NAT cost typically goes to S3/DynamoDB calls that should be on Gateway endpoints.

We deploy these patterns across production engagements in fintech, healthcare, and eCommerce. Talk to a senior engineer about how they apply to your platform.

Let's talk

Have a product idea or a system to scale?

Tell us what you're building. You'll hear back within one business day - from a senior engineer, not a sales rep.

  • Free 30-min discovery call
  • Fixed-scope or T&M engagements
  • NDA on request - first reply within 24h