KubePruneAWS and EKS, trimmed
AWS costs

12 AWS cost cuts that don't need a re-architecture

For startups and scale-ups whose AWS bill grew faster than the product. Twelve places to look, how to spot each one with a command or a report, and the figures AWS itself publishes.

By Amine, freelance DevOps engineer ·

Most AWS savings that don't need a redesign come from the same twelve places: oversized resources and pod requests, non-production running 24/7, orphaned volumes, NAT gateway traffic to S3, gp2 volumes, missing Savings Plans, no Spot, x86 by default, S3 without lifecycle rules, logs kept forever, unused public IPv4 addresses, and EKS clusters on extended support. Each one can be found with a few commands.

The twelve cuts in one table

Where to look, and the figure AWS publishes
#CutHow to spot itPublished figure
1Rightsize instances, databases and pod requestsAWS Compute Optimizer; requests vs. usageDepends on your workloads
2Schedule non-productionHours each environment runs50 of 168 hours a week = 70% fewer hours (arithmetic)
3Delete unattached volumes and old snapshotsVolumes in the available state100% of what they cost
4Route S3 and DynamoDB traffic through gateway endpointsNAT gateway bytes processedGateway endpoints: no extra charge
5Move gp2 volumes to gp3Volumes of type gp2gp3 is 20% cheaper per GB-month
6Cover your baseline with Savings PlansCost Explorer coverage reportUp to 66% (Compute) or 72% (EC2 Instance)
7Use Spot for interruptible workCI runners, batch, stateless nodesUp to 90% off On-Demand
8Move to Gravitonx86 instance families in useUp to 20% lower cost (EC2)
9Add S3 lifecycle rulesBuckets with no lifecycle configurationDepends on storage classes
10Set CloudWatch Logs retentionLog groups with no retentionKept forever by default
11Release unused public IPv4 addressesPublic IP Insights$0.005 per IP per hour
12Get EKS clusters off extended supportCluster version and upgrade policy$0.60 vs $0.10 per cluster-hour

The percentages are maximums announced by AWS, not averages. Your savings depend on your bill, which is why we don't quote a typical number.

Where to start

Order matters. Start with what is safe and immediate: orphaned resources (3), gp3 (5), log retention (10), unused IPs (11). Then the changes that need measurement: rightsizing (1), schedules (2), Graviton (8), Spot (7). Commitments (6) come last, once the base is stable. Committing for three years to instances you were about to halve just locks the waste in.

The detail, one by one

1. Rightsize instances, databases and pod requests

AWS Compute Optimizer analyzes EC2 instances, Auto Scaling groups, EBS volumes and Lambda functions and recommends better-fitting types.

aws compute-optimizer get-ec2-instance-recommendations \
  --query "instanceRecommendations[].[instanceArn,finding,recommendationOptions[0].instanceType]" \
  --output table

Two cautions. Size for peaks, not averages. And without the CloudWatch agent, Compute Optimizer doesn't see EC2 memory, so a CPU-only recommendation can undersize a memory-hungry app. On Kubernetes, requests decide how many nodes you pay for, not actual usage: compare requests with real consumption before touching node types.

2. Schedule non-production

A staging environment up 10 hours a day, 5 days a week, runs 50 of 168 hours: 70% fewer hours. That's arithmetic, not a statistic, and it only applies to resources billed by the hour. The Instance Scheduler on AWS solution stops and starts EC2 and RDS on a schedule. On EKS, scale node groups to zero after hours or let Karpenter remove empty nodes. Note that a stopped RDS instance starts again on its own after seven days.

3. Delete unattached volumes and old snapshots

A detached EBS volume is still billed. So are snapshots, long after the volume or AMI they belonged to is gone.

# Unattached volumes
aws ec2 describe-volumes --filters Name=status,Values=available \
  --query "Volumes[].[VolumeId,Size,VolumeType,CreateTime]" --output table
# Your snapshots, oldest first
aws ec2 describe-snapshots --owner-ids self \
  --query "sort_by(Snapshots,&StartTime)[].[SnapshotId,VolumeId,VolumeSize,StartTime]" --output table

On EKS, orphaned volumes often come from PersistentVolumes with a Retain policy whose claim is gone.

4. Route S3 and DynamoDB traffic through gateway endpoints

A NAT gateway is billed twice: per hour and per gigabyte processed. The classic trap is private-subnet nodes pulling data from S3 through the NAT. In Cost Explorer, group by usage type and look for NAT gateway bytes. Gateway VPC endpoints for S3 and DynamoDB come at no additional charge, which makes them the best value fix in this list. Interface endpoints, for ECR for example, are billed: compare their cost with the traffic before adding them.

5. Move gp2 volumes to gp3

