Free tool

Lighthouse required-runs calculator

“We ran it five times and the score went up two points” isn't evidence — Lighthouse is noisy enough that a small before/after change can be pure run-to-run variance. This tool measures your page's real variance for you (a short PageSpeed Insights pilot, per metric), tells you how many runs a claim actually needs, hands you the scripts that run it — and when you've run it, drop your before/after Lighthouse JSONs below for the statistical verdict.

Where to start

Plan the experiment

1 · Where your σ comes from

Derived from the published 100-run score ranges in Heričko et al. (2021) — stable ≈ Unsplash/Shopify/IKEA (range 4–5 pts), moderate ≈ Zendesk/Bola (13–14), noisy ≈ Amazon India/AliExpress/Wix (20–23) — using range ≈ 5σ for ~100 normal draws. Typical, not yours: your page's σ can differ by several×; the pilot measures it in minutes. Presets exist for the score only — that's where published data exists.

2 · Your claim

Drop ONE report of the page you want to improve. It fills in the URL, the device profile and the Lighthouse version, and tells you where each metric stands today — so your target is a number relative to your page rather than a guess. It does not estimate noise: one run has no spread. That still takes a pilot or a set of runs.

You know the change worth claiming — the tool prices it in runs.

The smallest real before/after difference worth claiming. Smaller δ costs quadratically more runs.

A preview deployment, a variant path, a feature-flagged URL — anything that serves the changed page while the original is still up. Without one, the runners can only do all of one arm and then all of the other, which is the sequential design under a different name.

Both versions live at once and the runs interleave, so drift lands on both arms instead of one. Needs a second URL below.

Confidence & power
  1. Historical example a published page, not yours — this answer stands here
  2. Measured on your URL a PSI pilot here, or a σ you measured yourself — not reached yet
  3. From your own runs the spread in the reports you uploaded — not reached yet
Example — runs required per condition
20
40 Lighthouse runs in total — 20 before + 20 after, roughly 17 minutes of runner time
to detect a 3-points change in Performance score at σ = 2.7 (preset · Heričko-derived), α = 0.05, power = 0.8
sized for the median comparison the verdict below makes. Comparing means would need 13 runs per condition (26 total) — fewer, but one stalled run can then carry the result. Under a normal distribution the median costs about π/2 ≈ 1.57× the runs; Lighthouse timings are skewed, so treat this plan as a safe upper estimate rather than an exact price.
your δ of 3 points is smaller than the gap between two runs of the same page (about 3.64 points, estimated from σ assuming a normal spread). That is exactly why the plan needs 20 runs a side: individual before/after runs will keep disagreeing about a change this size, and the run count is what resolves it. Cutting the spread — pinning the hardware, removing third parties — buys the same certainty for fewer runs.

n = ⌈π/2 · 2·(z₁₋α/₂+z_power)²·σ²/δ²⌉ — the π/2 because the verdict compares medians

Metric
Performance score
Run-to-run σ
2.7 preset · Heričko-derived
Change to detect (δ)
3 points
Comparison
independent runs
α / power
0.05 / 0.8
Estimator
median — what the verdict compares by mean: 13 runs
Run-to-run spread
3.64 points normal-theory from σ

That σ is an assumption, not your page. σ enters the formula squared, so the run count moves fast when it is wrong — with a short PageSpeed pilot.

6 minimum detectable effect at n = 5 — the smallest true change this design usually catches (an observed difference clears noise sooner, at 4.19)
±4.19 95% CI half-width on the difference at n = 5
1.11 signal-to-noise, δ ⁄ σ

Quick check — a number, no files

Enter the change you measured and how many runs produced it, and this judges it against the σ above. Got the actual Lighthouse JSONs? Upload them instead — that reads your real spread per metric rather than assuming this one, and checks the runs are comparable first.

Detectable change against runs per condition At 20 runs per condition this plan can detect a change of 3. Fewer runs detect only larger changes; the curve flattens, so each extra run buys less than the one before. 02.585.167.7431119273543 your target: 3 20 runs13 by meanrun-to-run spread: 3.64
Runs per condition (horizontal) against the smallest change this plan can be expected to catch (vertical). The shaded area is where the plan has enough power for your target. The dotted upright is what the same claim would cost comparing means — cheaper, and not what the verdict below does. The dashed horizontal line is the gap between two runs of the same page, which your target sits below — so single runs will disagree about it, and the run count is what settles it.
How precision improves with runs (∝ 1 ⁄ √n), judged the way the verdict below judges — by median. The last column asks one question: do these runs resolve your target?
Runs n95% CI half-widthMin. detectable ΔEnough for your target?
3 ±5.42 7.74 No
5 ±4.19 6 No
7 ±3.55 5.07 No
10 ±2.97 4.24 No
15 ±2.42 3.46 No
20 ±2.1 3 Yes
30 ±1.71 2.45 Yes
50 ±1.33 1.9 Yes
75 ±1.08 1.55 Yes
100 ±0.94 1.34 Yes

Your experiment kit

The protocol is a checklist your team can follow — run order, freeze list, decision rule. The files below are the experiment: the runners read plan.json, so the run count, device profile and Lighthouse version are never retyped, and their output drops straight back into the verdict box below.

