Cloud guide
7 Practical Ways to Reduce AWS Cloud Costs
AWS bills grow quietly: a test server left running, volumes nobody deleted, instances sized for a peak that never comes. This guide goes through seven practical fixes, with the AWS commands to find the waste and worked examples using real AWS list prices, so you can see what each one is worth before you touch anything.
- Level
- Intermediate
- Best for
- IT managers, engineers and finance leads with access to an AWS account
- Assumes
- You can sign in to the AWS console. Command examples use the AWS CLI but are optional.
Key takeaways
- Tag resources and use Cost Explorer first; you cannot cut what you cannot attribute.
- Unattached volumes, idle IP addresses and forgotten NAT gateways cost money every hour and are the safest things to remove.
- Right-size from the 95th percentile of real usage, not the average, and keep headroom.
- Commit with Savings Plans only after right-sizing, and only to the baseline you are sure of.
- Scheduling dev and test to office hours cuts their compute hours by about 64%.
Before you start: find out where the money goes
Open Cost Explorer, set the last three months, and group by Service. In most accounts four or five lines (EC2, RDS, EBS, data transfer and S3) make up the bulk of the bill. Then group by Usage type inside the biggest service; that is where surprises like "NatGateway-Bytes" or "EBS:SnapshotUsage" show up.
If resources are not tagged, start now with three tags: environment (production, staging, dev), application and owner. Activate them as cost allocation tags in the Billing console so spend can be grouped by team or product from next month on.
- SeeCost Explorer, tags
- Clean upDelete unused resources
- Right-sizeMatch capacity to use
- CommitDiscount steady usage
- AutomateSchedules and lifecycle rules
- ReviewMonthly, with an owner
1. Remove unused and forgotten resources
Nothing depends on these, which makes them the safest savings on the bill.
| Resource | Approximate list price | Monthly cost of one |
|---|---|---|
| Unattached 500 GB gp3 volume | $0.08 per GB-month | About $40 |
| Idle public IPv4 address (including unattached Elastic IPs) | $0.005 per hour | About $3.65 |
| NAT gateway in an unused environment | $0.045 per hour, plus data processed | About $33 before any traffic |
| 1 TB of old EBS snapshots | $0.05 per GB-month | About $51 |
# Volumes not attached to any instance
aws ec2 describe-volumes --filters Name=status,Values=available \
--query 'Volumes[].{id:VolumeId,gb:Size,created:CreateTime}' --output table
# Elastic IPs not associated with anything
aws ec2 describe-addresses --query 'Addresses[?AssociationId==null].PublicIp'
# Your snapshots, oldest first
aws ec2 describe-snapshots --owner-ids self \
--query 'sort_by(Snapshots,&StartTime)[].{id:SnapshotId,gb:VolumeSize,date:StartTime}' --output table2. Right-size oversized servers
AWS Compute Optimizer analyzes CloudWatch metrics and recommends smaller or different instance types. Memory is not collected by default, so install the CloudWatch agent first if you want memory-aware recommendations; otherwise you are guessing at half the picture.
- Size to the 95th percentile of the busiest realistic period, and keep 20–30% headroom.
- Move to newer instance generations, which usually cost the same or less for more performance.
- Test AWS Graviton (ARM) instances for Linux workloads. AWS cites up to 40% better price-performance; most Node.js, Python, Java and .NET applications run unchanged, but test first.
- Check RDS instances too; databases are frequently the most oversized line on a bill.
3. Optimize storage
| Change | Example | Monthly effect at list price |
|---|---|---|
| EBS gp2 → gp3 | 2 TB of gp2 volumes | $200 → $160, and gp3 includes a 3,000 IOPS baseline. The change is online, with no downtime. |
| S3 Standard → Glacier Deep Archive for old logs | 10 TB of log files kept for compliance | About $235 → about $10. Retrieval takes hours and there is a 180-day minimum, so use it only for data you rarely read. |
| CloudWatch Logs retention | Logs kept forever (the default) | Stored logs cost $0.03 per GB-month indefinitely; a 30- or 90-day retention stops the growth. |
| Snapshot lifecycle | Daily snapshots never deleted | Data Lifecycle Manager or AWS Backup keeps, say, 14 dailies and 6 monthlies instead of hundreds. |
{
"Rules": [{
"ID": "archive-then-expire-logs",
"Filter": { "Prefix": "logs/" },
"Status": "Enabled",
"Transitions": [{ "Days": 30, "StorageClass": "DEEP_ARCHIVE" }],
"Expiration": { "Days": 730 }
}]
}If you do not know how often data is read, S3 Intelligent-Tiering moves objects between tiers automatically for a small monitoring fee per object.
4. Commit to reserved capacity for steady workloads
If part of your usage runs 24 hours a day, every day, you are paying on-demand rates for something predictable. A one- or three-year commitment earns a discount.
| Option | How it works | Best for |
|---|---|---|
| Compute Savings Plans | Commit to a dollar amount of compute per hour; applies across instance families, regions, Fargate and Lambda. | Most businesses; stays flexible as you change instance types. |
| EC2 Instance Savings Plans | Larger discount, tied to one instance family in one region. | Stable workloads unlikely to change family. |
| Reserved Instances for RDS, ElastiCache, OpenSearch | Commit to a specific database or cache instance. | Production databases that run continuously. |
| Spot Instances | Spare capacity at a deep discount, reclaimable with two minutes' notice. | Batch jobs, CI builds and other interruption-tolerant work. |
AWS advertises discounts of up to 72% for Savings Plans and up to 90% for Spot compared with on-demand; real savings depend on term, payment option and instance type. Cost Explorer's Savings Plans recommendations show the commitment that fits your last 30 or 60 days of usage.
5. Schedule non-production resources
A week has 168 hours; office hours (12 hours a day, 5 days a week) are 60. Running dev and test only during office hours cuts their compute hours by about 64%.
The Instance Scheduler on AWS solution starts and stops EC2 and RDS instances based on a tag such as Schedule=office-hours. Give developers a simple way to override it for late nights, or they will find a way around it.
6. Reduce data transfer and networking charges
Networking charges are easy to miss because they never show up as a "server."
- NAT gateway processing. Every gigabyte through a NAT gateway costs about $0.045. Servers in private subnets that read 2 TB a month from S3 through a NAT gateway pay about $92 a month for nothing. An S3 gateway endpoint carries that traffic with no data processing charge.
- Data transfer out. Put Amazon CloudFront in front of public content; it caches close to users and its outbound pricing is often lower than serving directly.
- Cross-zone traffic. Traffic between Availability Zones is charged in each direction (about $0.01 per GB each way). Very chatty services spread across zones can quietly add up; keep tightly coupled components close where reliability allows.
7. Monitor continuously and give cost an owner
- Create AWS Budgets with alerts at 80% and 100% of expected monthly spend, sent to a person, not a shared inbox.
- Turn on Cost Anomaly Detection so a runaway resource is flagged within a day, not at month-end.
- Review costs monthly with each application owner, using the tags from the first step.
- Track a unit cost the business understands, such as AWS cost per active customer or per 1,000 orders, so growth and waste are easy to tell apart.
Saving money without hurting reliability
- Change one thing at a time and watch the metrics for a week before the next change.
- Never remove production redundancy to save money: Multi-AZ databases and spare capacity exist for the day something fails.
- Test instance changes in staging first, especially moves to Graviton or a new family.
- Use Spot only for work that can be interrupted and retried.
- Keep backup retention aligned with your recovery requirements, not the cheapest setting.
If the bill jumped after a migration, our AWS cloud migration guide explains why copying server sizes 1:1 is a common cause.
Frequently asked questions
How much can we realistically save on AWS?
It depends on how the account has been managed. Accounts that have never been reviewed usually have unused resources and oversized instances that can be removed safely; well-run accounts save more from commitments and architecture. Running the steps above against your own Cost Explorer data gives a real number.
Should we choose Savings Plans or Reserved Instances?
For EC2, Fargate and Lambda, Compute Savings Plans are the most flexible choice for most businesses. Reserved Instances remain the way to discount RDS, ElastiCache and OpenSearch.
Will right-sizing cause outages?
Not if it is based on real utilization with headroom, tested in staging and done one change at a time. Changing an EC2 instance type needs a brief stop and start, so schedule it in a maintenance window.
Do we need a third-party cost tool?
Not to start. Cost Explorer, Compute Optimizer, Budgets and Cost Anomaly Detection are built in and cover most small and mid-sized environments.
How often should we review AWS costs?
Monthly, with budget and anomaly alerts catching surprises in between.
How CodeMutual can help
Discuss your project with CodeMutual
Tell us what you're working on. We'll come back with a plain-English plan within one business day, and you'll talk directly to the engineers who would do the work.