A p95 budget your team will actually keep
Performance targets fail because they are stated as feelings. A percentile budget with a test behind it survives contact with a deadline.
"We want it fast" is not a target. It cannot be measured, it cannot be broken by a specific commit, and it cannot be defended when a launch date moves. Most performance work fails for this reason before a single slow query is written.
A budget fixes that. It is one number, agreed up front, with a consequence attached.
State it as a percentile, not an average
An average hides the users who are actually suffering. If the mean response is 200ms because most requests are fast and a few take four seconds, the average is useless — and the people on the slow path are the ones who leave.
Pick a percentile. p95 under 300ms is a target you can hold a release to.
Give the budget a ceiling and a floor
Two numbers, not one:
- The ceiling — the worst acceptable
p95. Cross it and the build fails. - The floor — the point at which you stop optimising. Fast enough is a real place, and chasing past it is how teams gold-plate the wrong thing.
Put a test behind it
A budget with no test is a preference. Add a check to the pipeline that fails when the number regresses beyond a threshold. Now performance is enforced by the same mechanism as correctness, which is the only way it survives.
Optimise the three that matter
Ninety percent of the wins come from a short list, every time:
- What is on the critical path. Ship less to the first paint.
- What the database does per request. The N+1 query is still undefeated.
- What blocks the main thread. Long tasks make everything feel slow, even when the network was fine.
The point
Performance is a budget, not a virtue. Decide the number, write the test, and let the build tell you when you have spent it.