Cost Optimization That Sticks
Right-size before you commit, buy Savings Plans for your steady baseline, tag everything so you can see where the money goes, and let budgets warn you before the bill does.
Cloud spend rarely explodes in one dramatic moment. It creeps — an oversized instance here, a forgotten environment there. The senior move is to make cost visible and then attack it in the right order.
Right-size first, commit second
Never buy a discount for capacity you do not actually need. Look at Compute Optimizer and CloudWatch: if an m5.2xlarge sits at 8% CPU for a month, it wants to be an m5.large. Right-size the fleet, then price the steady-state.
Cover the baseline with Savings Plans
Whatever compute you run 24/7 is your baseline — buy a Compute Savings Plan for it (up to ~66% off on-demand) and let spiky, unpredictable load run on-demand. For fault-tolerant, interruptible work, Spot instances go up to ~90% off.
Tag everything, or fly blind
You cannot optimize what you cannot attribute. Enforce a tagging standard (Environment, Owner, CostCenter) and activate those as cost allocation tags so Cost Explorer can slice the bill by team and service.
Budgets are your smoke alarm
Set an AWS Budget with alerts at 50/80/100% of forecast. It is far cheaper to get an email on the 12th than a surprise invoice on the 1st.
Example
{
"BudgetName": "monthly-account-cap",
"BudgetType": "COST",
"TimeUnit": "MONTHLY",
"BudgetLimit": { "Amount": "500", "Unit": "USD" },
"CostFilters": {},
"CostTypes": {
"IncludeTax": true,
"IncludeSubscription": true,
"UseAmortized": true
}
}When to use it
- A team saves 40% on steady-state EC2 by purchasing 1-year Compute Savings Plans while keeping 20% of capacity on-demand for bursts.
- An engineer uses AWS Compute Optimizer to downsize 15 over-provisioned EC2 instances from m5.xlarge to m5.large, saving $800/month.
- A startup enables S3 Intelligent-Tiering on their data lake bucket to automatically move cold objects to cheaper tiers without manual lifecycle rules.
More examples
Check Savings Plan Coverage
Shows what percentage of your on-demand compute is covered by Savings Plans each month, identifying gaps.
aws ce get-savings-plans-coverage \
--time-period Start=2024-01-01,End=2024-04-01 \
--granularity MONTHLY \
--query 'SavingsPlansCoverages[].{Month:TimePeriod.Start,Coverage:Coverage.CoveragePercentage}' \
--output tableList Unattached EBS Volumes
Finds EBS volumes not attached to any instance — these accrue storage costs with no value and should be deleted.
aws ec2 describe-volumes \
--filters Name=status,Values=available \
--query 'Volumes[].{ID:VolumeId,Size:Size,Created:CreateTime,Type:VolumeType}' \
--output tableIdentify Idle EC2 Instances
Retrieves daily average CPU for an instance over 7 days; consistently low values indicate a candidate for rightsizing or termination.
aws cloudwatch get-metric-statistics \
--namespace AWS/EC2 \
--metric-name CPUUtilization \
--dimensions Name=InstanceId,Value=i-0abc123 \
--start-time $(date -d '7 days ago' --utc +%FT%TZ) \
--end-time $(date --utc +%FT%TZ) \
--period 86400 \
--statistics Average \
--query 'Datapoints[].{Date:Timestamp,CPU:Average}' \
--output table
Discussion