Skip to content

feat(slo): multiwindow burn-rate alerts on a service's AWS bill - #17

Merged
chris13524 merged 2 commits into
mainfrom
chris13524/cost-burn-rate
Oct 9, 2026
Merged

chris13524 merged 2 commits into
mainfrom
chris13524/cost-burn-rate

Conversation

@chris13524

@chris13524 chris13524 commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

What this adds

slo/cost.libsonnet: multiwindow, multi-burn-rate alerting on a service's whole AWS bill against a monthly budget in dollars. It's the SLO burn-rate shape applied to spend.

It watches the account total rather than one usage line, because a regression shows up on whichever line it shows up on. In August–September that was AMP query samples on pay-core and blockchain-api, which ran unnoticed for two months (#16). Cost Explorer shows which line moved once an alert fires.

Tier Long / short window Over the budget's pace by Priority
fast burn 24h / 6h 3× P2
slow burn 72h / 12h 1.5× P3
over budget 7d / 24h 1× P3
data missing 6h, no datapoints — P3

The SLO multiples (14.4×/6×) are for outages. pay-core's AMP regression reached 1.8×, then 3.3×, of a sensible budget, and would have tripped neither. Nothing here pages.

Input and constraints

  • The input is one CloudWatch metric holding the account's cost per billed hour, published from Cost Explorer by a small poller (pay-core's terraform/cost-reporter, in the companion PR). The poller re-writes recent hours as Cost Explorer revises them, so every query reads each hour's Maximum; Sum would count each revision.
  • Settle offset: every window ends 14h back. Measured on pay-core prod, Cost Explorer's newest hour with any cost was ~10h old, and hours younger than ~13h were still partial. A window over unsettled hours under-reads spend and silently misses. This also sets the detection floor at about a day.
  • Metric-search mode, not SQL: Metrics Insights only reaches back three hours. A consumer that patches every CloudWatch model into SQL mode has to skip models that already set metricQueryType, as pay-core's alerts.jsonnet patch now does.
  • Missing data: tiers treat no data as OK, and a separate rule fires when the metric stops arriving, so a broken poller can't silence the tiers indefinitely.

Dashboard panels

From the same budget and tiers as the rules:

  • hourlyPanel: hourly cost, with a line at each tier's hourly pace (1×, 1.5×, 3× of budget/720h).
  • monthPanel: month-to-date spend as a gauge against the budget.
  • trailingPanel: trailing 30-day spend as a gauge against the budget.

There's deliberately no rolling burn-multiple chart. The input must be read at each hour's Maximum, CloudWatch metric math has no moving sum, and Grafana's window transforms aren't available on every instance these dashboards render on.

Tests

tests/cost_smoke.jsonnet (new CI step) pins the allowances, windows, query shape, priorities and the no-data split. promtool can't evaluate CloudWatch queries. Mutation-checked: changing a tier multiple, the settle offset, or the statistic each fails the smoke test.

Consumers: WalletConnect/pay-core#1909, reown-com/blockchain-api#1528.

🤖 Generated with Claude Code

cost.libsonnet: three tiers (3x/24h+6h P2, 1.5x/72h+12h P3, 1x/7d+24h P3)
against a monthly dollar budget, over an hourly-cost CloudWatch metric, with
every window ending 14h back because Cost Explorer reports late. Plus a P3
guard when the metric stops arriving.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@chris13524
chris13524 marked this pull request as ready for review October 7, 2026 14:19
Hourly cost with a line at each tier's pace, plus month-to-date and trailing
30-day spend as gauges against the budget, from the same budget and tiers the
rules use.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@chris13524
chris13524 merged commit 26a7ac7 into main Oct 9, 2026
3 checks passed
@chris13524
chris13524 deleted the chris13524/cost-burn-rate branch October 9, 2026 14:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants