All articles · Performance

Why Lighthouse and Your Real Users Disagree About Speed

Cover with the article title next to a speed gauge, in light blue on a dark background

Someone on the team runs PageSpeed Insights and gets a 38. Someone else runs it ten minutes later and gets a 52. Meanwhile the Core Web Vitals section at the top of the same report says the page passes. Which number is the truth?

Both, as it turns out. They answer different questions, and most of the confusion around web performance comes from treating them as the same measurement. This article explains where each number comes from, why they drift apart, and how to use them together.

Two kinds of data on one page

A PageSpeed Insights report contains two very different things:

  • Field data from the Chrome UX Report (CrUX): what real Chrome users experienced on this URL or across the whole origin over the past 28 days.
  • Lab data from Lighthouse: one synthetic page load, run on Google’s servers, under a fixed simulated device and network.

The Core Web Vitals assessment (pass or fail) comes only from the field data. The 0–100 performance score comes only from Lighthouse. They’re printed next to each other, but they are not two readings of the same instrument.

How the lab run works

Lighthouse in PSI’s mobile mode emulates a mid-range phone and applies simulated throttling: roughly a 150 ms round-trip time, about 1.6 Mbps of throughput and a 4x CPU slowdown. It loads the page once, with a cold cache, records a trace, and then models how long things would have taken on that slower device and network.

The performance score is a weighted blend of five metrics:

Metric Weight
Total Blocking Time 30%
Largest Contentful Paint 25%
Cumulative Layout Shift 25%
First Contentful Paint 10%
Speed Index 10%

Each metric is converted to a 0–100 value on a log-normal curve, so improvements at the slow end are worth more points than polishing an already fast metric. More detail in our Lighthouse score guide.

Two consequences follow directly:

  1. The lab score varies between runs. Server response times, third-party scripts, A/B tests and ad auctions differ from one load to the next. Swings of 5–10 points on the same page are normal. If you compare before and after a change, run several times and compare medians.
  2. The lab can’t see interaction. Lighthouse doesn’t click anything, so it has no Interaction to Next Paint. Total Blocking Time is a proxy, and it only covers the load.

How the field data works

CrUX collects metrics from Chrome users who have opted in to sharing usage statistics. For each metric it reports the 75th percentile over a rolling 28-day window. A page passes the Core Web Vitals assessment when LCP, INP and CLS are all in the “good” range at that percentile:

Metric Good at p75
LCP ≤ 2.5 s
INP ≤ 200 ms
CLS ≤ 0.1

Three details trip people up:

  • URL vs origin. If a single URL doesn’t have enough traffic, PSI falls back to origin-level data, which mixes in every other page on the site. A blazing landing page can “fail” because the logged-in dashboard drags the origin down.
  • The window lags. A fix deployed today shows up gradually over the next four weeks as old samples roll out of the window.
  • Only Chrome, only opted-in users. That’s a large and fairly representative sample for most sites, but Safari-heavy audiences (many consumer apps in some markets) aren’t in it.

Why the numbers disagree

Once you know where each number comes from, the disagreements stop being mysterious.

Real devices are faster and slower

The lab emulates one fixed device. Your real visitors are a distribution: some on new flagship phones over 5G, some on four-year-old budget phones on a congested network. If most of your Chrome traffic comes from fast desktops and recent phones, the 75th percentile can sit well ahead of the emulated device, and the field looks much better than the lab. A site whose users are mostly on low-end Android in regions with slow networks will see the reverse.

Caches and repeat visits

Lighthouse always loads cold. Real users come back with a warm HTTP cache, a service worker, or a page restored instantly from the back/forward cache. For sites with lots of returning visitors, field LCP is often far better than the lab predicts.

Layout shifts after the load

Lab CLS stops when the load finishes. Field CLS covers the whole life of the page: the cookie banner that pushes content down after three seconds, the ad slot that expands as you scroll, the “related articles” block injected late. CLS uses session windows of up to five seconds and reports the worst one, so a single late shift can dominate. If your field CLS is bad and lab CLS is zero, look for things that happen after load or on scroll.

Interaction cost

A page with a clean lab run can still have a poor INP, because the expensive JavaScript only runs when someone opens the menu or types into a search box. The INP guide covers how to track those down.

Different page, same URL

Personalization, logged-in states, consent choices, geolocation and experiments all mean that the page Lighthouse loads may not be the page most users get. A Google data center in the US might see an English, cookie-wall-free page while your actual traffic in Germany gets a consent dialog and a different hero image.

Server and CDN behaviour

Lighthouse runs from a handful of locations. If your CDN isn’t warm there, or your origin is slow for uncached requests, Time to First Byte in the lab can be much worse than what users near your edge nodes see. The opposite happens too: a nearby lab server can hide poor TTFB for users on another continent. Our TTFB guide goes into that.

Which one to trust

Use them for different jobs:

  • Field data answers “do we have a problem, and for whom?” It is the ground truth for user experience and the input to Google’s page experience signals. If the field says you pass, you pass, whatever the lab score says.
  • Lab data answers “why, and did my change help?” It’s reproducible enough to compare builds, shows you the waterfall and the long tasks, and gives you a result in a minute instead of a month.

The mistake is optimizing the lab score for its own sake. Shaving 200 ms of TBT off a page whose field INP is already 90 ms won’t change anything users feel. Conversely, a page with a good lab score and a poor field LCP needs investigation, not celebration.

A workflow that holds up

  1. Start from the field. Check the CrUX numbers per metric, and note whether they’re URL or origin level.
  2. Pick the failing metric and the device class. Mobile and desktop are separate datasets; fix the one that fails.
  3. Reproduce in the lab with settings close to the real audience. Mobile emulation is a good default; if your users are mostly on fast desktops, the mobile lab result will overstate the problem.
  4. Measure your own users if the stakes are high. A small RUM setup with the web-vitals library gives you per-page, per-device distributions without waiting 28 days.
  5. Change one thing, compare medians of several lab runs, then watch the field data over the following weeks.

When the lab score is still worth watching

None of this makes Lighthouse pointless. It’s a fine regression alarm: if the score on a stable page drops 20 points after a deploy, something heavier was shipped. It’s also the only signal you have for brand-new pages with no traffic, and its diagnostics (render-blocking resources, unused JavaScript, image sizing) are the quickest route to concrete fixes.

Our own report shows both: the Lighthouse metrics and opportunities from the lab, and the CrUX field data when Google has enough traffic for the page. When they disagree, now you know why.

Tags:LighthouseCrUXfield datalab dataCore Web Vitals