Something went wrong!
Hang in there while we get back on track
Hidden Costs Investigation
Audit guide for finding hidden AWS costs including CloudWatch Logs retention, S3 versioning bloat, old Lambda versions, orphaned secrets, unused KMS keys, and ECR untagged images. Potential savings: $50-440/month.
Input
What you provide to the skill
My AWS bill is $500/month but I can’t figure out where it’s all going. What hidden costs should I look for?
Output
What the skill generates for you
Hidden AWS Cost Audit
AWS bills often hide costs in small line items that add up. Here’s what to check:
Often-Overlooked Cost Sources
| Hidden Cost | Why It’s Missed | Typical Cost | Difficulty |
|---|---|---|---|
| CloudWatch Logs retention | Default is “never delete” | $10-100/month | Easy |
| S3 versioning bloat | Old versions accumulate | $20-200/month | Medium |
| Old Lambda versions | Versions persist forever | $5-50/month | Easy |
| Orphaned Secrets Manager | $0.40/secret/month | $5-20/month | Easy |
| Unused KMS keys | $1/key/month | $5-20/month | Easy |
| ECR untagged images | $0.10/GB/month | $5-50/month | Easy |
| Data transfer | NAT, load balancers | $50-500/month | Hard |
1. CloudWatch Logs with No Retention
Default retention is “never expire” - logs accumulate forever.
Find log groups without retention:
aws logs describe-log-groups \
--query 'logGroups[?retentionInDays==null].[logGroupName,storedBytes]' \
--output table
Set 30-day retention (adjust based on compliance needs):
# For a single log group
aws logs put-retention-policy \
--log-group-name /aws/lambda/my-function \
--retention-in-days 30
# For all log groups without retention
aws logs describe-log-groups \
--query 'logGroups[?retentionInDays==null].logGroupName' \
--output text | while read group; do
echo "Setting retention for $group"
aws logs put-retention-policy \
--log-group-name "$group" \
--retention-in-days 30
done
Typical savings: $10-100/month
2. S3 Versioning Bloat
If versioning is enabled, old versions stay forever.
Check versioning status:
# List all buckets
aws s3api list-buckets --query 'Buckets[*].Name' --output text | while read bucket; do
status=$(aws s3api get-bucket-versioning --bucket $bucket --query 'Status' --output text)
echo "$bucket: $status"
done
Check storage by version (requires S3 Storage Lens - check in console):
- Go to S3 > Storage Lens > Default dashboard
- Look for “Current version bytes” vs “Noncurrent version bytes”
Set lifecycle rule to delete old versions:
cat > lifecycle.json <<'EOF'
{
"Rules": [
{
"ID": "Delete old versions after 30 days",
"Status": "Enabled",
"NoncurrentVersionExpiration": {
"NoncurrentDays": 30
}
}
]
}
EOF
aws s3api put-bucket-lifecycle-configuration \
--bucket my-bucket \
--lifecycle-configuration file://lifecycle.json
Typical savings: $20-200/month
3. Old Lambda Versions
Lambda keeps all versions forever. Each version consumes storage.
Find functions with many versions:
aws lambda list-functions \
--query 'Functions[*].FunctionName' \
--output text | while read func; do
count=$(aws lambda list-versions-by-function \
--function-name $func \
--query 'length(Versions)' --output text)
echo "$func: $count versions"
done
Delete old versions (keep $LATEST and last 3):
function_name="my-function"
aws lambda list-versions-by-function \
--function-name $function_name \
--query 'Versions[?Version!=`$LATEST`].Version' \
--output text | tr '\t' '\n' | head -n -3 | while read ver; do
echo "Deleting version $ver"
aws lambda delete-function \
--function-name $function_name \
--qualifier $ver
done
Typical savings: $5-50/month
4. Orphaned Secrets Manager Secrets
Each secret costs $0.40/month. Old secrets add up.
List all secrets:
aws secretsmanager list-secrets \
--query 'SecretList[*].[Name,CreatedDate,LastAccessedDate]' \
--output table
Delete unused secrets:
aws secretsmanager delete-secret \
--secret-id my-unused-secret \
--recovery-window-in-days 30
Typical savings: $5-20/month
5. Unused KMS Keys
Active KMS keys cost $1/month each.
List KMS keys:
aws kms list-keys \
--query 'Keys[*].KeyId' \
--output text | while read key; do
aws kms describe-key --key-id $key \
--query 'KeyMetadata.{ID:KeyId,State:KeyState,Created:CreationDate}' \
--output text
done
Disable unused keys (can re-enable later):
aws kms disable-key --key-id arn:aws:kms:us-east-1:123456789012:key/xxxxx
Schedule key deletion (7-30 day waiting period):
aws kms schedule-key-deletion \
--key-id arn:aws:kms:us-east-1:123456789012:key/xxxxx \
--pending-window-in-days 30
Typical savings: $5-20/month
6. ECR Untagged Images
Untagged images from old builds accumulate.
Find untagged images:
aws ecr list-images \
--repository-name my-repo \
--filter tagStatus=UNTAGGED \
--query 'imageIds[*]' \
--output json
Delete untagged images:
repo="my-repo"
aws ecr list-images \
--repository-name $repo \
--filter tagStatus=UNTAGGED \
--query 'imageIds[*]' \
--output json | \
jq -r '.[] | .imageDigest' | while read digest; do
echo "Deleting $digest"
aws ecr batch-delete-image \
--repository-name $repo \
--image-ids imageDigest=$digest
done
Typical savings: $5-50/month
Summary: Total Hidden Cost Potential
| Source | Effort | Monthly Savings |
|---|---|---|
| CloudWatch Logs retention | 1 hour | $10-100 |
| S3 versioning lifecycle | 1 hour | $20-200 |
| Lambda old versions | 30 min | $5-50 |
| Orphaned Secrets | 15 min | $5-20 |
| Unused KMS keys | 15 min | $5-20 |
| ECR untagged images | 30 min | $5-50 |
Total potential savings: $50-440/month = $600-5,280/year
Next Steps
Start with CloudWatch Logs and S3 versioning - they typically have the biggest impact for the least effort.
Share the output of the audit commands and I’ll help you prioritize what to clean up first.
About This Skill
Audit your AWS account to find unused resources, get prioritized cleanup commands, and safely delete cloud clutter to reduce infrastructure costs.
View Skill DetailsMore Examples
Full Account Audit
Comprehensive AWS account audit with prioritized resource checklist, copy-paste CLI commands for 10 resource types, and estimated savings potential of $155-1,040/month.
Safe EBS Volume Cleanup
Step-by-step guide to safely delete 8 unattached EBS volumes with pre-deletion snapshots, safety checklist, deletion commands, and rollback procedures. Estimated savings: $468-540/year.