DEV Community

KloudAudit
KloudAudit

Posted on

The 5 AWS charges silently draining your budget (and how to fix each one)

Every AWS bill tells a story. After couple of years as a DevOps engineer reviewing cloud infrastructure, I've learned to read that story, and it almost always has the same five chapters.
These aren't exotic edge cases. They show up on the bills of well-run teams with experienced engineers. They survive because cloud billing is complex, everyone is busy, and "we'll optimise later" is the most expensive phrase in engineering.
Here's what to look for — and exactly how to fix each one.

1. Dev/Staging RDS Running 24/7

What it costs: A db.r5.xlarge running continuously costs ~$876/month. If it's only used 8 hours a day on weekdays, you're paying for 720 hours and using ~170.

Why it happens: The database got created for a sprint, the sprint ended, and nobody scheduled a shutdown.

The fix — Lambda stop/start schedule (20 minutes to implement):

`# Create an IAM role for Lambda with RDS stop/start permissions
aws iam create-role --role-name RDSScheduler \
--assume-role-policy-document file://lambda-trust-policy.json

Stop RDS at 7pm weekdays

aws events put-rule \
--name "StopDevRDS" \
--schedule-expression "cron(0 17 ? * MON-FRI *)"

Start RDS at 8am weekdays

aws events put-rule \
--name "StartDevRDS" \
--schedule-expression "cron(0 8 ? * MON-FRI *)"`

Savings: 65% reduction on affected instances.

2. Everything on On-Demand Pricing

What it costs: On-Demand is the list price the most expensive way to run EC2. If you've had stable workloads running for 6+ months, you're paying a significant premium for flexibility you're not using.
Why it happens: Reservations require commitment and upfront analysis. On-Demand requires neither.

The fix — Compute Savings Plans:

shell
bash# Check your On-Demand spend for the last 3 months
aws ce get-cost-and-usage \
--time-period Start=2026-01-01,End=2026-04-01 \
--granularity MONTHLY \
--filter '{"Dimensions":{"Key":"PURCHASE_TYPE","Values":["On Demand"]}}' \
--metrics BlendedCost

Check Savings Plans recommendations

shell
aws savingsplans describe-savings-plans-purchase-recommendation \
--savings-plans-type COMPUTE_SP \
--term-in-years ONE_YEAR \
--payment-option NO_UPFRONT

Purchase a 1-year no-upfront Compute Savings Plan for your baseline usage. Zero architecture change. Zero risk.

Savings: 30–45% on covered compute.

3. Unattached EBS Volumes

What it costs: $0.10/GB/month sounds trivial. 50 forgotten 100GB volumes from a migration two years ago = $500/month. Every month. For nothing.

Why it happens: When you terminate an EC2 instance, AWS doesn't automatically delete the attached EBS volume unless you explicitly configured it to do so.
The fix — find and review them in 60 seconds:

bash# List all unattached EBS volumes with their size and creation date

aws ec2 describe-volumes \
--filters Name=status,Values=available \
--query 'Volumes[*].{ID:VolumeId,Size:Size,Created:CreateTime,Type:VolumeType}' \
--output table

# Delete a specific volume (after verifying you don't need it)
aws ec2 delete-volume --volume-id vol-xxxxxxxxxxxxxxxxx

Before deleting: create a snapshot if there's any chance the data is needed. Snapshots cost ~$0.05/GB/month — a fraction of the volume cost.
Savings: variable, but I've seen $200–$1,200/month from this alone.

4. S3 Storage Never Tiered

What it costs: S3 Standard is $0.023/GB/month. S3 Glacier Instant Retrieval is $0.004/GB/month. Data from 2022 that nobody has accessed sitting in Standard costs 5.75x more than it needs to.
Why it happens: Lifecycle rules require deliberate configuration. Default bucket settings keep everything in Standard forever.

The fix — lifecycle policy (5 minutes):

bash# Apply intelligent tiering lifecycle rule to a bucket
aws s3api put-bucket-lifecycle-configuration \
--bucket your-bucket-name \
--lifecycle-configuration '{
"Rules": [{
"ID": "IntelligentTiering",
"Status": "Enabled",
"Filter": {"Prefix": ""},
"Transitions": [
{"Days": 30, "StorageClass": "STANDARD_IA"},
{"Days": 90, "StorageClass": "GLACIER_IR"}
]
}]
}'

Savings: 30–60% on storage older than 90 days.

5. NAT Gateway Data Processing Charges

What it costs: NAT Gateway charges $0.045 per GB processed; in both directions. Microservices calling each other through a NAT Gateway instead of VPC endpoints can generate $1,000+/month in charges that appear as "data transfer" on your bill.
Why it happens: It's invisible. The architecture diagram looks fine. Nobody knows NAT Gateway charges per-GB until they see the bill.

The fix — VPC endpoints for AWS services:

`bash# Create a VPC endpoint for S3 (free — Gateway type)
aws ec2 create-vpc-endpoint \
--vpc-id vpc-xxxxxxxxx \
--service-name com.amazonaws.eu-west-1.s3 \
--route-table-ids rtb-xxxxxxxxx

Create a VPC endpoint for DynamoDB (free — Gateway type)

aws ec2 create-vpc-endpoint \
--vpc-id vpc-xxxxxxxxx \
--service-name com.amazonaws.eu-west-1.dynamodb \
--route-table-ids rtb-xxxxxxxxx`

S3 and DynamoDB Gateway endpoints are free. Traffic to these services no longer routes through NAT Gateway.

Savings: 10–30% of your NAT Gateway bill, potentially much more.

How to Find All of This in 15 Minutes

If you want to run through all five of these, plus 13 more checks across compute, storage, database, and networking, I built a free structured audit tool that does exactly this.

No account access required. No IAM roles. No agents. You answer questions about your setup and it flags issues with savings estimates.

kloudaudit.eu — free to run, takes 15 minutes.

What's the biggest AWS cost surprise you've found on your bill?
Drop it in the comments, always curious what patterns others are seeing.

Top comments (0)