
Seven Habits That Keep Your AWS Bill Under Control
Surprise bills usually come from a handful of small oversights, not big architecture mistakes. These seven habits catch most of them early, and none of them slow your team down
Most surprise AWS bills have boring causes: a forgotten test environment, logs that never expire, a volume nobody remembers creating. The good news is that a few lightweight habits catch nearly all of it. Here are seven I'd set up in any account, ideally in the first week.
1. Set a budget alert on day one
Before you build anything, create a monthly cost budget in AWS Budgets and add email alerts at a few thresholds (for example 50%, 80%, and 100% of what you expect to spend). Also add an alert on forecasted spend, which warns you before you cross the line rather than after.
It takes five minutes and is the single cheapest insurance you can buy.
2. Tag everything, and activate the tags
Tags like
project, owner, and environment turn a single opaque bill into something you can actually investigate. One detail people miss: user-defined tags only show up in cost reports after you activate them as cost allocation tags in the Billing console, and they only apply going forward.Pick a small, consistent set and enforce it in your infrastructure-as-code templates so nobody has to remember.
3. Look at Cost Explorer every week
Spend five minutes weekly in Cost Explorer. Group by service first, then by tag. You're looking for one thing: what changed since last week? A new line item or a sudden jump is far easier to explain when it's seven days old than when it's thirty.
4. Hunt for idle resources
These are the usual suspects:
- Unattached EBS volumes and old snapshots
- Unused Elastic IP addresses (public IPv4 addresses are billed)
- Load balancers with no healthy targets or traffic
- Stopped instances that still have large attached volumes
- NAT gateways in dev accounts nobody uses
You can list unattached volumes from the CLI:
1
2
3
4
aws ec2 describe-volumes \
--filters Name=status,Values=available \
--query "Volumes[].{ID:VolumeId,SizeGiB:Size,Created:CreateTime}" \
--output tableReview the output before deleting anything, and snapshot first if you're unsure.
5. Set log retention
By default, CloudWatch Logs keeps log groups forever. Set a retention period that matches how long you really look at them:
1
2
3
aws logs put-retention-policy \
--log-group-name /aws/lambda/my-function \
--retention-in-days 14If you define Lambda functions with CloudFormation or SAM, create the log group explicitly with a
RetentionInDays property so every environment gets it automatically.6. Add S3 lifecycle rules
Data that nobody reads shouldn't sit in the most expensive storage class. A lifecycle rule can move objects to a cheaper class and eventually delete them:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"Rules": [
{
"ID": "age-out-logs",
"Status": "Enabled",
"Filter": { "Prefix": "logs/" },
"Transitions": [
{ "Days": 30, "StorageClass": "STANDARD_IA" }
],
"Expiration": { "Days": 365 },
"AbortIncompleteMultipartUpload": { "DaysAfterInitiation": 7 }
}
]
}1
2
3
aws s3api put-bucket-lifecycle-configuration \
--bucket my-bucket \
--lifecycle-configuration file://lifecycle.jsonThe multipart cleanup rule is easy to forget: abandoned uploads are invisible in normal listings but still cost money. If your access patterns are unpredictable, look at S3 Intelligent-Tiering instead.
7. Right-size first, then commit
Once a workload is stable, use AWS Compute Optimizer to see whether your instances are bigger than they need to be. Only after right-sizing should you consider Savings Plans or Reserved Instances, because committing to capacity you're about to shrink locks in waste.
Start with a small commitment that covers your steady baseline, and leave bursty or experimental usage on demand.
A simple weekly checklist
- Check budget alerts and forecast
- Open Cost Explorer: what changed?
- Review untagged resources
- Delete or snapshot anything idle
- Confirm new log groups and buckets have retention or lifecycle rules
Wrapping up
None of these habits require special tooling or a dedicated FinOps team. They work because they're small, regular, and set up early. Pick two from this list and do them today, then add the rest as you go.
Pricing and defaults change over time, so check the current AWS documentation for each service before relying on specifics.
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article