Your target is smaller than the gap between two runs of the same page, which the kit records (targetBelowRunSpread in plan.json). That is not a reason not to run it — it is the reason the plan asks for 20 runs a side rather than five.

Download .md
  • plan.json the plan itself — every runner reads this, so the numbers exist once
    Download
  • run-lighthouse.mjs Node runner: npm install lighthouse, then one command per arm
    Download
  • run-lighthouse.sh the same experiment through the CLI, no repo dependency
    Download
  • lighthouserc.json for a repository already running Lighthouse CI
    Download

No Lighthouse version is pinned, because this tool has not seen one for this plan — plan.json carries a placeholder for you to fill in. Run the pilot, or upload reports, and the version travels with the plan. A σ measured on one version does not price an experiment run on another.

3 · Ran the experiment? Upload the runs — get the verdict.

Drop your before and after Lighthouse JSON files (raw Lighthouse reports or PageSpeed Insights API exports, any number per side). The verdict comes from your runs' own measured spread — median difference, a deterministic bootstrap confidence interval, and a noise floor — per metric. Your files are parsed in memory for this session only — never written to disk, never stored, and gone when you leave the page.

Raw Lighthouse reports or PageSpeed Insights API exports, as .json — up to 500 files and 400 MB per side.

Load at least one file on each side and the per-metric verdict appears here — including the consistency checks (mixed Lighthouse versions, mixed device profiles, mixed throttling) that silently invalidate most spreadsheet comparisons.

Why “just run it five times” isn't proof

Running Lighthouse five times and taking the median is excellent advice — for getting a stable single estimate of where a page sits today. It is not the same as having enough statistical power to prove a small before/after change is real. Those are different jobs, and the second one is governed by the spread of the runs:

n ≥ 2 · (z₁₋α/₂ + z_power)² · σ² ⁄ δ²        (independent, equal n)

at α = 0.05 and 80% power:  n ≈ 15.7 · σ² ⁄ δ²

this formula is for the difference of two MEANS. Aggregating by the median
instead costs precision (≈π/2 the variance under normality), so budget ~1.5×
the runs — the calculator above already does, and the upload verdict tests the
medians directly.

The dependence on σ²/δ² is what bites. Halving the change you want to detect quadruples the runs you need. On a moderately noisy page — σ ≈ 2.7 points, the middle of the published range the presets above are derived from — proving a 3-point change needs about 13 runs per condition by the mean, and 20 by the median, which is what the calculator above sizes for and the verdict below tests; a 2-point change needs 29 (45 by median). Five runs on that page reach 80% power only around a five-point change by the mean — nearer six by the median, which is the aggregation the advice actually names — and on the noisiest sites in that study (σ ≈ 4.3) it takes 33 runs to prove 3 points (51 by median). Fine for a big regression, useless for the single-digit gains most optimisation work produces. Note what that number is: the effect size this design would usually catch, not a floor below which a measured difference cannot be significant. The threshold a measured difference must clear is smaller (√(π/2) · z₁₋α/₂ · σ · √(2/n) for the median comparison the verdict makes), which is exactly why the upload verdict tests your actual runs instead of comparing them to a planning number.

What the pilot measures — and what it can't. The “measure it for me” pilot runs your page through PageSpeed Insights repeatedly and takes the per-metric standard deviation. That σ includes Google's runner mix (we report the CPU-benchmark spread when it's material), so it's the honest σ for PSI-based before/afters; a pinned local or CI setup is usually tighter, so measure there if that's where your experiment will run. A small pilot's σ̂ is itself uncertain — we show its 90% band and the conservative run count from the upper bound rather than hiding it. And note the pilot yields the run-level σ: a paired design needs the SD of paired differences from your own harness. Lab CLS is often deterministic; when the pilot measures σ = 0, any before/after CLS difference is directly interpretable and there is no sample-size question to answer.

How the upload verdict decides. The before/after comparison never trusts a single number: it takes the median of each side, builds a deterministic bootstrap confidence interval on the median difference from your runs' own spread, and sets a noise floor from the within-arm variation. A change is called real only when the interval excludes zero and the change clears the floor — and an apparent regression larger than the page's own baseline is treated as instability, not as a confident result. It also checks what spreadsheets silently miss: mixed Lighthouse versions, mixed device profiles, mixed throttling, and multiple URLs in one comparison.

The full method, the secondary evidence, and the registered protocol behind this calculator are in the study “How many Lighthouse runs prove a change?”

Free 5-day email course

Read your PageSpeed report like an auditor

The statistics behind this calculator are day 5 of the course — the other four days teach the rest of the method, every number from our published worked example:

  1. Day 1The 81% problem — 21 representative flags from real adjudications, and why only 4 deserved effort.
  2. Day 2The four verdicts — Real, Wrong, Trivial, Locked — and the test each flag must pass.
  3. Day 3Falsifying a flag — three places the disproof hides, starting with the tool's own numbers.
  4. Day 4Hearing the silence — the five-minute field-vs-lab drill that outranks every flag.
  5. Day 5Predict, prove, confirm — this calculator's math and the 28-day rule that make a fix provable.

The course lives in email only — it isn't published anywhere on the site.

Double opt-in: we email a confirmation link first. Five emails, then it stops — unsubscribe any time.