Skip to main content

FinOps

AWS cost optimization checklist: 15 ways to reduce your AWS bill

To reduce an AWS bill, first remove what is no longer used (volumes, IP addresses, logs without retention), then right-size what runs, and only commit to Savings Plans last, on the baseline that remains. This guide ranks 15 levers by savings and effort, priced on a sample account, with the AWS CLI command that detects each one.

In short

  • Clean up first: unattached EBS volumes, unused public IP addresses, old snapshots, logs without retention, gp2 to gp3. Low effort, no impact on production.
  • Then right-size: instance right-sizing, non-production stopped at night, upgrades that leave extended support.
  • Commit last: a Savings Plan bought before the clean-up locks your budget into waste for one or three years.
  • On this guide's sample account, the 15 levers add up to about USD 2,780 a month, around USD 550 of it with no risk to production.

The sample account used for the figures

The savings below are computed on a fictitious account, typical of a mid-sized company running a web application in the Paris Region (eu-west-3). Your amounts will differ; the method applies as is.

  • Production: 12 m7i.xlarge instances running around the clock, 4 of them below 10% CPU.
  • Non-production: 10 m7i.large instances running around the clock, used during office hours.
  • Storage: 6 TB of attached gp2 EBS volumes, 800 GB of detached gp2 volumes, 3 TB of snapshots older than six months, 15 TB of rarely read S3 Standard objects.
  • Network: two VPCs (production and non-production) with one NAT gateway per Availability Zone, six in total; 1.2 TB a month of S3 traffic going through the production NAT; 12 public IPv4 addresses no longer used.
  • Other: 1.5 TB of CloudWatch logs with no retention period, 2 Application Load Balancers with no traffic, one EKS cluster in extended support, one unused Interface VPC endpoint across 3 zones.

AWS public on-demand prices for eu-west-3, taken from the AWS Price List API on 23 October 2026, in US dollars (the currency of AWS prices), on the basis of 730 hours a month. No Savings Plan or Reserved Instance is in place at the start.

The 15 levers, ranked by savings and effort

Levers 1 to 7: wave 1, clean-up. Levers 8 to 10: wave 2, right-sizing. Levers 11 to 15: wave 3, architecture and commitment. Within each wave, levers are in the recommended order of application.

15 levers to reduce an AWS bill, with the monthly savings on the sample account, the effort and the risk
LeverSavings on the sample accountEffortWatch out for
1. Delete or archive snapshots older than six monthsUp to USD 159/month (3 TB at USD 0.053/GB-month)LowSnapshots are incremental: the space freed may be smaller than the size shown. Check the backup policy.
2. Move EBS volumes from gp2 to gp3USD 139/month (6 TB, from USD 0.116 to 0.0928/GB-month, −20%)LowAbove 1 TB, provision on gp3 the IOPS the gp2 volume had (3 IOPS per GB).
3. Delete unattached EBS volumesUSD 93/month (800 GB of gp2)LowTake a snapshot before deletion if the content is unknown.
4. Set a retention period on CloudWatch logsUp to USD 47/month (1.5 TB at USD 0.0315/GB-month), and the bill stops growingLowKeep the retention periods your security or regulatory rules require.
5. Release unused public IPv4 addressesUSD 44/month (12 addresses at USD 0.005/hour)LowA released Elastic IP cannot be recovered: check partners' allow lists.
6. Delete load balancers with no trafficUSD 39/month (2 ALBs at USD 0.02646/hour, excluding LCUs)LowCheck that no DNS record still points to them.
7. Delete unused Interface VPC endpointsUSD 24/month (1 endpoint across 3 zones at USD 0.011/hour per zone)LowTraffic then goes back through the NAT gateway, if there is one.
8. Stop non-production outside office hoursUSD 553/month (10 m7i.large, from 730 to 260 hours a month)MediumEBS volumes are still billed while stopped. A stopped RDS instance restarts on its own after seven days.
9. Right-size over-provisioned instancesUSD 343/month (4 m7i.xlarge brought down to m7i.large)MediumLook at memory, not just CPU, and test under real load.
10. Take EKS clusters out of extended supportUSD 365/month per cluster (USD 0.50/hour surcharge)MediumKubernetes version upgrade to test (deprecated APIs, add-ons).
11. Move rarely read S3 objects to a suitable storage classUSD 164 to 285/month (15 TB in Standard-IA or Glacier Instant Retrieval)MediumRetrieval fees and minimum storage duration (30 days in Standard-IA, 90 days in Glacier Instant Retrieval).
12. A single NAT gateway for non-productionUSD 73/month (2 NAT gateways at USD 0.05/hour)MediumNon-production loses cross-zone redundancy: fine for testing, not for production.
13. Add an S3 gateway endpoint (free)USD 60/month (1.2 TB no longer processed by the NAT, at USD 0.05/GB)LowCheck bucket policies that filter on the source IP address.
14. Cover the baseline with a Compute Savings PlanUSD 415/month (1 year, no upfront, −24% on USD 1,717 of production)Low to do, one-year commitmentDo it after levers 8 and 9, otherwise you commit on instances that are about to go.
15. Migrate to Graviton (Arm)USD 262/month (8 m7i.xlarge to m7g.xlarge, −19%)HighImages and dependencies to rebuild for Arm, regression testing.

