Read-only AWS cost checklist
The AWS Cost Leak Self-Audit
Ten read-only checks an engineer can run in an afternoon.
This checklist covers ten common sources of unnecessary AWS spend. Give an engineer read-only access to the relevant billing and resource metadata, then use the results to identify which areas deserve deeper analysis.
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 a few hours once access is ready. In Cost Explorer, use amortized cost when reviewing periods affected by Savings Plans or Reserved Instances so the commitment cost is distributed across the covered usage.
Record the estimated monthly impact beside every finding. A cost item is easier to prioritize when its financial effect is explicit.
01Commitments (Savings Plans / Reserved Instances)
Start with commitment utilization and coverage because these can materially affect the bill. In Cost Explorer, under the Savings Plans and Reservations reports, check:
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% may indicate that part of a purchased commitment is going unused.
- Coverage under ~70% on steady 24/7 compute may indicate that a material share of predictable usage is still billed on demand.
- Record each commitment's end date so finance and engineering can review renewal options before the rate changes.
02Unused and overprovisioned compute
aws compute-optimizer get-ec2-instance-recommendations --filters name=Finding,values=Overprovisioned
aws ec2 describe-addresses --query 'Addresses[?AssociationId==null]'
- Review Compute Optimizer's overprovisioned recommendations where the service is already enabled.
- For previous-generation instance families such as t2, m4, c4, and r4, compare current-generation x86 and Graviton options, then validate workload compatibility and performance.
- For non-production environments, compare daily spend on working days with nights and weekends. A flat curve may indicate that compute is running outside the required schedule.
- Review unattached Elastic IPs, then confirm whether each one is still required.
03Kubernetes over-requesting
If you run EKS and have read access to cluster metrics, compare what workloads request with what they use. Kubernetes schedules pods against requests, so sustained over-requesting can increase the node capacity the cluster needs.
kubectl top nodes
kubectl describe nodes | grep -A5 "Allocated resources"
Large, sustained gaps between requests and measured usage may indicate that workloads can be right-sized and nodes consolidated. Validate peaks, autoscaling behavior, and workload constraints before changing requests. Also check for load balancers that no longer serve an active workload.
04Databases
aws rds describe-db-instances --query 'DBInstances[].[DBInstanceIdentifier,DBInstanceClass,StorageType]'
- Flag instances or read replicas with near-zero connections over two weeks in CloudWatch (
DatabaseConnections), then confirm whether they still serve a scheduled or failover purpose. - Compare
gp2storage with gp3 pricing and performance in the relevant region. gp3 is often less expensive, but required IOPS and throughput still need to be checked. - Compare provisioned IOPS on io1 and io2 volumes with observed IOPS and latency.
- Review old manual snapshots with the owning team before changing retention or deleting anything.
05NAT gateways and data transfer
In Cost Explorer, group by usage type and search NatGateway-Bytes and DataTransfer.
- If NAT processing is material, check whether S3 or DynamoDB traffic is routing through it. Gateway VPC endpoints have no hourly or data-processing charge and can avoid NAT processing for traffic routed through the endpoint.
- For material cross-AZ transfer (
Regional-Bytes), identify the services generating it and determine whether the topology is intentional for resilience.
06EBS volumes and snapshots
aws ec2 describe-volumes --filters Name=status,Values=available
aws ec2 describe-volumes --filters Name=volume-type,Values=gp2
Review unattached volumes, snapshots associated with retired resources, and AMIs that have not been launched recently. Confirm ownership, retained data, rollback requirements, and retention policy before deleting anything.
07S3 lifecycle
For every bucket whose name contains log, backup, or archive:
aws s3api get-bucket-lifecycle-configuration --bucket <bucket>
A NoSuchLifecycleConfiguration response means the bucket has no lifecycle policy. Treat permission and request errors separately. Also check versioned buckets for noncurrent-version rules and review incomplete multipart uploads, which retain uploaded parts until they are completed or aborted.
08Logs and observability
aws logs describe-log-groups --query 'logGroups[?retentionInDays==null].[logGroupName,storedBytes]'
Log groups with no retention setting keep every byte indefinitely. If CloudWatch is a top-five service in your bill, split it by usage type. High ingestion may come from debug logging or full-capture flow logs in production. Apply the same review to Datadog indexed-log volume and retention tiers.
09AI workloads
Review Bedrock and SageMaker in Cost Explorer. For EC2 GPU instances, use resource inventory, tags, and billing usage types to identify the relevant instance families.
- For Bedrock spend by model, identify high-volume tasks that may be candidates for evaluation on a lower-cost model. Change models only after testing against the workload's quality requirements.
- Check for repeated prompt prefixes that may benefit from prompt caching. For work that does not require real-time responses, compare supported batch-inference pricing and constraints.
- Review SageMaker endpoints with no recent invocations, then confirm whether they support scheduled, failover, or infrequent workloads.
- For GPU instances, compare accelerator utilization with provisioned capacity and identify sustained periods of idle or lightly used time.
10Cost allocation and ownership
Check your cost-allocation tag coverage: total spend versus spend attributable to a team, product, or environment. Low attribution limits ownership, unit-cost analysis, and the ability to verify whether savings persist after a change.
What this doesn't do
This checklist can surface areas to investigate, but it does not calculate each item's impact from the available billing data, rank the work against engineering effort and production risk, or provide rollback and billing-verification plans.
The paid assessment adds that analysis in a fixed-price, read-only engagement delivered within ten business days. If your team can validate and implement the findings directly, the checklist has done its job.