gp3 costs 20% less per GB-month than gp2 ($0.08 vs $0.10 in AWS's example) and includes a baseline of 3,000 IOPS and 125 MiB/s whatever the size. The change is made on the volume with Elastic Volumes:

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

A gp2 volume over 1 TiB has more than 3,000 baseline IOPS: provision the same on gp3. On Kubernetes, make a gp3 StorageClass with the EBS CSI driver the default, or new volumes keep coming in as gp2.

6. Cover your baseline with Savings Plans

According to AWS, Compute Savings Plans cut up to 66% off On-Demand prices, and EC2 Instance Savings Plans and Standard Reserved Instances up to 72%, for one- or three-year terms. Compute Savings Plans apply to EC2, Fargate and Lambda without tying you to an instance family, which suits a startup whose architecture still moves. Commit to your floor, not your average.

7. Use Spot for interruptible work

AWS advertises Spot Instances at up to 90% off On-Demand. Good candidates are CI runners, batch jobs and stateless Kubernetes nodes spread across several instance types. Bad ones are anything that can't lose a node at short notice.

8. Move to Graviton

AWS states that Graviton-based EC2 instances deliver up to 40% better performance at up to 20% lower cost than comparable x86 instances. Managed services such as RDS and ElastiCache are the easiest: an instance type change. For containers you need arm64 or multi-architecture images, built with docker buildx, and compatible native dependencies. Test your real load: the gain depends on your code.

9. Add S3 lifecycle rules

A bucket with no lifecycle rule keeps everything in its storage class forever, including old object versions when versioning is on, and abandoned multipart uploads.

aws s3api get-bucket-lifecycle-configuration --bucket my-bucket

A NoSuchLifecycleConfiguration error means no rule. The three rules that come up most: transition to a cheaper class after N days (or S3 Intelligent-Tiering if access is unpredictable), expire noncurrent versions, and AbortIncompleteMultipartUpload.

10. Set CloudWatch Logs retention

By default, CloudWatch Logs keeps logs indefinitely. Log groups created automatically by Lambda, EKS or collection agents often have no retention set.

# Log groups with no retention, with stored size
aws logs describe-log-groups \
  --query "logGroups[?!retentionInDays].[logGroupName,storedBytes]" --output table
# Set 30 days on one group
aws logs put-retention-policy --log-group-name /aws/eks/my-cluster/cluster \
  --retention-in-days 30

Retention cuts storage; ingestion is billed separately. If the line stays high, look at what is being sent.

11. Release unused public IPv4 addresses

Since February 1, 2024, AWS charges $0.005 per hour for every public IPv4 address, in use or idle. Public IP Insights in Amazon VPC IP Address Manager lists them. Idle Elastic IPs, forgotten load balancers and nodes in public subnets are the usual suspects.

12. Get EKS clusters off extended support

An EKS cluster whose Kubernetes version has left standard support pays $0.60 per cluster-hour instead of $0.10, by default and without anyone opting in. That's about $365 more per cluster per month. The cost of EKS extended support guide shows how to check every cluster in a few commands.

Want someone to go through all twelve on your account? The cost audit is $2,400, fixed, with read-only access: a written report with prioritized savings, and Terraform pull requests for the quick wins. The 20-minute bill review is free.

KubePrune is independent and not affiliated with Amazon Web Services. Prices are AWS public list prices checked on November 3, 2026; check the pricing pages for your region and date.

Frequently asked questions

What is the fastest AWS saving for a startup?

Usually the risk-free ones: deleting unattached volumes and old snapshots, moving gp2 volumes to gp3, and setting log retention. They take hours, not weeks.

Should we buy Savings Plans first?

No. Rightsize and clean up first, then commit to the stable floor of your usage. Committing before that locks in the waste.

Are gateway endpoints really free?

Yes. AWS states there is no additional charge for using gateway endpoints, which exist for S3 and DynamoDB. Interface endpoints are billed.

How much does an unused Elastic IP cost?

Since February 1, 2024, AWS charges $0.005 per hour for every public IPv4 address, whether in use or idle.

Sources

  1. AWS Savings Plans and Reserved Instances — up to 66% and 72%.
  2. Amazon EC2 Spot Instances pricing — up to 90% off On-Demand.
  3. AWS Graviton fast start — up to 40% better performance, up to 20% lower cost.
  4. AWS Prescriptive Guidance: migrate gp2 to gp3 — 20% cheaper per GB-month.
  5. Amazon VPC: Gateway endpoints — no additional charge.
  6. AWS News Blog: public IPv4 address charge — $0.005 per IP per hour from February 1, 2024.
  7. What is Amazon CloudWatch Logs? — logs kept indefinitely by default.
  8. Amazon EKS pricing — standard and extended support.

Checked November 3, 2026. Prices vary by region; check the pricing pages for yours.

Related