Skip to main content

Budgets are worth little if nothing enforces them, and unenforceable if they fail on the day they land. This separates the two jobs: targets say where we want to be, ratchets stop today's number becoming tomorrow's floor.

Targets

Where the build should get to. Scored and displayed, never build-failing.

MetricCurrentWarn / failVerdict
route_js_kb483.8 KB150 / 250Poor
baseline_js_kb79.6 KB80 / 120Good
doc_html_kb2.8 KB50 / 100Good

The heaviest route is well over its target, and saying so plainly is the point. A dashboard that only shows green has stopped being a measurement.

Ratchets

The measured value at the moment it was accepted. These fail the build when exceeded, and only ever move down — lowering one is how an improvement gets banked.

MetricCurrentCeilingSlack (KB)
route_js_kb483.8630+146.2
baseline_js_kb79.682+2.4
median_route_js_kb213.8372+158.2
total_client_js_kb2205.62270+64.4
doc_html_kb2.85+2.2

Why bundle size specifically

Not everything belongs in a gate. Bundle weight is unusually well suited to one:

  • It is invisible in review — a one-line import can add a hundred kilobytes with nothing in the diff to show it.
  • It is deterministic — the same source produces the same number, so the check does not flake.
  • It is only catchable before shipping — by the time real-user data reflects it, users have already downloaded it.

Measured 2026-09-18 · NODE_ENV=production

Think this pattern could be better? Tell us how.

Leave feedback