Back to Blog
aws
cost-optimization
finops
ec2
s3
savings-plans

AWS Cost Optimization Guide: Practical Strategies That Actually Work

Most teams overspend 20-40% on AWS without realizing it. This guide covers billing visibility, right-sizing EC2, Savings Plans vs Reserved Instances, idle resource cleanup, S3 storage optimization, and a monthly review framework — no dedicated FinOps team required.

Matias Coca|
13 min read
AWS Cost Optimization Guide: Practical Strategies That Actually Work

AWS bills have a way of creeping up. One month you're within budget, the next you're staring at a 30% spike with no clear explanation. The cost breakdown shows hundreds of line items across dozens of services, and the pricing models — on-demand, reserved, savings plans, spot, per-request, per-GB, per-hour — make it genuinely hard to understand where the money goes.

This guide covers practical strategies to reduce AWS spend. No enterprise tooling required. No six-month implementation plan. Just the optimizations that consistently deliver the biggest savings for teams managing cloud costs without a dedicated FinOps team.


Why AWS Costs Get Out of Control

Before jumping into fixes, it helps to understand why AWS bills spiral:

  1. Pricing complexity: AWS has over 300 services, each with its own pricing model. EC2 alone has on-demand, reserved, savings plans, spot, and dedicated host pricing — across hundreds of instance types.
  2. No visibility by default: AWS gives you Cost Explorer for free, but most teams don't configure it properly. Without tags and account structure, you can't answer "which team spent what."
  3. Over-provisioned resources: Teams pick instance sizes based on peak load estimates, then never revisit. The result: 40-60% of compute capacity sits unused.
  4. Idle resources accumulate: That test environment from last quarter, the unattached EBS volumes from terminated instances, the Elastic IPs nobody remembers reserving — they all cost money every hour.
  5. No commitment strategy: You're paying on-demand rates for workloads that run 24/7 and haven't changed in months.
The good news: most teams can reduce AWS spend by 20-40% with the optimizations below.

Step 1: Get Visibility Right

You can't optimize what you can't see. AWS provides several free tools for cost visibility — the trick is knowing which ones matter.

