AWS / Guide 10

Cost hygiene

Cost Explorer, budgets, the monthly clean-up checklist, Savings Plans and Spot.

AWS bills are rarely high because of one big mistake. They grow from many small ones: an instance nobody stopped, volumes left behind, a NAT gateway moving more data than expected, logs kept forever. Cost hygiene is a monthly routine that finds them, plus paying less for what you keep.

See where the money goes

  • Cost Explorer (Billing and Cost Management): group by Service, then Linked account, then by your CostCenter and Application tags. Look at the last three months side by side; changes matter more than totals.
  • Usage type explains surprises: NatGateway-Bytes, DataTransfer-Regional-Bytes (cross-AZ traffic) and PublicIPv4:InUseAddress often appear in the top ten and are easy to miss.
  • Data Exports (the Cost and Usage Report 2.0 or FOCUS format) to S3, queried with Athena or a dashboard such as the Cloud Intelligence Dashboards, when you need line-item detail or showback reports.
  • Activate cost allocation tags first, or none of the tag views work (Guide 3).
# Last month's cost by service (Cost Explorer API: run from the management account, us-east-1)
$start = (Get-Date -Day 1).AddMonths(-1).ToString('yyyy-MM-dd'); $end = (Get-Date -Day 1).ToString('yyyy-MM-dd')
(Get-CECostAndUsage -TimePeriod @{ Start = $start; End = $end } -Granularity MONTHLY -Metric UnblendedCost `
    -GroupBy @{ Type = 'DIMENSION'; Key = 'SERVICE' }).ResultsByTime.Groups |
    Select-Object @{n='Service';e={$_.Keys[0]}}, @{n='USD';e={ [math]::Round([double]$_.Metrics['UnblendedCost'].Amount, 2) }} |
    Sort-Object USD -Descending | Select-Object -First 15

Each Cost Explorer API request is charged (a cent per request), so don't put it in a loop that runs every minute.

Set budgets and alerts

  • A budget per account (and per cost centre), with alerts at 50%, 80% and 100% of actual spend and at 100% of forecast. Forecast alerts give you time to act before the month ends.
  • Cost Anomaly Detection watches spend by service, account or cost category and emails a daily or weekly summary of unusual jumps. It's free; turn it on in the management account.
  • Budget actions can apply an SCP or IAM policy when a sandbox account passes its budget, stopping further spend without deleting anything.

The monthly clean-up checklist

Find-AwsOrphanedResources.ps1 covers most of this list across every region:

Look forWhy it costs
Unattached EBS volumesCharged per GB-month whether attached or not
Old EBS snapshots and AMIs nobody usesSnapshots of deleted volumes, AMIs from old builds; move long-term ones to the archive tier
Unassociated Elastic IPs, and public IPv4 addresses in generalEvery public IPv4 address is charged hourly
Load balancers with no healthy targetsCharged hourly plus capacity units, doing nothing
Instances stopped for weeksNo compute charge, but volumes and addresses still bill; snapshot and terminate
NAT gateways in non-production VPCsHourly charge per gateway plus per GB processed; share one, or use VPC endpoints for S3 and DynamoDB
Idle RDS instancesStop non-production databases out of hours (they restart automatically after 7 days)
Log groups with no retentionStorage grows forever (Guide 9)
Incomplete multipart uploads in S3Invisible in the console, still stored; add a lifecycle rule to abort them after 7 days

AWS Trusted Advisor and Compute Optimizer list idle and underused resources too; the full set of Trusted Advisor cost checks needs Business support or higher. Cost Optimization Hub collects the recommendations from across the organisation into one list with estimated savings.

Pay less for what you keep

OptionDiscountCommitmentUse for
Compute Savings PlansUp to about 66%$ per hour for 1 or 3 years, any region, family, OS, plus Fargate and LambdaThe default choice for steady compute
EC2 Instance Savings PlansUp to about 72%$ per hour for one instance family in one regionVery stable fleets that won't change family
Reserved InstancesUp to about 72%Specific attributes, 1 or 3 yearsRDS, ElastiCache, OpenSearch and Redshift, which Savings Plans don't cover
Spot InstancesUp to 90%None, but can be interrupted with 2 minutes' noticeBatch, CI, stateless and fault-tolerant work
  • Rightsize first, then commit. A Savings Plan on an oversized fleet locks in the waste.
  • Commit to the floor, not the average: cover the usage that's there at 3 a.m. on a Sunday, and let on-demand and Spot handle the rest. Cost Explorer's Savings Plans recommendations do the maths.
  • Buy centrally in the management account, so the discount is shared across all accounts, and track utilisation and coverage monthly.
  • Graviton instances (Guide 7) stack with Savings Plans for another saving on top.

Storage and data transfer

  • S3 Intelligent-Tiering for data with unknown or changing access patterns; lifecycle rules to move known-cold data to Glacier classes and to expire old versions.
  • gp2 to gp3 for every EBS volume: about 20% cheaper with no downtime (Guide 7).
  • Cross-AZ traffic is charged in both directions. Keep chatty services in the same AZ where the design allows, and use VPC endpoints so S3 traffic doesn't pay NAT processing.
  • Data out to the internet is cheaper through CloudFront than directly from EC2 or S3, and the first 1 TB per month from CloudFront is free.

Make it routine

  • A monthly cost review with the owners of the top ten cost items: what changed, what can go, what to commit to.
  • Stop schedules for non-production (Invoke-AwsEC2PowerSchedule.ps1) and budgets on every sandbox account.
  • Tag compliance as a standing item: untagged cost is cost nobody owns (Get-AwsUntaggedResources.ps1).
  • Show the savings. A monthly note on what was removed and what it saved keeps the routine funded.

Examples to try

From aws.ravindran.in: S3 lifecycle rules, changing storage class, Glacier and VPC gateway endpoints (no NAT charges for S3).