All posts
Performance Budgets|6 min read

How to set performance budgets that actually work

Performance budgets only work when they are enforced. Here is a proven framework for setting, enforcing, and iterating on budgets for LCP, INP, CLS, and JavaScript bundle size.

M

Marcus Webb

Engineering Lead, PagePulse · May 28, 2025

Most teams set performance budgets at some point. Most teams also abandon them within a quarter. The reason is almost always the same: the budgets were aspirational rather than measurable, and they were never enforced in CI. This guide walks through a framework that has worked across dozens of teams.

Start from real-user data

Never set a budget by guessing. Pull the 75th percentile of LCP, INP, CLS, FCP, and TTFB for each route from your RUM tool. If your dashboard LCP is currently 3.2s, do not set a 2.5s budget tomorrow. Set a 3.0s budget, hit it for a sprint, then tighten to 2.7s, then 2.5s. Budgets that feel achievable get enforced; budgets that feel impossible get ignored.

Categorize by route, not by site

Your marketing homepage and your authenticated dashboard have very different performance characteristics. Setting a single 2.5s LCP budget across the entire site is a recipe for frustration. Set per-route budgets that reflect the actual work each page does. PagePulse makes this trivial:

typescript
PagePulse.setBudget({
  routes: {
    '/':            { lcp: 2500, inp: 200, cls: 0.1 },
    '/dashboard':   { lcp: 3500, inp: 300, cls: 0.1 },
    '/blog/[slug]': { lcp: 2000, inp: 200, cls: 0.05 },
  },
  jsSizeKB: 175,
});

Enforce in CI

A budget that is not enforced is a wish. Use the @pagepulse/ci package to fail any pull request that breaches a budget. PagePulse posts a comment to the PR showing exactly which budget was exceeded, by how much, and which module caused the regression. Engineers learn very quickly to keep their changes within budget.

bash
# In your CI pipeline
npx @pagepulse/ci check \
  --project site_123 \
  --base origin/main \
  --head HEAD

Iterate monthly

Budgets should get tighter over time. Review your budgets once a month. If you are comfortably under budget on a route, tighten the budget by 5-10%. If you are consistently over budget, investigate the root cause and either fix it or relax the budget. The goal is continuous improvement, not perfection.

Ready to ship
faster pages?

Join thousands of frontend teams monitoring Core Web Vitals with PagePulse. Install in 2 minutes, see results today.

No credit card required