Enable Cost Explorer (if you haven't)

Cost Explorer is free and gives you a visual breakdown of spend over time. It's not enabled by default on all accounts.

Go to Billing → Cost Explorer → Launch Cost Explorer. It takes 24 hours to populate historical data.

What to look for first:

  • Daily cost trend: Is spend stable, growing, or spiking?
  • Top 5 services: Where is most of the money going?
  • Cost by account: If you're using AWS Organizations, which accounts drive spend?

Set Up Cost Allocation Tags

Tags are the foundation of cost attribution. Without them, you know THAT money was spent but not WHERE or BY WHOM.

Recommended tags:

TagPurposeExample
EnvironmentSeparate prod from dev/stagingproduction, staging, dev
TeamAttribute costs to teamsplatform, data, backend
ProjectTrack spend by initiativecustomer-api, ml-pipeline
OwnerAccountabilityjane@company.com
How to activate:
  1. Go to Billing → Cost allocation tags
  2. Activate your user-defined tags (they must already exist on resources)
  3. Wait 24 hours for tags to appear in Cost Explorer
Important: Tags are NOT retroactive. Costs before tag activation won't be categorized. Start tagging now — every month you wait is unattributed data you can't get back.

Enable Cost Anomaly Detection

This is a free AWS feature that uses ML to detect unusual spending patterns and alerts you automatically.

Setup: Billing → Cost Anomaly Detection → Create monitor

Create two monitors:

  • Service monitor: Detects spikes in any AWS service
  • Account monitor: Detects spikes in any linked account (if using Organizations)

Set alert thresholds based on your tolerance — a 20% daily increase is a reasonable starting point for most teams.

This catches the kind of surprises that otherwise show up as a shock on the monthly invoice: a forgotten test cluster, a misconfigured auto-scaling group, or a data transfer spike from a new deployment.


Step 2: Right-Size EC2 Instances

EC2 is typically the #1 line item on AWS bills, and most instances are over-provisioned.

How to Find Oversized Instances

AWS Compute Optimizer (free) analyzes your EC2 usage and recommends better instance types:

  1. Go to Compute Optimizer → EC2 instances
  2. Look for instances flagged as "Over-provisioned"
  3. Review the recommended instance type and projected savings
What to look for:
  • Average CPU under 40% → likely over-provisioned
  • Memory utilization consistently under 50% → consider a smaller instance family
  • Network throughput well below instance limits → you're paying for bandwidth you don't use

Instance Family Selection Matters

Picking the right instance family is often more impactful than just sizing down:

WorkloadCommon MistakeBetter ChoiceSavings
Web serversm5.xlarge (general purpose)c6i.large (compute optimized)40-50%
Databasesr5.2xlarge (oversized memory)r6i.xlarge (right-sized memory)~50%
Batch processingOn-demand m5 instancesSpot c6i instances60-90%
Dev/testSame instance as productiont3/t3a burstable instances50-70%

Graviton Instances: Easy 20% Savings

AWS Graviton (ARM-based) instances are 20% cheaper than equivalent x86 instances and often perform better. If your workload runs on Linux and doesn't require x86-specific binaries:

  • m6g instead of m6i
  • c7g instead of c7i
  • r7g instead of r7i
Most modern applications (Node.js, Python, Java, Go, containers) run on Graviton without modification.

Step 3: Clean Up Idle Resources

Idle resources are the easiest savings — you're paying for things nobody uses. Common culprits on AWS:

Unattached EBS Volumes

When you terminate an EC2 instance, its EBS volumes often survive. They keep costing you money even with no instance attached.

How to find them:

  • EC2 → Volumes → Filter by "State: available"
  • Any volume in "available" state is unattached and costing you money

Typical waste: A single 500GB gp3 volume costs ~$40/month. Ten forgotten volumes = $400/month for nothing.

Before deleting: Snapshot the volume first if you're unsure whether the data is needed. Snapshots cost a fraction of live volumes.

Unused Elastic IPs

An Elastic IP attached to a running instance is free. An unattached Elastic IP costs $3.60/month (since Feb 2024, AWS charges for ALL public IPv4 addresses).

How to find them: EC2 → Elastic IPs → look for IPs with no associated instance.

Idle RDS Instances

Database instances that serve no traffic but run 24/7 are common — dev databases, staging environments, databases from decommissioned projects.

How to find them:

  • CloudWatch → RDS metrics → DatabaseConnections
  • Any instance with near-zero connections for 2+ weeks is a candidate

Options:
  • Stop the instance (up to 7 days, then it auto-starts — set a reminder)
  • Snapshot and delete for instances not needed regularly
  • Use Aurora Serverless v2 for dev/test databases that need to exist but are rarely used

Old Snapshots and AMIs

Snapshots accumulate silently. Every time someone creates a backup "just in case," it persists forever unless explicitly deleted.

How to audit:

  • EC2 → Snapshots → Sort by creation date
  • Look for snapshots older than 90 days
  • Cross-reference with existing volumes — if the source volume is deleted, do you still need the snapshot?


Step 4: Optimize S3 Storage Costs

S3 is deceptively expensive at scale. The per-GB price looks cheap, but costs compound across storage classes, request fees, and data transfer.

Use Lifecycle Policies

Most S3 data follows a predictable access pattern: frequent access for the first 30 days, occasional access for 90 days, then rarely or never again.

Recommended lifecycle policy:

AgeStorage ClassCost (per GB/month)
0-30 daysS3 Standard$0.023
30-90 daysS3 Infrequent Access$0.0125
90-365 daysS3 Glacier Instant Retrieval$0.004
365+ daysS3 Glacier Deep Archive$0.00099
That's a 95% cost reduction from Standard to Deep Archive for data you rarely access.

How to implement: S3 → Bucket → Management → Lifecycle rules

Enable S3 Intelligent-Tiering

If you're unsure about access patterns, S3 Intelligent-Tiering automatically moves objects between tiers based on actual access. It charges a small monitoring fee ($0.0025/1,000 objects) but eliminates manual lifecycle management.

Best for buckets where access patterns are unpredictable or mixed.

Watch for Request Costs

S3 charges per request, not just per GB stored. A bucket serving millions of small-object reads can generate significant request costs even if the storage volume is small.

Common traps:

  • Web assets served directly from S3 without CloudFront → high GET request costs + data transfer
  • Logging buckets with millions of tiny objects → LIST operations become expensive
  • Applications that poll S3 for changes instead of using S3 Event Notifications


Step 5: Savings Plans vs Reserved Instances

If you have predictable workloads running 24/7, you're overpaying on on-demand rates. AWS offers two commitment mechanisms:

Savings Plans are simpler and more flexible than Reserved Instances:

TypeDiscountFlexibility
Compute Savings PlansUp to 66%Any instance family, size, OS, region, or tenancy
EC2 Instance Savings PlansUp to 72%Locked to instance family and region, flexible on size and OS
How to right-size your commitment:
  1. Go to Cost Explorer → Savings Plans → Recommendations
  2. AWS analyzes your last 7/30/60 days of usage
  3. It recommends a specific hourly commitment amount
  4. Start with the 1-year, No Upfront option (lowest risk, still significant savings)
Rule of thumb: Commit to 70-80% of your stable baseline. Let the remaining 20-30% run on-demand to handle variability.

Reserved Instances (Still Useful for Specific Cases)

RIs offer slightly higher discounts than Savings Plans for specific instance types but are less flexible:

  • Standard RIs: Up to 72% savings, locked to specific instance type and region
  • Convertible RIs: Up to 66% savings, can change instance family
When RIs still make sense:
  • RDS databases (Savings Plans don't cover RDS)
  • ElastiCache instances (same reason)
  • OpenSearch/Elasticsearch instances
  • Redshift clusters

The Math That Matters

For a team spending $10,000/month on EC2:

StrategyMonthly CostAnnual Savings
All on-demand$10,000$0
Compute Savings Plan (70% coverage, 1yr)$7,200$33,600
EC2 Instance Savings Plan (70% coverage, 1yr)$6,800$38,400
Compute Savings Plan (70%, 3yr, all upfront)$5,500$54,000
Even the most conservative option (1-year Compute Savings Plan) saves over $33K/year.

Step 6: Leverage Spot Instances for Fault-Tolerant Workloads

Spot instances offer 60-90% savings over on-demand but can be interrupted with 2 minutes' notice. They're ideal for:

  • Batch processing: Data pipelines, ETL jobs, image processing
  • CI/CD: Build and test runners
  • Stateless web servers: Behind a load balancer with auto-scaling
  • Machine learning training: Checkpoint-enabled training jobs
How to use Spot safely:
  • Use mixed instance policies in Auto Scaling groups (combine on-demand + spot)
  • Diversify across multiple instance types and Availability Zones
  • Implement graceful shutdown handling for the 2-minute interruption notice
  • Use Spot Fleet or EC2 Fleet for automatic capacity management
What Spot is NOT good for:
  • Databases
  • Single-instance applications
  • Workloads that can't tolerate interruptions
  • Long-running jobs without checkpointing

Step 7: Network and Data Transfer Costs

Data transfer is the "hidden tax" on AWS bills. Ingress is free, but everything else costs money:

Transfer TypeCost
Internet egress (first 10 TB)$0.09/GB
Cross-region transfer$0.01-0.02/GB
Cross-AZ transfer$0.01/GB each way
Same-AZ transfer (private IP)Free
To CloudFrontReduced rates

Quick Wins for Network Costs

  1. Use VPC endpoints for S3 and DynamoDB — eliminates NAT Gateway data processing charges ($0.045/GB)
  2. Keep services in the same AZ when possible — cross-AZ transfer adds up fast with microservices
  3. Use CloudFront for content delivery — cheaper egress rates than direct S3/EC2
  4. Compress responses — gzip/brotli compression reduces transfer volume by 70-80%
  5. Review NAT Gateway costs — they charge per GB processed, which surprises teams running large data transfers through private subnets

Monthly Cost Review Framework

Run this process monthly to catch waste before it accumulates:

Week 1: Quick Review (30 minutes)

  • [ ] Check Cost Explorer for spending trends and anomalies
  • [ ] Review Cost Anomaly Detection alerts from the past month
  • [ ] Compare spend to previous month — investigate any increase over 10%

Week 2: Resource Audit (1 hour)

  • [ ] Check Compute Optimizer for oversized EC2 instances
  • [ ] List unattached EBS volumes and unused Elastic IPs
  • [ ] Review RDS instances with near-zero connections
  • [ ] Audit snapshots and AMIs older than 90 days

Week 3: Optimization Actions (2 hours)

  • [ ] Right-size the top 5 oversized instances
  • [ ] Delete confirmed idle resources (snapshot first if uncertain)
  • [ ] Apply or update S3 lifecycle policies on large buckets
  • [ ] Review and apply Savings Plan recommendations

Week 4: Planning (30 minutes)

  • [ ] Review Savings Plan utilization — are you under-committed or over-committed?
  • [ ] Check for new services or workloads that should be tagged
  • [ ] Plan next month's optimization focus

Common Mistakes to Avoid

  1. Buying commitments too early: Don't purchase Savings Plans or RIs until you have 2-3 months of stable usage data. Premature commitments lock you into resources you might not need.
  1. Ignoring data transfer costs: Teams optimize compute and storage but ignore the $0.09/GB egress charges that quietly become a top-5 line item.
  1. Over-committing on Reserved Instances: RIs for instances that get replaced, resized, or decommissioned within the commitment period are wasted money. When in doubt, use Savings Plans instead.
  1. Forgetting about dev/test environments: Production gets all the optimization attention while dev and staging environments run the same instance sizes 24/7. Schedule dev environments to stop outside business hours — that alone saves 65%.
  1. Not tagging from day one: Retroactive tagging is painful and incomplete. Make tagging part of your infrastructure-as-code templates from the start.
  1. Treating Spot as unreliable: Spot interruption rates are low for diversified instance type selections. Teams that dismiss Spot leave 60-90% savings on the table for workloads that would handle it fine.

Getting Started

  1. Today: Enable Cost Explorer and Cost Anomaly Detection (5 minutes)
  2. This week: Activate cost allocation tags, audit unattached EBS volumes and unused Elastic IPs
  3. This month: Right-size top 10 oversized instances, set up S3 lifecycle policies
  4. Next month: Evaluate Savings Plans based on 30-day usage data
You don't need a FinOps team or enterprise tools to control AWS costs. Start with visibility, clean up the obvious waste, and build a monthly review habit. The savings compound.

Struggling with AWS costs across multiple accounts and services? Brain Agents AI helps teams optimize cloud spend across GCP, AWS, and Azure — without enterprise complexity or a dedicated FinOps team.


Related Articles:

Written by Matias Coca

Building AI agents for cloud cost optimization. Questions or feedback? Let's connect.

Ready to optimize your cloud costs?

Deploy AI agents that continuously find savings across your cloud infrastructure.