The savings do not add up to the dollar: moving to Graviton shrinks the baseline the Savings Plan covers, and archiving a snapshot instead of deleting it keeps part of the cost. The order matters more than the total.

Wave 1: clean-up, with no risk to production

These levers target resources that are no longer used. They need no load test and no maintenance window, only a check of who owns each resource before deleting it. The details per resource type are in the unused AWS resources checklist.

Start with detached EBS volumes and public IP addresses: since February 2024, AWS charges USD 0.005 an hour for every public IPv4 address, attached or not, which is USD 3.65 a month per address. An Elastic IP reserved for a server deleted two years ago is still being paid for.

CloudWatch logs with no retention are a cost that only grows: every gigabyte ingested stays stored forever. A retention of 30, 90 or 365 days depending on use stops the increase.

Moving from gp2 to gp3 belongs here because it happens live, with no instance stop: gp3 costs 20% less and includes 3,000 IOPS and 125 MiB/s whatever the size. As gp2 gives 3 IOPS per GB, a volume above 1 TB must get on gp3 the IOPS it would otherwise lose (USD 0.0058 per IOPS-month in eu-west-3).

# Unattached EBS volumes (status available)
aws ec2 describe-volumes --filters Name=status,Values=available \
  --query 'Volumes[].[VolumeId,Size,VolumeType,CreateTime]' --output table

# Elastic IP addresses not associated
aws ec2 describe-addresses \
  --query 'Addresses[?AssociationId==`null`].[PublicIp,AllocationId]' --output table

# Log groups with no retention, with their stored volume
aws logs describe-log-groups \
  --query 'logGroups[?retentionInDays==`null`].[logGroupName,storedBytes]' --output table

# Set a 90-day retention
aws logs put-retention-policy --log-group-name /aws/lambda/my-api --retention-in-days 90

# gp2 volumes to migrate, then live migration
aws ec2 describe-volumes --filters Name=volume-type,Values=gp2 \
  --query 'Volumes[].[VolumeId,Size,Iops]' --output table
aws ec2 modify-volume --volume-id vol-0123456789abcdef0 --volume-type gp3

Wave 2: right-size what runs

These levers touch resources in service. They save the most, but each one needs a test.

  • Stop non-production at night and at weekends: at 12 hours per working day, an instance goes from 730 to about 260 billed hours a month, 64% less. The Instance Scheduler on AWS solution or an EventBridge Scheduler rule is enough.
  • Right-size: AWS Compute Optimizer recommends an instance type from the last 14 days of metrics (30 hours minimum). Memory is only visible if the CloudWatch agent publishes it: without it, a CPU-only recommendation can be wrong.
  • Leave extended support: a Kubernetes version past standard support costs USD 0.60 an hour per cluster instead of USD 0.10. RDS databases on an end-of-life major version also move to paid extended support.
# Over-provisioned instances according to Compute Optimizer
aws compute-optimizer get-ec2-instance-recommendations \
  --query 'instanceRecommendations[?finding==`OVER_PROVISIONED`].[instanceArn,currentInstanceType,recommendationOptions[0].instanceType]' \
  --output table

# Version and support type of an EKS cluster
aws eks describe-cluster --name my-cluster \
  --query 'cluster.[version,upgradePolicy.supportType]'

Wave 3: commitment and architecture

