Performance Budget: Definition, Examples, CI Integration
Performance budget is a set of limits on metrics like JS bundle size, LCP, INP, CLS — enforced in CI to prevent regressions. Stops perf rot before deploy.
What is a performance budget?
A performance budget is a set of explicit limits on web performance metrics — bundle sizes, page weight, Core Web Vitals (LCP, INP, CLS), request counts, third-party script weight — that the team commits to staying under. Enforced in CI, the budget fails builds that exceed limits, preventing performance regressions from shipping.
Without a budget, perf rot is invisible: each PR adds a few KB of JS, a few hundred ms of script time. After 6 months of additions, the page is 3× heavier and twice as slow — but no single PR "caused" it. A budget makes the cost visible at the moment of merge.
Categories of performance budgets
| Type | What it limits | Example |
|---|---|---|
| Quantity-based | Number of resources | ≤ 50 HTTP requests |
| Size-based | Bytes transferred | JS < 200KB gzipped |
| Time-based | Performance metrics | LCP < 2.5s on 4G |
| Score-based | Lighthouse / synthetic scores | Lighthouse Perf ≥ 90 |
| Rule-based | Specific anti-patterns | No render-blocking JS |
Example performance budget
# budget.json (Lighthouse format)
[
{
"path": "/*",
"timings": [
{ "metric": "interactive", "budget": 3000 },
{ "metric": "first-contentful-paint", "budget": 1500 }
],
"resourceSizes": [
{ "resourceType": "script", "budget": 200 },
{ "resourceType": "image", "budget": 500 },
{ "resourceType": "stylesheet", "budget": 50 },
{ "resourceType": "document", "budget": 30 },
{ "resourceType": "font", "budget": 100 },
{ "resourceType": "third-party", "budget": 200 },
{ "resourceType": "total", "budget": 1500 }
],
"resourceCounts": [
{ "resourceType": "third-party", "budget": 10 }
]
}
]Recommended baselines
| Metric | Good budget | Stretch goal |
|---|---|---|
| LCP | < 2.5s | < 1.8s |
| INP | < 200ms | < 100ms |
| CLS | < 0.1 | < 0.05 |
| JS bundle (gzipped) | < 200KB | < 100KB |
| Total page weight | < 1.5MB | < 1MB |
| HTTP requests | < 50 | < 30 |
| Lighthouse Perf score | ≥ 90 | ≥ 95 |
| Third-party requests | < 10 | < 5 |
Adjust based on your audience. Mobile-heavy apps in emerging markets need stricter budgets than desktop B2B SaaS.
Tools to enforce budgets
| Tool | How it enforces |
|---|---|
| Lighthouse CI | Runs Lighthouse on every PR; fails if budget exceeded |
| SpeedCurve | Tracks budget over time; alerts on regression |
| Bundle Analyzer (webpack/Vite) | Visualizes bundle composition; CI rule on size |
| size-limit | NPM package; CI fails if bundle exceeds limit |
| WebPageTest CI | Field-grade testing in CI |
| Calibre | Performance monitoring + budgeting platform |
| Lighthouse (manual) | Local dev: run before merging |
| Cloudflare Observatory | Synthetic tests with budgets |
Where to start: defining your first budget
- Audit current performance with Lighthouse (3-5 representative pages)
- Set budget at current baseline (or slightly tighter — e.g., -10%)
- Add Lighthouse CI to GitHub Actions / GitLab CI
- Fail PRs that exceed budget
- Iterate: tighten budget as team improves perf
Performance budget best practices
- Start with current performance. Aim for slight improvements, not aspirational targets that fail every PR.
- Budget per page type. Marketing pages and dashboards have different needs.
- Fail loudly in CI. Block merge until fixed; don't let warnings accumulate.
- Track trends. Single Lighthouse run is noisy; aggregate over time.
- Test on slow devices. Lighthouse simulates throttled conditions; reflect real users.
- Track third-party impact separately. Often the bloat source.
- Owner per metric. Make it someone's job to defend each budget line.
- Visible in dashboard. Bonus: in PR comments + dashboard.
Common pitfalls
- Aspirational budgets. Set so tight that every PR fails; team disables CI.
- No follow-up on regressions. Budget warnings ignored = no enforcement.
- Per-PR variance. Single Lighthouse run varies ±5%; use multiple runs.
- Lab-only testing. Budget passes synthetic but real users still suffer; combine with RUM.
- Forgetting third-party. Marketing adds Hotjar + Intercom + ad pixels; budget exceeded silently.
- Page-level only. Critical user flows (checkout, signup) need their own budgets.
- No budget for new pages. Greenfield pages launch over-budget; never get fixed.
Performance budget vs SLI/SLO
| Aspect | Performance Budget | SLI/SLO |
|---|---|---|
| When measured | Build time (lab) | Production (field) |
| Enforced via | CI failing PRs | Alerts + error budgets |
| Owner | Frontend team | SRE / platform |
| Best at preventing | Code-side regressions | Infra incidents |
Use both: budget catches regressions before deploy; SLO catches issues in prod.
FAQ: Performance budget
What's a good starter budget?
LCP < 2.5s, JS < 200KB gzipped, Lighthouse Perf ≥ 90 on a typical mobile profile. Tighten over time.
How is this different from Core Web Vitals?
CWV are the metrics. Performance budget = your team's commitment to specific limits on those metrics.
Can I budget per page?
Yes. Lighthouse CI supports per-URL budgets. Marketing pages might have stricter LCP than dashboards.
Should I budget on lab or field data?
Both. Lab (Lighthouse) for CI; field (CrUX/RUM) for production monitoring.
What if PR exceeds budget but for good reason?
Two paths: (1) raise budget consciously with team approval, (2) optimize until under budget. Don't "temporarily" bypass.
How often should budgets be reviewed?
Quarterly. Tighten if consistently passing; investigate if frequently failing.
Do single-page apps need different budgets?
Yes — bigger JS bundles allowed, but TTI/INP critical. Track route transition perf too.
Enforce your performance budget with LoadFocus
LoadFocus runs Lighthouse audits from 25+ regions on a schedule, alerting when metrics breach your budget. Sign up free at loadfocus.com/signup.
Related LoadFocus Tools
Put this concept into practice with LoadFocus — the same platform that powers everything you just read about.