· Updated · 4 min read

The cloud cost checklist we run before every audit

Most cloud bills hide the same handful of wins. Here are the items we look at first — and what they typically save.

Cloud costAWS

Cloud bills are a great mirror of engineering decisions made years ago that no one has revisited. Before recommending anything complicated, we walk the bill against a short checklist. Most accounts have 20–40% of spend that comes out without rewriting a single line of code.

The checklist uses AWS names, but every item has a direct equivalent on Google Cloud and Azure.

Before you start: make spend visible

You can't cut what you can't attribute. Before touching anything, make sure you can answer "who owns this cost?" for most of the bill:

  • Turn on Cost Explorer and the detailed Cost and Usage Report.
  • Tag resources with at least an owner, a service, and an environment, and activate those tags for cost allocation.
  • Separate production and non-production into different accounts, which makes that split visible without any tagging at all.
  • Set budgets with alerts per account or team, so surprises surface within days instead of at the end of the month.

1. Idle and forgotten resources

Old EBS volumes detached from terminated instances. Test environments running 24/7 that no one uses. Load balancers in front of services that were retired six months ago. Elastic IPs allocated but never attached. A monthly sweep of resources with zero traffic in the last 30 days routinely surfaces real spend.

For non-production environments that are needed, but not around the clock, schedule them. Shutting development environments down outside working hours removes about two thirds of their compute hours.

2. Right-sizing and Graviton

Most workloads run on instance types chosen during the original deploy and never revisited. Compute Optimizer data plus a few hours of analysis usually finds 20–30% savings from right-sizing alone. Look at memory as well as CPU — EC2 doesn't report memory usage to CloudWatch without the CloudWatch agent, so many teams size on half the picture.

On AWS, switching to Graviton (ARM) instances is often another 20% on top. Many workloads need no code changes: most interpreted, JVM, and Go services just need multi-architecture container images. Managed services such as RDS and ElastiCache offer Graviton instance classes too, which is often the easiest win of all.

3. Kubernetes requests and limits

In Kubernetes, nodes are sized by what pods request, not what they use. Requests copied from a template years ago commonly reserve several times the CPU and memory workloads actually consume, and the cluster autoscaler dutifully pays for the gap. Compare requests to real usage, lower the worst offenders, and let the autoscaler consolidate onto fewer nodes. For fault-tolerant workloads, spot instances cut node cost much further.

4. Storage class and lifecycle

S3 buckets that hold years of archival data on Standard pricing. Snapshots kept forever "just in case". Logs in CloudWatch with no retention policy. A lifecycle policy that moves cold data to cheaper storage classes or deletes it after N days is one of the highest-ROI changes you can make.

  • Set a retention period on every CloudWatch log group; by default logs are kept forever.
  • Use S3 Intelligent-Tiering for buckets with unpredictable access patterns.
  • Expire old snapshots and AMIs with Data Lifecycle Manager or AWS Backup policies.
  • Move gp2 volumes to gp3, which is cheaper per GB and lets you provision IOPS separately.

5. Commit-based discounts

If you're running on-demand instances at steady state, you're leaving 20–40% on the table. Savings Plans and Reserved Instances are paperwork wins, but they require enough confidence in your forecast to commit. Right-size first — committing to oversized instances locks in the waste — then cover the steady baseline, not the peak. Compute Savings Plans are the flexible default because they apply across instance families and regions, and to Fargate and Lambda as well.

6. Cross-AZ traffic, egress, and NAT

Cross-AZ traffic and NAT gateway data processing are silent killers. Architectures that chatter across availability zones or send all egress through a single NAT can show up as thousands per month in line items most teams don't recognize.

  • Add gateway VPC endpoints for S3 and DynamoDB. They are free and take that traffic off the NAT gateway.
  • Use interface endpoints for other heavily used AWS APIs where the traffic volume justifies them.
  • Keep chatty services and their databases in the same availability zone where your resilience requirements allow it.
  • Check data transfer line items for unexpected internet egress, such as backups or logs shipped to another provider.

Making it stick

A one-off clean-up decays within months unless cost becomes part of normal engineering. Show each team its own spend, review the biggest changes monthly, and treat a cost regression like any other regression: something to catch in review, not on the invoice. Infrastructure as code helps, because a right-sized instance in Terraform stays right-sized.

None of these items require a big project; the hardest part is finding the time to look. A cost review is part of our cloud infrastructure work, and right-sizing helped a fintech client lower monthly cloud spend by 38% during their move to Kubernetes. If your bill keeps growing faster than your business, get in touch.

Let's build something awesome.

Tell us about your infrastructure or product challenge. We'll reply within one business day.