
Table of Contents
By Khimananda Oli | Last reviewed: August 2026
Most AWS bills are not big because the workload is big — they are big because nobody turned anything off. An over-provisioned instance, a forgotten load balancer, a terabyte of logs kept forever: each one is small, and together they can double what you pay. These 12 cloud cost optimization tactics to reduce your AWS bill are ordered from fastest win to deepest structural change, so you can start cutting spend this afternoon. If you would rather have someone run the audit for you, our DevOps and cloud services do exactly this.
How do you find out where your AWS bill is going?
You cannot reduce a bill you cannot see. Every real cost optimization program starts with visibility, so the first two tactics are about measurement, not cutting.
1. Turn on Cost Explorer and read it monthly
AWS Cost Explorer is free to enable and shows spend broken down by service, region, account, and — if you tag resources — by team or project. Open it, group by service, and sort descending. The top three lines are almost always EC2, RDS, and data transfer; that is where your effort pays off. Enable the hourly and resource-level granularity so Cost Explorer can drive right-sizing recommendations later.
2. Set AWS Budgets with alerts before you optimize
A budget is your safety net. Create at least one monthly cost budget and one that alerts on forecasted overspend, wired to email or SNS:
aws budgets create-budget \
--account-id 111122223333 \
--budget '{
"BudgetName": "monthly-all-in",
"BudgetLimit": {"Amount": "500", "Unit": "USD"},
"TimeUnit": "MONTHLY",
"BudgetType": "COST"
}' \
--notifications-with-subscribers '[{
"Notification": {"NotificationType": "FORECASTED",
"ComparisonOperator": "GREATER_THAN", "Threshold": 90},
"Subscribers": [{"SubscriptionType": "EMAIL",
"Address": "[email protected]"}]
}]' Now a runaway instance or a mis-scoped data pipeline pings you on day 4, not on the invoice.
Which idle and unused AWS resources should you delete first?
Deleting waste is the only tactic with zero downside — no performance trade-off, no commitment. Do it before anything clever.
3. Delete unattached EBS volumes and unused Elastic IPs
Every EBS volume bills whether or not it is attached to a running instance, and an Elastic IP that is allocated but not associated with a running instance is billed hourly. Find both quickly:
# Unattached EBS volumes
aws ec2 describe-volumes \
--filters Name=status,Values=available \
--query 'Volumes[].{ID:VolumeId,GiB:Size,AZ:AvailabilityZone}' \
--output table
# Allocated Elastic IPs not associated with an instance
aws ec2 describe-addresses \
--query 'Addresses[?AssociationId==`null`].PublicIp' \
--output table Snapshot anything you are unsure about, then delete. Old EBS snapshots pile up too — a lifecycle policy via Amazon Data Lifecycle Manager ages them out automatically.
4. Remove stale load balancers, NAT Gateways, and idle RDS
An Application or Network Load Balancer with no healthy targets still costs roughly $16+ a month plus capacity units. A NAT Gateway you spun up for a one-off migration keeps billing hourly and per-GB. Idle non-production RDS instances left running overnight are pure waste — schedule them to stop, or delete and restore from snapshot when needed.
How do you right-size AWS instances that are too big?
Over-provisioning is the single largest source of avoidable spend. Teams pick an instance size "to be safe" and never revisit it.
5. Right-size EC2 and RDS from real utilization
Use AWS Compute Optimizer (free) and Cost Explorer's right-sizing recommendations, both of which read CloudWatch metrics. The rule of thumb: if an instance sits below ~40% CPU and memory at peak for two weeks, drop it one size. Halving an m6i.2xlarge to an m6i.xlarge halves that line item. Right-size before you buy any commitment, so you commit to the smaller footprint — never the bloated one.
6. Modernize storage: gp3 over gp2, and clean CloudWatch logs
Migrating an EBS volume from gp2 to gp3 is a live modify with no downtime and is roughly 20% cheaper per GiB, with baseline throughput included. Separately, CloudWatch Logs with the default Never Expire retention quietly become one of your top bills. Set retention explicitly:
# gp2 -> gp3 in place, no downtime
aws ec2 modify-volume --volume-id vol-0abc123 --volume-type gp3
# Cap CloudWatch log retention at 30 days
aws logs put-retention-policy \
--log-group-name /aws/lambda/my-fn \
--retention-in-days 30 When should you buy Savings Plans or Reserved Instances?
Once your footprint is right-sized, commitment-based discounts are the biggest structural saving on steady workloads.
7. Commit steady compute to Savings Plans
A Compute Savings Plan commits you to a dollars-per-hour spend for 1 or 3 years in exchange for discounts up to roughly 66%, and it applies flexibly across EC2, Fargate, and Lambda in any region and instance family. Buy it for your always-on baseline only — the floor of your usage graph, never the peaks. Cost Explorer's Savings Plans recommendations size this for you from the last 7, 30, or 60 days.
8. Use Reserved Instances where they still win
For RDS, ElastiCache, Redshift, and OpenSearch — which Savings Plans do not cover — Reserved Instances remain the discount lever, up to about 72% off on a 3-year term. Prefer Standard RIs for stable databases and Convertible RIs when you may change instance family. Match the term to how confident you are in the workload's next year.
How do Graviton and Spot cut compute cost further?
Beyond discounts on what you already run, you can change what you run.
9. Move to Graviton (ARM) instances
AWS Graviton processors deliver meaningfully better price-performance than comparable x86 instances — commonly 20% cheaper for equal or better throughput. For most PHP, Node, Python, Java, and containerized apps the switch is a one-line change from m6i to m7g (or t4g for burstable). Test on a canary first: rebuild any native extensions for arm64, then roll out. RDS and ElastiCache offer Graviton nodes too.
10. Send interruptible work to Spot instances
Spot instances use spare AWS capacity at up to ~90% off on-demand, with the catch that AWS can reclaim them with a two-minute warning. That is fine for anything fault-tolerant: CI/CD runners, batch jobs, data processing, and stateless web tiers behind an autoscaling group with a mixed instances policy. Pair Spot for the flexible portion with a Savings Plan for the guaranteed baseline. Our DevOps case studies show this mixed model running in production.
How does S3 lifecycle tiering reduce storage cost?
Storage is the leak that grows silently. Most objects are read constantly for a week, then almost never — yet they sit in S3 Standard forever.
11. Tier S3 with lifecycle rules and Intelligent-Tiering
S3 storage classes drop in price as access drops: Standard → Standard-IA → Glacier Instant/Flexible → Glacier Deep Archive. A lifecycle rule ages objects down automatically. If access patterns are unpredictable, S3 Intelligent-Tiering moves objects between tiers for you and removes the guesswork:
{
"Rules": [{
"ID": "archive-old-objects",
"Status": "Enabled",
"Filter": {"Prefix": "logs/"},
"Transitions": [
{"Days": 30, "StorageClass": "STANDARD_IA"},
{"Days": 90, "StorageClass": "GLACIER"},
{"Days": 365, "StorageClass": "DEEP_ARCHIVE"}
],
"Expiration": {"Days": 730}
}]
} Apply it with aws s3api put-bucket-lifecycle-configuration. Also enable a rule to abort incomplete multipart uploads after 7 days — orphaned upload parts are invisible in the console but still billed.
What architectural change gives the biggest long-term saving?
The final tactic is structural — it changes how you pay for traffic, which is often the most opaque line on the bill.
12. Cut data-transfer and NAT Gateway costs with VPC endpoints
Data transfer is deceptively expensive: cross-AZ traffic, internet egress, and especially the NAT Gateway's per-GB processing charge. Private subnets that talk to S3, DynamoDB, ECR, or other AWS services through a NAT Gateway pay twice — the hourly NAT fee and the per-GB fee. Replace that path with VPC Gateway Endpoints (free for S3 and DynamoDB) and Interface Endpoints for other services, and keep same-AZ placement where latency-sensitive services talk to each other. Also front public content with CloudFront, whose egress is cheaper than direct S3 or EC2 egress and often lands in a lower tier. Combined, these move a large, mysterious data-transfer line down sharply.
Conclusion
Reducing your AWS bill is not one heroic move — it is a repeatable loop: measure in Cost Explorer, delete idle resources, right-size, commit the steady baseline to Savings Plans or Reserved Instances, then push variable work to Spot and Graviton and tier your storage. Run these 12 cloud cost optimization tactics once and you will typically cut 30–50% of spend; schedule them quarterly and the savings hold. If you want a fixed-scope audit that pinpoints your biggest leaks first, get in touch or see how our cloud and DevOps services put this into practice. For the deployment side of a lean stack, read our guide on building a CI/CD pipeline with GitLab CI.