Guide
Core Web Vitals explained lab vs field data
Lighthouse says 98, Search Console says "poor". Both are right — they measure different things. This guide explains the three Core Web Vitals, the two ways to measure them, and how to use each.
By Roger Campos · Last updated: September 2026
TL;DR
Core Web Vitals are three real-user metrics: Largest Contentful Paint (good ≤ 2.5 s), Interaction to Next Paint (≤ 200 ms) and Cumulative Layout Shift (≤ 0.1), judged at the 75th percentile of visits. Field data comes from real Chrome users and is what Google uses; lab data, like Lighthouse, is one simulated load you can repeat and debug. Use the lab to find causes, the field to confirm.
Free plan, no credit card. 1,000 credits a month.
The metrics
The three Core Web Vitals, and what "good" means
Core Web Vitals are Google's three measures of how a page feels to the people using it: how fast the main content appears, how quickly the page responds, and how much it jumps around.
| Metric | Measures | Good | Poor |
|---|---|---|---|
| Largest Contentful Paint (LCP) | When the largest image or text block in the viewport has rendered | ≤ 2.5 s | > 4.0 s |
| Interaction to Next Paint (INP) | How long the page takes to show a response after clicks, taps and key presses, across the visit | ≤ 200 ms | > 500 ms |
| Cumulative Layout Shift (CLS) | How much visible content moves unexpectedly, summed over the worst burst of shifts | ≤ 0.1 | > 0.25 |
Two details in those definitions change how you read every report. First, a page "passes" when the 75th percentile of its visits is in the good range, separately for mobile and desktop — so a quarter of your visitors can have a worse experience and the page still passes, and a fast median proves nothing. Second, INP replaced First Input Delay as the responsiveness metric in March 2024; guides that mention FID are describing a metric Google has retired.
The thresholds are published on web.dev, which is the reference to check when a number here and a number elsewhere disagree.
The two sources
Lab data and field data measure different things
| Lab (Lighthouse, WebPageTest, DevTools) | Field (CrUX, your own RUM) | |
|---|---|---|
| Who loads the page | One simulated device on a throttled network | Every real Chrome user who visits |
| What you get | One load, with a full trace of why | A distribution, with no trace at all |
| Measures INP | No | Yes |
| Repeatable | Yes | No |
| Works before launch, or on a page with no traffic | Yes | No |
| What Google's ranking uses | No | Yes |
| How quickly a fix shows | Immediately | Over about 28 days |
Field data is the truth about your users, and it is what Search Console reports and Google's page experience signals use. Its public source is the Chrome UX Report (CrUX): measurements from Chrome users who opted into usage statistics, aggregated over a rolling 28-day window, per URL and per origin — for pages with enough traffic to be reported at all.
Lab data is a controlled experiment. Lighthouse loads the page once on an emulated device — by default a mid-range phone with a 4× slower CPU on a slow 4G connection — and records everything. You can't learn your users' experience from it, but you can learn exactly why a load was slow, change one thing, and run it again.
Why they disagree
"Lighthouse says 95, Search Console says poor"
That combination is common, and neither tool is broken. The lab run leaves out most of what real visits contain:
- Devices and networks. Your real audience's slowest quarter is often slower than the lab's emulated phone — and sometimes faster. The 75th percentile is set by them, not by the emulator.
- What's on the page. Real visitors get the consent banner, the personalized recommendations, the A/B test variant, the chat widget and the logged-in header. The lab gets a first-time anonymous load.
- Caches. Lighthouse loads cold. Returning visitors have warm caches, and back/forward navigations can be instant.
- The whole visit. Field CLS keeps counting while the user scrolls and interacts; a lab run mostly sees the load. A layout shift triggered by a late ad or an infinite-scroll insert never shows up in the lab.
- Interactions. INP exists only when someone clicks, taps or types. A page-load audit has nobody doing that, so it reports Total Blocking Time instead — the time the main thread was too busy to respond during load, which correlates with INP but is not the same number.
- Which element is "largest". LCP depends on the viewport. The hero image on a desktop may be a headline on a phone, and field data blends every size your visitors use.
Using both
A workflow that uses each for what it's good at
- 1Start in the field. Search Console's Core Web Vitals report, or PageSpeed Insights, tells you which metric fails, on which device type, for which group of pages. Don't optimize a metric that already passes.
- 2Reproduce in the lab. Run Lighthouse on a representative URL from the failing group, with the matching device setting. If the lab can't reproduce the problem, the cause is something the lab doesn't have — look at the list above.
- 3Diagnose from the trace. Lighthouse's insights name the LCP element and what delayed it, the long tasks behind TBT and the elements that shifted. The Lighthouse guide covers reading them.
- 4Fix, and re-run the lab to confirm the metric moved. Take the median of three to five runs; single runs are noisy.
- 5Confirm in the field over the following weeks. CrUX's 28-day window means the improvement arrives gradually as old visits age out.
For your own site
Real-user monitoring — the web-vitals JavaScript library reporting to your analytics — gives you field data for every page, broken down by whatever you like, without waiting for CrUX's window or traffic threshold. It's the best upgrade to this workflow if you own the site.
With URLpipe
Lab audits from an API, on any URL
URLpipe's /lighthouse endpoint runs a real Lighthouse audit on any public URL and returns the four category scores and the lab metrics — LCP, CLS, TBT, FCP and Speed Index — as JSON, for 2 credits. Mobile is the default (a 360 × 640 viewport, 4× CPU slowdown, slow 4G); pass device: "desktop" for the other half. It's the step-2 tool in the workflow above, for pages you don't host or when you want lab numbers in a script, a CI job or a spreadsheet.
What it isn't: field data. It can't tell you your users' INP or your CrUX status — nothing that loads the page once can. If you want audits monitored over time with the history and a written report, our sister product Full Stack Audit does that; URLpipe gives you the raw audit to build on.
curl -X POST https://urlpipe.dev/lighthouse \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "device": "mobile"}'
# An audit takes a while, so this returns a token at once; the result arrives
# at your webhook, or from GET /result/:token when it's ready.FAQ
Frequently asked questions
What are the Core Web Vitals thresholds?
Why is my Lighthouse score good but Core Web Vitals poor?
Can Lighthouse measure INP?
Where do I find field data for my site?
How long does it take for a fix to show in field data?
Try it yourself
Free tools for this
No signup — run these on a real page right now, then call the same endpoint from your code.
- Check a page's Core Web Vitals
Paste a link and get Largest Contentful Paint, Cumulative Layout Shift and Total Blocking Time from a real Lighthouse run — each marked good, needs improvement or poor.
Try it free - Run a Lighthouse audit on any URL
Paste a link and get a real Google Lighthouse audit — performance, accessibility, best practices and SEO scores, plus Core Web Vitals — measured against the live page.
Try it free
Put this into practice.
Each of the eight kinds of data URLpipe returns has a free, no-signup tool — try the ideas from this guide on a real page, then grab an API key to run them from your code. 1,000 credits a month, no card.