AWS Builder Center
Seven Habits That Keep Your AWS Bill Under Control

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 table
Review 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 14
If 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.json
The 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

  1. Check budget alerts and forecast
  2. Open Cost Explorer: what changed?
  3. Review untagged resources
  4. Delete or snapshot anything idle
  5. 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.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article