Performance Budgets That Actually Work
How we enforced performance budgets in CI at CARS24 and Mamaearth — and what happened when we didn't.
Why Performance Budgets Fail
Every team I've worked with has at some point said 'we should set performance budgets.' Most of them set the budgets, put them in a wiki page, and never looked at them again. The budgets were aspirational, not enforced, and without enforcement they're just documentation.
Performance budgets fail for three reasons: they're too abstract (nobody knows what '200KB JavaScript budget' means in terms of their daily work), they're not automated (checking requires manual effort), and there are no consequences for exceeding them (the PR merges anyway).
Making Budgets Concrete
At CARS24, we translated abstract budgets into rules engineers could internalize. Instead of 'JavaScript bundle under 200KB,' we said 'no single route should add more than 15KB of new JavaScript.' Instead of 'LCP under 2.5 seconds,' we said 'hero images must be under 100KB and use the AVIF format.'
We also created a performance budget dashboard that showed each route's current metrics against its budget. Engineers could see at a glance where they stood. When a route was at 90% of its budget, it showed yellow. At 100%, red. This visibility alone changed behavior.
The most effective budget we set was on third-party scripts. We capped the total number of third-party scripts per page at five and required VP approval to add a new one. This forced product managers to prioritize which analytics and marketing tools actually mattered.
Automating Enforcement in CI
At Mamaearth, we integrated Lighthouse CI into our GitHub Actions pipeline. Every PR ran Lighthouse against the affected pages and compared the results against our budgets. If any metric exceeded the budget, the check failed and the PR couldn't merge.
We also added a custom webpack plugin that tracked bundle sizes per route. If a PR increased any route's bundle by more than 5KB, it added a comment to the PR with a breakdown of what changed and why. This wasn't a blocking check, but the visibility was enough to make engineers think twice before adding a dependency.
The key insight is that non-blocking checks are nearly useless. If the PR can still merge, the budget is a suggestion. If you're serious about performance, make the checks blocking and give engineers clear guidance on how to fix failures.
Dealing with Budget Overruns
Budgets will be exceeded. The question is how you handle it. We created an override process: if a PR exceeds the budget, the engineer adds a performance-override label and includes a justification comment explaining why the increase is necessary and what the plan is to bring it back under budget.
We reviewed overrides in our weekly engineering sync. Most were legitimate — a new feature that genuinely required more JavaScript, or a library upgrade with a temporary size increase. A few were not, and the review process caught them.
Over six months at CARS24, our JavaScript bundle size decreased by 18% despite shipping new features every week. The budgets didn't prevent growth; they made growth intentional rather than accidental.
The Business Case for Performance Budgets
The hardest part is getting organizational buy-in. Engineering leadership understands why performance matters, but product leadership needs business metrics. At Mamaearth, we ran an A/B test comparing our optimized pages against the pre-budget baseline. The optimized pages had a 6% higher conversion rate and 11% lower bounce rate.
That data point secured dedicated engineering time for performance work every sprint. Performance budgets went from a nice-to-have to a product requirement. If you're struggling to get buy-in, stop talking about milliseconds and start talking about revenue.
Related Articles
The Full-Stack Engineer's Guide to Core Web Vitals
Practical tips from production — not theory, not docs rewrites, just what actually moved the needle.
ReadThe 5 Debugging Techniques That Save Me Hours
Chrome DevTools, profiling, strategic logging, and other tools I reach for before touching the code.
ReadThe Cost of JavaScript: A Deep Dive
Bundle analysis, tree-shaking, and how we cut Total Blocking Time by 60% at Mamaearth.
ReadFound this useful? I write about engineering, performance, and career growth.