Use this page for a monthly cost review or a savings target. Cost work is ideal for an agent: the finding is mostly read-only, and the changes are small, reviewable MRs.
Look in this order (biggest, safest wins first)
- Idle resources: unattached EBS volumes, old snapshots, idle load balancers, unused Elastic IPs, stopped instances with large volumes, NAT gateways in empty VPCs.
- Non-production running 24x7: schedule dev and test to stop nights and weekends.
- Oversized compute and databases: CPU under 10 percent for 30 days.
- Storage classes: S3 lifecycle to infrequent access or Glacier; gp2 to gp3 volumes.
- Logs and metrics: CloudWatch log groups with "never expire", high-cardinality custom metrics, verbose debug logging in production.
- Commitments: Savings Plans or reserved capacity only after the above, for steady baseline usage.
Find it (read-only)
# Spend by service, last full month
aws --profile <payer-ro> ce get-cost-and-usage \
--time-period Start=<YYYY-MM-01>,End=<YYYY-MM-01> --granularity MONTHLY \
--metrics UnblendedCost --group-by Type=DIMENSION,Key=SERVICE \
--query 'ResultsByTime[0].Groups[].{svc:Keys[0],usd:Metrics.UnblendedCost.Amount}' --output table
# Unattached volumes
aws --profile <readonly-profile> --region <region> ec2 describe-volumes \
--filters Name=status,Values=available \
--query 'Volumes[].{id:VolumeId,gb:Size,type:VolumeType,created:CreateTime}' --output table
# Log groups with no retention
aws --profile <readonly-profile> --region <region> logs describe-log-groups \
--query 'logGroups[?!retentionInDays].{name:logGroupName,bytes:storedBytes}' --output table
# Rightsizing suggestions
aws --profile <readonly-profile> --region <region> compute-optimizer get-ec2-instance-recommendations \
--query 'instanceRecommendations[].{id:instanceArn,finding:finding,now:currentInstanceType,rec:recommendationOptions[0].instanceType}'
Turn findings into savings
- One ticket per finding type per account, with monthly cost and the evidence.
- Estimate the monthly saving with the price list, not a guess.
- Changes as MRs; deletes follow the staged approach in decommissioning.
- Track: finding, saving estimate, date changed, saving confirmed next month.
| Finding | Account | Est. monthly saving | Status | Confirmed |
|---|---|---|---|---|
<account-alias> |
MR open |
Prevent it coming back
- Required tags (
owner,env,service,cost-center) enforced with tag policies or IaC checks. - Budgets with alerts per account.
- Default log retention in your IaC modules.
- Monthly report of top 10 movers by service and account.
- Cost per request for each service, so growth is not mistaken for a leak.
$$\text{cost per request} = \frac{\text{daily cost}}{\text{daily requests}}$$
For example, 400 USD a day at 20 million requests is 20 USD per million requests. If daily cost jumps to 600 USD with flat traffic, it is 30 USD per million.
Pitfalls
- Deleting snapshots that are the only backup. Check backup policy first.
- Rightsizing a database before peak season based on quiet-month data.
- Counting savings that never showed up on the bill. Confirm next month.