Our production AWS bill had crept from $1,800 to $4,200 over eighteen months. Not through any single big decision, but through the slow accumulation of "we'll optimize that later" choices that never got optimised.

I spent two days doing a cost audit in January. No code changes, no architecture changes, just configuration and purchasing decisions. Here's exactly what we did.

Step 1: Reserved Instances on Steady-State Workloads (Savings: ~$900/month)

We had four EC2 instances that had been running at consistent utilisation for over a year. We were paying on-demand pricing for all of them. Converting to 1-year Reserved Instances at no-upfront pricing reduced those instance costs by approximately 38%. This took 20 minutes and saved $900 per month immediately.

The check: look at your Cost Explorer → Reserved Instance recommendations. AWS will show you which instances have been running for long enough that reserved pricing makes financial sense. If an instance appears there and it's a stable workload, buy the reservation.

Step 2: Right-Sizing Over-Provisioned Instances (Savings: ~$400/month)

We had several instances running at 12-18% average CPU utilisation. They were sized for a peak load we'd planned for but never reached. AWS Compute Optimizer flagged all of them with right-sizing recommendations.

We dropped four instances one size (t3.large → t3.medium, etc.) and saw no performance impact. Average CPU went from 14% to 28% — still well within healthy range — and monthly compute costs dropped meaningfully.

Step 3: S3 Lifecycle Policies on Old Data (Savings: ~$340/month)

We had 8TB of data in S3 Standard. Most of it was log files and backups older than 90 days that we kept "just in case" but had never actually accessed. S3 Standard costs $0.023/GB/month. S3 Glacier Instant Retrieval costs $0.004/GB/month — 83% cheaper — and still gives you millisecond access if you ever need it.

We set up a lifecycle rule: any object older than 90 days that matches our backup and log prefixes automatically transitions to Glacier Instant Retrieval. Monthly storage bill for those 8TB dropped from $184 to $32.

Step 4: Delete Orphaned Resources (Savings: ~$200/month)

Running a resource audit via AWS Trusted Advisor and a custom Cost Explorer filter revealed: three unattached EBS volumes still charging storage fees, two old load balancers with no targets, one Elastic IP not attached to anything ($3.60/month each, adds up), and a snapshot schedule that was creating daily snapshots of volumes we'd stopped using.

Deleted all of it. This step alone freed up $200/month and took three hours.

Step 5: Transfer Acceleration and Data Transfer Routing Review (Savings: ~$700/month)

This one required understanding our architecture. We were routing a lot of inter-service traffic through paths that incurred unnecessary data transfer charges. Moving to VPC endpoints for S3 and DynamoDB, and ensuring services in the same AZ were actually communicating within the same AZ (cross-AZ data transfer isn't free) reduced our data transfer line items significantly.

Total: From $4,200 to $1,596 per month

Two days of work. No feature impact, no code changes, no architecture changes. The cloud bill optimisation problem is real, and the first pass is almost always worth doing. Schedule a cost audit day on your team's calendar — the ROI on the time is almost always exceptional.