Originally published on the CloudWise blog.

Next year's AWS budget usually starts as a copy of this year's bill with a growth percentage on top.

That is a reasonable shortcut. It has one flaw: the bill you are copying includes everything you pay for and do not use. Copy it forward and the waste stops being a mistake you could fix. It becomes a budget line that someone will defend in March.

So before you lock the number, take an afternoon and split the current bill. This post is the method.

Why the run rate lies

A run rate is a measurement of what you spent, not of what you needed. It cannot tell the difference between a database serving customers and a database nobody has connected to since a migration.

Three things make the copied number worse than it looks:

  1. Waste is quiet. An unattached volume, a load balancer with no healthy targets and a NAT gateway with no traffic all bill by the hour or by the gigabyte-month whether anything uses them or not. Nothing alarms, because nothing is failing.
  2. Growth percentages compound it. If you add a growth factor to a bill that holds waste, you grow the waste too, and you forecast spend that no workload will ever consume.
  3. Budgets get defended. Once a number is in the plan, the team that owns the line has a reason to spend to it.

Step 1: Get a list, not a total

Cost Explorer is built around cost by service and usage type. It does not tell you whether a given resource inside that service was idle. For that you need a resource-level read of the account.

The local CLI does this with read-only credentials you already have:

pip install cloudcostwise cloudcostwise scan --profile my-profile --regions all 

It runs on your machine and sends nothing to CloudWise. Each finding names the waste type, the region, the resource and a monthly cost. Treat that figure as an estimate to confirm against your own bill, not as a promise.

Step 2: Sort every finding into one of three buckets

This is the part that turns a scan into a budget input.

Bucket A: cut before January. Findings where the check takes minutes and a mistake is cheap to undo. A load balancer with no healthy targets is the usual example, once you have confirmed that no DNS record still points at it. Remove these in November or December. Their cost drops out of the run rate you carry forward. Nothing here is check-free: Bucket A is only the findings where the check is short.

Bucket B: check first. Findings where a wrong delete is expensive. A volume in the available state, or a stopped instance. Each needs one specific check before anything is removed, and the post on what to check before you delete a finding lists that check for six common cases. Give each item an owner and a date. If the date is before January, it joins Bucket A once the check passes.

Bucket C: keep. Resources that look idle but are on purpose: a disaster recovery standby, a seasonal workload, a bucket you are required to keep. These stay in the budget, and now they stay as a decision rather than an accident. Write the reason next to the line.

Step 3: Build the number

Take your baseline, say the last full three months of AWS spend. Then:

  • Subtract Bucket A. You are going to remove it, so it should not be budgeted.
  • Subtract Bucket B only for the items whose checks will finish before the year starts. Anything you cannot check in time stays in, with the owner and date noted.
  • Leave Bucket C in.
  • Apply your growth assumption to what is left.

Your forecast is now built on spend that does something. Whether the number goes down a lot or a little depends entirely on your account, and the scan is how you find out. Do not assume.

Two cautions

A subtraction only counts if the delete happens. If Bucket A is still sitting there on January 2, you budgeted a saving you did not take. Put the cleanup on the calendar, not in the document.

Commitments are a different decision. Reserved Instances and Savings Plans change what you pay for compute you do use. Do the waste pass first, because buying a commitment sized to a bill that holds idle resources locks the waste in for the length of the term.

The habit

The budget season is the forcing function, but the split is worth repeating each quarter. Waste does not arrive in a batch. It builds one forgotten resource at a time.

If you review accounts for clients, there is a page for consultants and MSPs, and a client cost review with the credentials you already have walks through a run with someone else's account.

Run it yourself

The CLI is free and source-available (FSL-1.1-ALv2). It runs on your machine, reads your AWS account with your own credentials, and sends nothing to CloudWise. The full list of checks is on the waste checks page.

pip install cloudcostwise cloudcostwise scan --profile my-profile --regions all 

Read-only and free, in a few minutes. AWS bills the scan's Cost Explorer calls; add --no-cost-explorer to skip them. Start at cloudcostwise.io.