Free, in full, no email gate

The AWS Cost Leak Self-Audit

ten checks read-only one afternoon

Ten checks a competent engineer can run in an afternoon, read-only.

Industry surveys consistently put self-reported cloud waste at 27 to 29 percent of spend, and the number went up in 2026, driven by AI workloads. Most of it hides in the same ten places. This is the checklist I run at the start of every paid assessment; there is nothing secret about the what. Hand it to one of your engineers, give them read-only billing access and an afternoon, and you will find real money.

Every command below is read-only. Nothing here changes your infrastructure.

Before you start

You need: Cost Explorer access (ce:Get*), the AWS CLI with a read-only profile, and 3 to 4 hours. In Cost Explorer, set the cost metric to amortized: unblended numbers mislead anywhere commitments exist.

One rule as you go: write down the monthly dollar figure next to every leak you find. Un-priced findings never get fixed.

01Commitments (Savings Plans / Reserved Instances)

The most money in the least time. In Cost Explorer, under the Savings Plans and Reservations reports, check utilization and coverage:

aws ce get-savings-plans-utilization --time-period Start=<90d-ago>,End=<today>
aws ce get-savings-plans-coverage    --time-period Start=<90d-ago>,End=<today>
  • Utilization under ~90%: you are paying for commitment you don't use.
  • Coverage under ~70% on compute that runs 24/7: you are paying on-demand rates for predictable usage.
  • List every commitment's end date. An expiry you haven't planned for is next quarter's bill shock.

02Compute you don't need

aws compute-optimizer get-ec2-instance-recommendations --filters name=Finding,values=Overprovisioned
aws ec2 describe-addresses --query 'Addresses[?AssociationId==null]'
  • Compute Optimizer's overprovisioned list (enable it if it isn't: free, takes a day).
  • Previous-generation instance families (t2, m4, c4, r4): same workload, newer generation or Graviton, less money.
  • Non-prod environments running nights and weekends: pull daily-granularity spend on your dev and staging accounts and look at the weekend line. Flat curve = money burning while everyone sleeps.
  • Unattached Elastic IPs: small, but pure waste.

03Kubernetes over-requesting

If you run EKS: compare what workloads request to what they use. Your node bill follows requests, not usage.

kubectl top nodes
kubectl describe nodes | grep -A5 "Allocated resources"

Requests at 3 to 4x actual usage is the most common finding in this category. It means you could be running the same workloads on a fraction of the nodes. Also check for load balancers that no longer point at anything.

04Databases

aws rds describe-db-instances --query 'DBInstances[].[DBInstanceIdentifier,DBInstanceClass,StorageType]'
  • Any instance with ~zero connections over two weeks (CloudWatch DatabaseConnections): idle instances and forgotten read replicas are everywhere.
  • gp2 storage anywhere: gp3 is the same durability for ~20% less.
  • Provisioned IOPS (io1/io2) far above what CloudWatch shows you consuming.
  • Manual snapshots from years ago; nobody remembers why they exist and they bill monthly.

05NAT gateways and data transfer

The sneakiest category. In Cost Explorer, group by usage type and search NatGateway-Bytes and DataTransfer.

  • Heavy NAT processing charges usually mean traffic to S3 or DynamoDB routing through NAT. Gateway VPC endpoints for those services are free and end that charge.
  • Large cross-AZ transfer (Regional-Bytes) means chatty services split across zones.

06EBS volumes and snapshots

aws ec2 describe-volumes --filters Name=status,Values=available
aws ec2 describe-volumes --filters Name=volume-type,Values=gp2

Unattached volumes bill full price for storing nothing. Snapshot chains from instances that no longer exist. Old AMIs nobody ever launched.

07S3 lifecycle

For every bucket whose name contains log, backup, or archive:

aws s3api get-bucket-lifecycle-configuration --bucket <bucket>

An error means no lifecycle policy: that bucket grows forever at Standard rates. Also check versioned buckets for a noncurrent-version expiration rule, and look for incomplete multipart uploads (invisible in the console, real on the bill).

08Logs and observability

aws logs describe-log-groups --query 'logGroups[?retentionInDays==null].[logGroupName,storedBytes]'

Log groups with no retention setting keep every byte forever. This check alone pays for the afternoon at most companies. If CloudWatch is a top-five service in your bill, split it by usage type: ingestion-heavy means debug logging or full-capture flow logs in prod. Same logic applies to Datadog: indexed-log volume and retention tiers on your noisiest sources.

09AI workloads

The fastest-growing leak. In Cost Explorer, filter to Bedrock, SageMaker, and GPU instances:

  • Bedrock spend by model: are high-volume classification and extraction calls running on a frontier model when a smaller one scores the same on your task?
  • Prompt caching on anything with a repeated prefix; batch inference (half price) on anything that doesn't need real-time.
  • SageMaker endpoints with zero invocations in two weeks: idle endpoints bill 24/7.
  • GPU instances: if you can't answer "what's our GPU utilization," that is itself the finding.

10Can you even tell who spends what?

Check your cost-allocation tag coverage: total spend versus spend attributable to a team or feature. Under ~60% attribution, nobody owns any number, and every category above regrows after you cut it. Tagging isn't a savings line: it's what makes savings stick.

What this doesn't do

Run honestly, this checklist finds the leaks. What it doesn't give you: each item priced in first-year dollars from your own CUR data, ranked against engineering effort and production risk, with a rollback path and a named verification method, so your team knows what to fix first and can prove the bill actually moved.

That's the paid version. It's a fixed price, read-only, delivered in ten business days, and if you go on to fix things with me the fee is credited in full. If your team runs this checklist and ships the fixes themselves: genuinely, good. That was the point.