# Web Performance Budgets: Turn Speed Into a Release Gate

> Define and enforce web performance budgets for Core Web Vitals, JavaScript, images, fonts, third parties, and critical journeys in CI and production.

A web performance budget converts 'keep the site fast' into measurable release constraints. Set user-facing experience targets and resource ceilings by page class, measure both controlled lab runs and real-user field data, assign component budgets for JavaScript, images, fonts, and third parties, then fail or review changes that consume more than the agreed allowance.

**A web performance budget is an agreed limit on how slow or heavy a product is allowed to become.** It translates “performance matters” into numbers that design, engineering, analytics, and release systems can enforce.

Without a budget, every feature adds a small script, image, font, request, or hydration cost. Each local decision looks harmless; their sum becomes a slow product. A budget makes performance a resource allocated deliberately rather than a cleanup project after users complain.

## Budget outcomes before bytes

Begin with what users experience:

- how quickly primary content appears
- how soon the page responds to input
- whether the layout moves unexpectedly
- how long a critical journey takes end to end
- how often users see the slow tail

Core Web Vitals provide broadly useful loading, interaction, and stability measures, but a product may also need task metrics such as “search results interactive,” “checkout step complete,” or “dashboard filter applied.”

Write targets at a percentile and for a page class:

```text
Product listing on mobile field traffic:
- loading target at p75
- interaction target at p75
- visual stability target at p75
- filter-to-results latency at p95
```

Percentiles matter. A fast average can coexist with a painful experience for a large minority of users.

Avoid inventing universal numbers disconnected from the product. Establish a baseline, compare competitors where appropriate, and choose thresholds that reflect user expectation and business value while retaining room for regression detection.

## Create page classes

One budget rarely fits an entire site. Define classes such as:

- public landing and acquisition pages
- article or documentation pages
- search and listing pages
- authenticated application shells
- data-heavy dashboards
- checkout or conversion journeys

Assign representative URLs and interactions to each class. A dashboard may legitimately ship more application code than an article, but it still needs an interaction and task-completion target. Page classes prevent the heaviest route from normalizing poor performance everywhere.

## Allocate resource budgets

User metrics can be noisy in CI, so add resource ceilings that teams can act on before runtime:

- compressed JavaScript by route and initial chunk
- CSS size
- image bytes above the fold and total
- font files, variants, and blocking behavior
- request count and critical-request depth
- third-party JavaScript bytes and main-thread time
- server response and edge/cache time
- client hydration or long-task time

Allocate the overall budget to components or teams. For example, reserve a fixed third-party allowance so a new analytics vendor must replace or justify existing cost rather than drawing from an invisible pool.

Track both absolute limits and change deltas:

- **Absolute ceiling** prevents a route from being slow even after a major rewrite.
- **Regression limit** prevents many small changes from consuming the ceiling one pull request at a time.

## Measure in the lab and field

### Lab testing

Controlled tests use consistent hardware, network shaping, cache state, and flows. They are ideal for pull requests because the before/after comparison is reproducible.

Control:

- test runner and browser version
- device and CPU slowdown
- network profile
- geographic test location
- cold versus warm cache
- number of runs and aggregation method
- authenticated state and test data

Run several samples and compare distributions rather than one measurement. Store artifacts such as traces, waterfalls, screenshots, and bundle reports when a gate fails.

### Field monitoring

Real-user monitoring captures the devices, networks, locations, cache states, and interactions that lab tests cannot reproduce fully. Slice by route, device class, geography, release, and connection type while preserving privacy.

Field data tells you whether the chosen lab scenario predicts user experience. A route can pass a desktop CI run and still fail for real mid-range mobile devices. Conversely, a noisy lab result may have no material field impact.

Use lab data to prevent releases and field data to validate the model and identify missing scenarios.

## Build a release gate

A useful CI gate says exactly what failed:

```text
/products mobile cold-load
- initial JS: 218 KiB, budget 200 KiB (FAIL +18 KiB)
- image bytes: 410 KiB, budget 450 KiB (PASS)
- interaction lab p75: 180 ms, budget 200 ms (PASS)

Largest new contributor: reviews-widget.js +24 KiB compressed
```

Make the output actionable: route, scenario, metric, baseline, budget, delta, and likely contributor. A red score without attribution creates arguments about tool noise rather than fixes.

For variable runtime metrics, fail on sustained or statistically meaningful regressions rather than a single outlier. Resource size limits can be strict because their measurements are deterministic.

## Budget third parties explicitly

Third-party scripts often escape normal ownership while consuming network, parse, execution, privacy, and reliability budgets. Inventory each one:

- business purpose and owner
- routes where it loads
- bytes and main-thread time
- network endpoints and failure behavior
- data it receives
- expiry or review date

Load scripts only where needed, defer noncritical work, and test failure or slow response. A tag manager is not an exemption from the performance budget; it is a deployment path that requires stronger governance.

## Define exception policy before the first breach

Some features justify spending performance. An exception should record:

- affected route and metric
- measured user cost
- business reason and approving owner
- mitigation already attempted
- temporary revised limit
- expiry date and repayment plan

Never silently raise the baseline to make CI green. That converts the budget from a constraint into a historical chart.

When a route breaches field targets, pause discretionary weight growth, identify the largest contributors, and recover headroom before adding more. Performance debt compounds because every later feature starts from the slower baseline.

## Make ownership visible

Publish a dashboard showing experience and resource budgets by page class. Review it during architecture and design, not only after implementation. Include the performance impact in pull-request templates for changes that add dependencies, fonts, media, or third parties.

Celebrate deleting bytes and latency the same way the team celebrates shipping features. A budget works when it shapes tradeoffs before code exists.

> [!TIP]
> Give a new feature a budget during design: which page-class allowance will it spend, and what will be removed or optimized if that allowance is already committed?

Use the [Web Vitals Optimizer](/skills/performance/web-vitals-optimizer) to diagnose a failing route, the [Bundle Analyzer](/skills/performance/bundle-analyzer) to attribute JavaScript growth, and [Set Perf Budget](/commands/perf/set-perf-budget) to turn chosen thresholds into repository enforcement.

---

_Source: https://agentscamp.com/guides/performance/web-performance-budgets — Guide on AgentsCamp._
