Lesson 28 of 30
One manual Lighthouse run tells you the score right now, on your machine, this one time. Lighthouse CI is what makes that measurement trustworthy enough to gate a merge on.
11 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
Question 1 of 3
Why does Lighthouse CI run an audit multiple times per build and assert against a median, instead of trusting a single run?
Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
The previous lesson covered the general pattern of enforcing a performance budget in CI. Lighthouse CI is the tool most commonly used to actually implement that pattern for Lighthouse-measurable metrics, and it does meaningfully more than "run Lighthouse and check the score."
A single manual Lighthouse run has real run-to-run variance — machine load, background processes, network jitter can all shift a lab measurement by a noticeable amount between two runs of the exact same code. Trusting one run to gate a merge means occasionally failing a perfectly fine PR, or worse, occasionally passing a genuinely regressed one. Lighthouse CI runs multiple times per build and takes a median (or applies a statistical assertion across the runs), which is far more trustworthy than any single sample.
It also keeps history: results are stored per build, so when a metric does regress, it can be traced back to the specific commit where it happened, not just discovered as "somewhere in the last month, this got worse." And it can assert against individual metric thresholds, not just the rolled-up overall score — a PR fails because LCP specifically crossed its budget, with that fact stated directly, rather than because "the performance score dropped 4 points" for reasons a reviewer then has to go dig up.
// lighthouserc.json
{
"ci": {
"collect": {
"numberOfRuns": 5,
"url": ["https://preview-pr-482.example.com/"]
},
"assert": {
"assertions": {
"largest-contentful-paint": ["error", { "maxNumericValue": 2500 }],
"cumulative-layout-shift": ["error", { "maxNumericValue": 0.1 }],
"categories:performance": ["warn", { "minScore": 0.9 }]
}
}
}
}
With numberOfRuns: 5, this config runs the audit five times against the PR's preview deployment and asserts against the median. LCP and CLS are hard failures against their specific numeric thresholds — the same Core Web Vitals "good" thresholds from earlier in this track — while the rolled-up performance score is only a warning. A reviewer looking at a failed check sees exactly which metric broke and by how much, not a single opaque number.
"How do you make a performance regression fail a PR the way a broken test would?" is a common systems-thinking question, and naming Lighthouse CI's median-of-multiple-runs and metric-level assertions (versus a fragile single manual run) is what separates someone who's actually operated this in a real pipeline from someone who's only run Lighthouse manually once.