Chapter 5.55 of 9 in this part

Cost in CI

Budget alerts cannot be the control, because the vendors document how slow they are — AWS Budgets updates up to three times a day, 8–12 hours apart, and Google states that an alerts-only budget is not a hard cap. The gate has to move to the pull request.

5 min read·revised 2026-08-11

Everything so far measures cost after it has been incurred. This chapter is about the one place a cost decision can still be cheap to reverse: before the change is merged.

The argument for doing it there is not aesthetic. It is that the billing-side alerting most teams rely on is, by the vendors' own documentation, far too slow to function as a control.

What the alerting layer actually promises

AWS Budgets information "is updated up to three times a day", and "updates typically occur 8–12 hours after the previous update."

Google Cloud is blunter about the limitation. Its budget documentation carries a caution that for alerts-only budgets, "the budget doesn't automatically set a hard cap on spending", recommends setting the budget amount below available funds to account for reporting delay, and notes that after creating a budget "it may take several hours before receiving the first email or Pub/Sub notification" — on top of the separate delay between using a resource and that usage reaching Cloud Billing.

Azure notes that a newly created subscription may take up to 48 hours before all Cost Management features are usable, though a budget can be configured at creation time.

Put the AWS figure in operational terms, because it is the most precise of the three. If updates arrive up to three times a day and consecutive updates are typically 8–12 hours apart, then a spend change that begins immediately after an update may be invisible for up to roughly 12 hours, and the alert that follows describes money already spent. On a runaway agent loop or an accidental expensive-tier deployment, twelve hours is not a warning. It is a post-mortem.

None of this is a vendor failing. Billing pipelines aggregate across regions and services and cannot be real-time at that scale. It is a design constraint, and the correct response to a design constraint is to put the control somewhere else.

The three gates, cheapest first

1. The pull request. Static checks against the diff, before anything runs. These catch the largest class of avoidable cost because they catch it before it exists:

  • an accelerator instance type appearing in infrastructure code that is not on the approved list
  • a model identifier changing to a more expensive tier
  • a removed or weakened max_tokens, step limit, or loop bound
  • a new always-on resource with no autoscaling or schedule attached
  • a storage class or retention change that quietly makes data permanent

These are grep-and-policy checks, not forecasts. They are unglamorous and they are the highest-yield thing in this chapter, because the cost of failing them is a code-review comment.

2. The plan step. Where infrastructure-as-code produces a diff before applying, that diff is a cost artifact. A resource count and instance family are enough to reject a change without predicting a dollar figure — and rejecting on "this adds four always-on GPU instances" is more defensible than rejecting on an estimate anyone can argue with.

3. Runtime ceilings. Hard caps that fail closed: request budgets, per-job token limits, step counts, timeouts. These are the only layer that acts inside the twelve-hour window above, which is precisely why they cannot be optional.

Billing alerts sit below all three. They remain worth having — as detection of the thing every gate missed, not as the gate.

Make it a comment, not a wall

The rule that decides whether cost-in-CI survives contact with a team: fail the build only on the checks that are objective.

An instance type not on the approved list is objective. A missing token cap is objective. "This change looks expensive" is a forecast, and forecasts that block merges get disabled within two sprints — usually during an incident, permanently.

So: hard-fail the deterministic policy checks, and post everything else as a comment on the pull request. A comment that says "this adds two p5 instances; current approved list is g6 and below" changes the design conversation without ever becoming the thing standing between a team and a deploy.

What to do with the vendor alerts you keep

Because they are lagging by design, the useful configuration is different from the intuitive one.

  • Alert on forecast as well as actual. AWS Budgets supports alerting on both accrued and forecasted spend; forecast alerts are the only ones with any chance of arriving before the money is gone.
  • Set the threshold below the number that matters, exactly as Google's documentation recommends, because the reporting delay means the real figure is always ahead of the reported one.
  • Wire the notification to a channel with an owner, not to an inbox. An alert with a twelve-hour head start still needs someone to read it.
  • Where a hard stop is genuinely required, use an action, not an alert. AWS Budgets can run a budget action when a threshold is crossed — applying an IAM policy or a service control policy, or targeting specific EC2 or RDS instances, either automatically or after manual approval. That is a control. Note the documented boundary: from a management account you can apply an SCP to another account, but you cannot target that account's EC2 or RDS instances.

The honest limit of this chapter

The latency figures above are quoted from vendor documentation and are checkable. The gate design is not measured — no vendor publishes data on how much spend pull-request checks prevent, and this book will not invent a percentage for it.

What the sources do establish is the load-bearing claim, and it is enough to act on: the billing-side alert cannot be your control, because all three providers document a delay between spend and signal, and one of them states outright that an alerts-only budget is not a cap. Everything else in this chapter follows from taking that sentence seriously rather than assuming the dashboard is watching.

Sources & methodcaptured 2026-08-11

Sources, captured 2026-08-11: AWS Cost Management User Guide, "Managing your costs with AWS Budgets" — budgets updated up to three times a day, updates typically 8–12 hours apart, and alerting on both actual and forecasted spend; "Configuring budget actions" — IAM policy or SCP actions, EC2/RDS instance targeting, automatic or manual-approval execution, and the cross-account targeting limitation. Google Cloud Billing, "Create, edit, or delete budgets and budget alerts" — the caution that alerts-only budgets do not set a hard cap on spending, the recommendation to set the amount below available funds because of reporting delay, and the note that the first notification may take several hours. Microsoft Azure Cost Management + Billing, "Understand Cost Management data" — up to 48 hours before all features are usable on a new subscription. The ~12-hour worst-case blind window is computed by this book from AWS's documented 8–12 hour update spacing; the three-gate design and the fail-versus-comment rule are editorial judgment, labelled as such. No figure is asserted for spend prevented by CI checks, because none is sourceable.

Want this done on your account rather than by you?

The handbook is the method, written out in full so you can run it yourself — that is the point of publishing it. If you would rather someone else did the first pass, the teardown is free and you keep the findings either way.