Investigation practice5 min read

“The AWS bill changed” is not a useful investigation question

It names a symptom, not a scope. Until a question names a cost basis, a boundary, a comparison, and a decision, no amount of billing data can close it.

A symptom is not a question

“The AWS bill changed” has no cost basis, no scope, no comparison, and no decision attached. Any answer to it is either trivially true or impossible to check. The first piece of work in a cost investigation is not analysis. It is rewriting the question into one the evidence can close.

It usually arrives as a forwarded total

Finance sees the invoice or a budget alert and asks engineering to explain the change. That is a legitimate trigger. It is not yet an investigation question, because four things are missing:

  • Which number. Unblended, amortized, or net of credits and discounts. Cost Explorer and a CUR query can disagree about the same month because they are reporting different bases.
  • Which scope. Payer, linked account, service, usage type, region, or tag.
  • Against what. Last month, the same month last year, the forecast, or the budget. A 31-day month against a 30-day month already moves the total by about 3%.
  • For which decision. A re-forecast, a chargeback, an architecture change, a commitment purchase, or nothing at all.

Five checks before any explanation

  1. Fix the cost basis. Pick one and use it for the whole investigation. Unblended shows what usage did. Amortized is the better basis when Savings Plans or Reserved Instances are in the picture.
  2. Normalize for days. Compare daily run-rate, not month totals.
  3. Decompose the delta. Break the change down by linked account, then service, then usage type. Stop at the level where one or two lines explain most of the movement.
  4. Separate rate from usage. For the lines that moved, check whether usage quantity moved or the effective rate moved: commitment coverage expiring, a credit ending, a pricing tier boundary.
  5. Check the non-usage lines. Credits, refunds, tax, support, and one-time fees move the total without anything in the architecture changing.

In CUR 2.0, the line item type does a lot of that separation for you. A first decomposition query, on the unblended basis, against two billing periods:

SELECT
  bill_billing_period_start_date   AS period,
  line_item_usage_account_id       AS account,
  line_item_product_code           AS product,
  line_item_usage_type             AS usage_type,
  line_item_line_item_type         AS item_type,
  SUM(line_item_usage_amount)      AS usage_amount,
  SUM(line_item_unblended_cost)    AS unblended_cost
FROM cur2
WHERE bill_billing_period_start_date >= TIMESTAMP '2026-08-01'
  AND bill_billing_period_start_date <  TIMESTAMP '2026-10-01'
GROUP BY 1, 2, 3, 4, 5
ORDER BY unblended_cost DESC;

Pivot the two periods side by side and sort by the absolute difference. Rows where usage_amount moved are usage questions. Rows where cost moved and usage did not are rate questions. Rows with an item_type of Credit, Refund, Tax, or Fee are usually not architecture questions at all.

Table namecur2 stands in for whatever your Data Exports table is called in Athena. Column names follow the CUR 2.0 schema; check them against your own export before running.

Where, when, and what kind of change

With those checks done, the evidence can support statements like: the movement is concentrated in one account and two usage types; it is a usage change, not a rate change; it starts on a specific day. That is enough to name a likely owner and ask them something specific.

Billing data does not say why

A usage type rising from a given date is consistent with a deploy, a traffic change, a retry loop, a changed lifecycle rule, or a new customer. The bill cannot tell those apart. Tag-based ownership is only as good as tag coverage for that period. And a month-over-month comparison says nothing about whether the new level is wrong. Some increases are the business working.

The output of the first pass is a better question

The first pass does not produce an explanation. It produces a question with a cost basis, a scope, a start date, and someone to ask. For example: “Why did NAT gateway data processing in the shared-services account rise from the 14th, and which workload is sending the traffic?”

Then make one decision: is the movement material enough to investigate further? If yes, name who owns the next check. If no, write down why and close it. Both are acceptable outcomes. Leaving “the bill changed” open for a month is not.

Bring the rewritten question

If your team has already done this first pass and the question still will not close, that is the work the AWS Cost Question Review is for: one question, one evidence memo.

Want more of this, taught live from experience? Join the FinOps workshop waitlist ▶

Yuvdeep builds Kulshan and runs AWS cost investigations from Mission, BC. These notes distinguish observation, estimate, and inference; check your own billing data, region, and architecture.

← Back to Evidence Notes