15 AWS Cost Savings to Check in Every Audit
A 15-point AWS cost audit checklist: idle and oversized resources, NAT gateway waste, S3 lifecycle gaps, IPv4 charges, and how to find each one.
About 29% of public-cloud spend is wasted, according to Flexera's 2026 State of the Cloud report. On AWS, most of that waste sits in the same fifteen places, and you can check every one of them with native tools.
Not because engineers are careless. Because AWS pricing is genuinely complicated, accounts accumulate technical debt, and cost visibility degrades over time. A $50 instance that made sense 18 months ago is still running because nobody thought to check. A NAT gateway is routing traffic that could move through a VPC endpoint for free. A gp2 volume attached to a stopped instance charges the same per gigabyte whether it's in active use or sitting idle.
This post is a checklist: the 15 items to check in an AWS cost audit, with typical savings, the tools that surface them, and what remediation looks like. Everything here is actionable with native AWS tooling. If you'd rather start with the five habits that cause most of this waste in the first place, read 5 AWS cost mistakes SMBs make.
Before You Start: Your Baseline Tools
Two tools give you most of the visibility you need before touching anything:
AWS Cost Explorer — built-in, free. Sorts spend by service, region, resource tag, and linked account. Surfaces the largest spend buckets and month-over-month trends. Start here for every audit.
AWS Compute Optimizer — free. Analyzes EC2, ECS, Lambda, and EBS metrics against actual utilization, then issues right-sizing recommendations. Connects to Cost Explorer to translate recommendations into dollar impact.
Trusted Advisor — the full set of cost optimization checks needs a Business-level or higher support plan. Covers low-utilization EC2, idle RDS, underutilized EBS volumes, and unassociated Elastic IPs.
For catching cost changes before they ship, Infracost adds a cost estimate to Terraform pull requests.
The 15 Findings
1. Idle EC2 Instances
Typical savings: $200–$4,000/month per environment
Instances that have been running for months with CPU utilization consistently under 5% and near-zero network I/O. Common causes: dev/test environments that never get torn down, staging servers that outlasted the feature they were staging, and forgotten proof-of-concept deployments.
AWS Compute Optimizer flags these automatically. The fix is either terminating the instance (after confirming with the owner) or snapshotting the EBS volume and stopping it. Stopped instances do not incur instance-hour charges—only EBS storage charges, which are typically 80–90% cheaper.
How to find: Compute Optimizer → Idle resources, which flags EC2 instances with very low CPU and network use. Trusted Advisor's low-utilization check covers the same ground if you have a Business-level support plan.
2. Oversized EC2 Instance Types
Typical savings: 30–50% of EC2 line item
The most common pattern: an application was deployed on an m5.2xlarge because the engineer estimated headroom, it turned out not to need it, and nobody revisited the sizing. Compute Optimizer will show you the P99 CPU and memory utilization and recommend the smallest instance type that accommodates actual peak load with headroom.
A move from m5.2xlarge ($0.384/hr) to m5.large ($0.096/hr) for a single instance saves $2,100 per year. Multiply across a typical environment with 20–50 EC2 instances, and right-sizing is usually the single largest lever in an audit.
| Instance Type | Hourly Rate | Annual Cost |
|---|---|---|
| m5.2xlarge | $0.384 | $3,363 |
| m5.xlarge | $0.192 | $1,682 |
| m5.large | $0.096 | $841 |
| m5.medium | $0.048 | $420 |
How to find: AWS Compute Optimizer → EC2 instances → filter for "Over-provisioned" findings.
3. Missing Reserved Instances or Savings Plans
Typical savings: 30–60% on covered compute
Reserved Instances (RIs) and Compute Savings Plans are the highest-leverage cost control available on AWS—and the most consistently underused by teams that haven't made a deliberate commitment to FinOps.
If you have workloads with predictable, steady-state compute requirements (production APIs, data pipelines, always-on services), paying on-demand rates leaves money on the table. AWS advertises savings of up to 66% for Compute Savings Plans and up to 72% for EC2 Instance Savings Plans; one-year, no-upfront plans land at the low end of that range and three-year commitments at the high end.
A company running $20,000/month in on-demand EC2 for predictable workloads saves $5,000–$6,000 per month even at a 25–30% discount.
How to find: AWS Cost Explorer → Savings Plans → Recommendations. Look for coverage below 70% on stable services.
4. NAT Gateway Data Processing Charges
Typical savings: $500–$5,000/month
NAT gateways charge $0.045 per GB of data processed—in addition to the $0.045/hr per-AZ hourly charge (us-east-1 rates). In environments with high-volume egress traffic (log shipping, S3 backups, API calls to external services), this adds up fast, and processing fees can exceed the cost of the underlying EC2 instances.
The primary fix: move AWS service traffic to VPC endpoints, which bypass the NAT gateway entirely. S3 and DynamoDB gateway endpoints are free. Interface endpoints for other services (ECR, Secrets Manager, SSM) cost $0.01/hr per AZ plus $0.01/GB—usually cheaper than equivalent NAT gateway processing fees for those services.
A second fix: ensure traffic between resources in the same VPC routes internally rather than hairpinning through the NAT gateway. Misconfigured routing tables are a common cause.
How to find: Cost Explorer → VPC service → filter for NatGateway. If NAT gateway data processing exceeds $200/month, a routing audit is warranted.
5. Unattached EBS Volumes
Typical savings: $50–$500/month
When an EC2 instance is terminated, the default behavior depends on how the volume was created. Volumes created separately and attached to an instance persist after termination. Over time, environments accumulate detached volumes that haven't been accessed in months.
gp3 volumes cost $0.08/GB/month. A 500GB volume left detached costs $40/month indefinitely. A typical environment has between 5 and 30 orphaned volumes. Quick fix: snapshot and delete.
How to find: EC2 console → Volumes → filter for "Available" state. Trusted Advisor also surfaces this under Cost Optimization.
6. gp2 vs gp3 Volume Migrations
Typical savings: 20% of EBS costs, no performance loss
gp3 is AWS's current-generation general-purpose SSD volume type. It's 20% cheaper than gp2 per GB and usually faster for small volumes: every gp3 volume gets a 3,000 IOPS baseline regardless of size, while gp2 gets 3 IOPS per GB (a 500 GB gp2 volume has a 1,500 IOPS baseline). Migrating from gp2 to gp3 requires zero downtime and no data movement—it's a volume type change.
Despite this, older AWS environments often still run significant EBS capacity on gp2. An account with $8,000/month in gp2 volumes would pay about $6,400/month on gp3, often with a one-line Terraform change per volume.
How to find: EC2 console → Volumes → filter Type = gp2. Count the capacity and multiply by $0.016/GB to get the savings from switching to gp3 (which costs $0.08/GB vs $0.10/GB for gp2).
7. S3 Missing Lifecycle Policies
Typical savings: $300–$3,000/month
S3 Standard storage costs $0.023/GB/month. S3 Standard-IA costs $0.0125/GB/month. S3 Glacier Instant Retrieval costs $0.004/GB/month. S3 Glacier Deep Archive costs $0.00099/GB/month.
Data that was uploaded to Standard and never accessed again is incurring Standard pricing indefinitely. Common offenders: application logs, CloudTrail logs, archived database backups, old deployment artifacts, and infrequently accessed data lakes.
Lifecycle policies automate the tier transition. A typical policy: transition to Standard-IA after 30 days, Glacier Instant after 90 days, Deep Archive after 365 days, and delete after a defined retention window. A 10TB log archive on Standard ($230/month) drops to under $10/month on Deep Archive.
How to find: S3 Storage Lens → filter for buckets with zero lifecycle rules and large size. Cost Explorer → S3 → filter for "StandardStorage" class vs total spend.
8. RDS Instances Running Without Load
Typical savings: $200–$2,000/month
RDS instances charge by the hour whether they have active connections or not. Staging databases, QA environments, and development databases that run 24/7 but are only accessed during business hours are common candidates for scheduled stop/start automation.
Running a non-production database only 10 hours a day on weekdays (50 of 168 hours a week) cuts its instance-hour charges by about 70%. Storage is still billed while the instance is stopped.
Two caveats: a stopped RDS instance restarts automatically after seven days, so your schedule has to stop it again; and Aurora Serverless v2 can now scale to zero and pause when idle, resuming when a connection arrives, which suits intermittent dev and test databases.
How to find: RDS → Enhanced Monitoring → look for instances with zero connections during off-hours for 30+ days. AWS Instance Scheduler can automate stop/start.
9. Public IPv4 Addresses and Unused Elastic IPs
Typical savings: $3.60/month per address removed
Since February 1, 2024, AWS charges $0.005/hour for every public IPv4 address, whether it's attached to a running instance or sitting unassociated. That's about $3.60 a month per address. Unassociated Elastic IPs are pure waste, and instances or load balancers that don't need a public address are paying for one anyway.
The fix: release Elastic IPs that aren't in use, and move instances that don't need direct inbound traffic behind a load balancer or into private subnets.
How to find: EC2 console → Elastic IPs → filter for "Not associated." VPC IP Address Manager's Public IP Insights shows every public IPv4 address in the account.
10. CloudWatch Log Group Retention Not Set
Typical savings: $100–$800/month
CloudWatch Logs storage costs $0.03/GB/month. By default, log group retention is set to "Never expire." Without retention policies, logs accumulate indefinitely. A high-volume application writing 10GB/day of logs with no retention policy is storing 300GB of logs per month—indefinitely. After 12 months, that's 3.6TB at $108/month, just for logs you probably don't need after 30 days.
Setting 30-day retention on non-compliance log groups is a five-minute change with immediate impact on the next billing cycle.
How to find: CloudWatch → Log Groups → filter for "Never expire" retention. AWS Config rule cw-loggroup-retention-policy-check will flag this automatically.
11. Lambda Functions Over-Provisioned for Memory
Typical savings: 20–40% of Lambda costs
Lambda pricing is calculated on GB-seconds: (memory allocated in GB) × (execution duration in seconds). A function allocated 1024MB that consistently uses 128MB is paying 8x what it needs to pay on the memory dimension.
AWS Lambda Power Tuning (an open-source tool deployed as a Step Functions state machine) runs your function at different memory configurations and reports the cost-per-invocation. Most functions land at 50–70% of their originally allocated memory. For high-volume Lambda workloads—event processing, API backends, ETL jobs—this is a meaningful reduction.
How to find: Lambda → filter by invocation count → cross-reference with CloudWatch Insights for max_memory_used vs memory_size. AWS Compute Optimizer also covers Lambda functions.
12. Data Transfer: Same-Region Cross-AZ Traffic
Typical savings: $200–$2,000/month
AWS charges $0.01/GB for traffic that crosses Availability Zone boundaries within a region—in both directions. This is widely understood but consistently underestimated. A microservices architecture with 10 services each calling 3 others, running across 3 AZs, can generate hundreds of GB per day in cross-AZ traffic.
The fix isn't always architectural—sometimes it's adding topology-aware routing to Kubernetes services or load balancer target groups to prefer same-AZ traffic. The Kubernetes cost optimization guide covers the cluster-side levers. For services where latency tolerance allows, deploying a cache layer that serves cross-AZ requests eliminates the traffic at the source.
How to find: Cost Explorer → EC2-Other service → filter for DataTransfer-Regional. VPC Flow Logs + Athena queries can identify the specific service pairs generating the traffic.
13. Idle Load Balancers
Typical savings: $20–$200/month per LB
ALBs and NLBs charge an hourly fee ($0.0225/hr in us-east-1) plus a capacity unit charge based on traffic. An idle load balancer still costs about $16/month in hourly charges, plus its public IPv4 addresses—small per unit, but environments accumulate idle load balancers from deprecated services, abandoned feature branches, and migrated applications.
How to find: EC2 → Load Balancers → sort by "Active Flow Count" (NLB) or "RequestCount" (ALB). Look for zero or near-zero traffic over 30+ days. Trusted Advisor surfaces idle load balancers.
14. Oversized RDS Instance Types
Typical savings: 30–50% of RDS line item
RDS instance right-sizing follows the same logic as EC2 right-sizing but is often neglected because database sizing feels riskier to change. Compute Optimizer analyzes RDS instance metrics and issues recommendations—with the same "Over-provisioned" flag it uses for EC2.
A db.r5.2xlarge running at 15% CPU with 8GB of active memory usage should be a db.r5.large. The move saves $1,500–$2,500/year per instance. For environments running 5+ RDS instances, this is consistently a five-figure annual finding.
How to find: AWS Compute Optimizer → RDS instances → filter for "Over-provisioned."
15. ECR Images Never Cleaned Up
Typical savings: $50–$400/month
Amazon ECR charges $0.10/GB/month for private image storage. Container registries accumulate images aggressively: every CI build pushes a new image, tags pile up, and without a lifecycle policy, every image from the past two years is still in the registry. A registry with 500GB of accumulated images costs $50/month—for artifacts that are never pulled.
ECR lifecycle policies let you expire untagged images after N days and retain only the last N tagged images per repository. Setting expire untagged images after 7 days and keep last 10 tagged images reduces most registries to 10–20GB within a week.
How to find: ECR console → Repositories → check "Repository size" column. Any repository over 5GB without a lifecycle policy is worth reviewing.
Typical Total Savings by Environment Size
These are rough planning ranges, not an industry benchmark; Flexera's 29% average is the better-sourced reference point.
| Monthly AWS Spend | Typical Waste % | Recoverable Savings |
|---|---|---|
| $5,000–$15,000 | 25–35% | $1,250–$5,250/month |
| $15,000–$50,000 | 20–30% | $3,000–$15,000/month |
| $50,000–$150,000 | 18–25% | $9,000–$37,500/month |
| $150,000+ | 15–22% | $22,500–$33,000+/month |
The percentage decreases as spend increases because larger teams tend to have more FinOps maturity. But the absolute dollars at stake grow—and the items with the largest line-item impact (Savings Plans, right-sizing, NAT gateway routing) scale proportionally with spend.
Running This Audit Yourself
A DIY audit using native AWS tooling can surface most of these findings:
- Cost Explorer — identify largest service line items and month-over-month trends
- Compute Optimizer — pull EC2, EBS, RDS, and Lambda right-sizing recommendations
- Trusted Advisor — run the Cost Optimization category checks
- S3 Storage Lens — review bucket-level storage class and lifecycle policy coverage
- CloudWatch Logs — export a list of log groups sorted by stored bytes with no retention policy
Allow 8–12 hours for a thorough first pass on a mid-size environment. The primary time investment is triaging recommendations—some instances flagged as oversized are deliberately headroomed for burst handling; not every recommendation should be acted on without validating the use case with the service owner.
What a Managed Audit Adds
A self-service audit using Compute Optimizer and Cost Explorer will surface the obvious findings. What it misses:
- Architectural waste — cross-AZ traffic patterns, NAT gateway routing, data transfer optimization
- Reserved Instance strategy — coverage analysis, commitment risk modeling, portfolio optimization
- Tag hygiene and showback — identifying untagged resources whose costs can't be attributed to a team or service
- Right-sizing validation — distinguishing over-provisioned resources from deliberately headroomed ones without paging your engineers
Our cloud cost optimization service starts with a 72-hour cost audit covering all 15 categories above, with a remediation plan ranked by savings impact and implementation effort.
The question is usually not whether the savings exist, but how much engineer time you want to spend finding them. For ongoing cost control, our FinOps management service keeps spend optimized month over month; for a one-time cleanup, the Cloud Bill Sprint delivers results in a fixed two-week engagement.
Get a free cost assessment and we'll run the audit on your AWS account, identify the top 5 savings opportunities by dollar impact, and tell you exactly what it would take to capture them.
Questions about a specific AWS service or cost pattern in your environment? Reach out directly and we'll take a look.
Put this into practice
Book a free 1-hour call with a senior engineer about your infrastructure, or check your email security in 30 seconds.
Related Articles
Cloud FinOps: 5 AWS Cost Mistakes SMBs Make in 2026
The five most expensive AWS cost mistakes small and mid-size businesses make in 2026—and the exact steps to fix them before they compound further.
Azure Cost Optimization for SMBs: A Practical Guide to Cutting Your Bill by 30%
A hands-on guide to cutting Azure costs for SMBs: reserved instances, right-sizing, storage tiers, and the spending traps most teams miss.
Kubernetes Cost Optimization: How to Cut Your K8s Bill by 40%
A practitioner's guide to cutting Kubernetes costs 40%: resource requests, right-sizing, spot nodes, autoscaler, quotas, and idle detection.
Get articles like this in your inbox
Practical security, infrastructure, and DevOps insights for teams in regulated industries. Published weekly.