Once the baseline is stable, commitment brings the last big saving. On an m7i.large in eu-west-3, a one-year no-upfront Compute Savings Plan brings the hourly price from USD 0.1176 down to USD 0.08919, 24% less; over three years, 47%. The choice between plan types and Reserved Instances is covered in Savings Plans vs Reserved Instances.

  • Network: each NAT gateway costs USD 36.50 a month before a single byte, then USD 0.05 per GB processed. An S3 or DynamoDB gateway endpoint is free and takes that traffic out of the NAT. The full calculation is in AWS NAT gateway cost.
  • S3 storage: a lifecycle rule moves rarely read objects to Standard-IA (USD 0.0131/GB-month) or Glacier Instant Retrieval (USD 0.005/GB-month) instead of USD 0.024 in Standard. If access patterns are unpredictable, S3 Intelligent-Tiering does it on its own, for USD 0.0025 a month per 1,000 monitored objects.
  • Graviton: at the same size, an m7g costs 19% less than an m7i in eu-west-3. The saving is real but needs Arm images and a test campaign: it is a project, not a setting.
# Last month's cost by service
aws ce get-cost-and-usage --time-period Start=2026-09-01,End=2026-10-01 \
  --granularity MONTHLY --metrics UnblendedCost \
  --group-by Type=DIMENSION,Key=SERVICE

# Compute Savings Plan recommendation over 60 days of history
aws ce get-savings-plans-purchase-recommendation --savings-plans-type COMPUTE_SP \
  --term-in-years ONE_YEAR --payment-option NO_UPFRONT \
  --lookback-period-in-days SIXTY_DAYS

Mistakes that cost more than they save

  • Buying a Savings Plan first: the commitment is computed on current usage, waste included.
  • Deleting a snapshot that was the only backup: check the AWS Backup or Data Lifecycle Manager policy before any clean-up.
  • Folding production onto a single NAT gateway: losing one zone then cuts outbound access for all the others.
  • Optimising without measuring: with no before-and-after reading in Cost Explorer, nobody can say what the effort saved.
  • Cleaning up once: without owner tags or per-team budgets, orphaned resources come back within months.

What the FinOps audit automates

Silamir's AWS FinOps audit collects read-only data from Cost Explorer, Savings Plans, Compute Optimizer and Trusted Advisor, then looks for unused resources region by region:

  • unattached EBS volumes, unassociated Elastic IPs, snapshots older than six months, AMIs older than a year, logs with no retention, VPC endpoints with no traffic over 30 days;
  • Savings Plans and Reserved Instances coverage and utilisation, purchase recommendations;
  • right-sizing recommendations, and enabling Compute Optimizer when it is off.

Each action states the expected monthly saving, the resources concerned by their identifier and the command to apply it, sorted by return on investment. The audit costs USD 299, billed by AWS, and also covers security, resilience and seven other domains. It changes nothing: it recommends, you decide. To compare with a consultancy, see what a Well-Architected review costs.

Reducing your AWS bill: frequently asked questions

Where should I start to reduce my AWS bill?

With the cost breakdown by service in Cost Explorer, then with resources that are no longer used: unattached EBS volumes, unused public IP addresses, old snapshots, logs with no retention. None of these touch production. Right-sizing comes next, commitment (Savings Plans) last.

How much can I save on an AWS bill?

It depends on the account. On this guide's sample account (22 instances, six NAT gateways, 6 TB of EBS volumes), the 15 levers add up to about USD 2,780 a month. Only a review of your own account can price your case, resource by resource.

Should I buy Savings Plans straight away?

No. A Savings Plan commits an hourly spend for one or three years. Bought before right-sizing and before stopping unneeded environments, it covers usage that is about to drop, and the commitment turns into waste.

Are public IPv4 addresses charged on AWS?

Yes, since 1 February 2024: USD 0.005 an hour per public IPv4 address, whether attached to a resource or not, about USD 3.65 a month. Only addresses brought by the customer (BYOIP) are not charged.

Which free AWS tools help reduce the bill?

Cost Explorer (in the console), AWS Budgets for alerts, Compute Optimizer for EC2 right-sizing, and the Savings Plans recommendations in Cost Explorer. Calls to the Cost Explorer API are charged USD 0.01 per request.

Where does your AWS account stand?

Ten questions, three minutes, no access to your account: a security score, a FinOps score and the article to read for each of your three weakest points. Your answers stay in your browser.

Ready to audit your AWS account?

Subscribe on AWS Marketplace, deploy the read-only role and get your reports within the hour.