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
CostCenterandApplicationtags. 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) andPublicIPv4:InUseAddressoften 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 for | Why it costs |
|---|---|
| Unattached EBS volumes | Charged per GB-month whether attached or not |
| Old EBS snapshots and AMIs nobody uses | Snapshots of deleted volumes, AMIs from old builds; move long-term ones to the archive tier |
| Unassociated Elastic IPs, and public IPv4 addresses in general | Every public IPv4 address is charged hourly |
| Load balancers with no healthy targets | Charged hourly plus capacity units, doing nothing |
| Instances stopped for weeks | No compute charge, but volumes and addresses still bill; snapshot and terminate |
| NAT gateways in non-production VPCs | Hourly charge per gateway plus per GB processed; share one, or use VPC endpoints for S3 and DynamoDB |
| Idle RDS instances | Stop non-production databases out of hours (they restart automatically after 7 days) |
| Log groups with no retention | Storage grows forever (Guide 9) |
| Incomplete multipart uploads in S3 | Invisible 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
| Option | Discount | Commitment | Use for |
|---|---|---|---|
| Compute Savings Plans | Up to about 66% | $ per hour for 1 or 3 years, any region, family, OS, plus Fargate and Lambda | The default choice for steady compute |
| EC2 Instance Savings Plans | Up to about 72% | $ per hour for one instance family in one region | Very stable fleets that won't change family |
| Reserved Instances | Up to about 72% | Specific attributes, 1 or 3 years | RDS, ElastiCache, OpenSearch and Redshift, which Savings Plans don't cover |
| Spot Instances | Up to 90% | None, but can be interrupted with 2 minutes' notice | Batch, 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).