Interaction to Next Paint (INP)

What INP measures, the ≤200 ms threshold at p75, why it replaced FID in 2024, and how to actually fix a poor score — from a technical SEO.

First published: Jun 26, 2026 · Last updated: Jul 18, 2026 · Advanced
demand #8 in Web Vitals#17 in Web Performance#153 in Technical SEO#207 on the site

Interaction to Next Paint (INP) is the Core Web Vital for responsiveness. It watches every click, tap, and keyboard interaction across a visit and reports the latency that (close to) all of them came in under — measured at the 75th percentile in the field. Good is ≤200 ms, poor is >500 ms. INP replaced First Input Delay on March 12, 2024, because FID only timed the first interaction's input delay; INP measures the full latency (input delay + processing + presentation) of all of them. You fix it by breaking up long tasks, yielding to the main thread, doing less in event handlers, shrinking the DOM, and taming third-party scripts. It's a field metric — Total Blocking Time is its lab proxy.

TL;DR — INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good. is the Core Web Vital for responsiveness. It observes the latency of all click, tap, and keyboard interactions across a visit and reports the value at the 75th percentile (one outlier dropped per 50 interactions) — not just the first input like FIDFirst Input Delay — a retired Core Web Vital that measured the delay before the browser could begin processing a page's first interaction. Good was ≤100 ms. Replaced by INP in March 2024. did. An interaction’s latency = input delay + processing duration + presentation delay. Good ≤ 200 ms, poor > 500 ms, judged on field dataPerformance metrics captured from real users, not lab tests. at p75. It replaced FID on March 12, 2024 (FID fully removed from tools September 2024). Fix it by breaking up long tasksAny main-thread task over 50 ms — the primary cause of INP regressions., yielding to the main thread with scheduler.yield(), doing less in event handlers, shrinking the DOM, and deferring third-party scripts. It’s a field metric — Total Blocking TimeTotal Blocking Time — the sum of the blocking portion (time above 50 ms) of every long task between First Contentful Paint and Time to Interactive. It's a lab-recommended metric and the lab proxy for INP, not a Core Web Vital. is the lab proxy, and the two don’t always agree.

What INP measures — and how it differs from FID

Google’s definition is precise: INP “assesses a page’s overall responsiveness to user interactions by observing the latency of all click, tap, and keyboard interactions that occur throughout the lifespan of a user’s visit to a page.”

Evidence for this claim INP observes click, tap, and keyboard interaction latency throughout a page visit rather than measuring only the first input delay. Scope: Current web.dev INP definition and qualifying interaction types. Confidence: high · Verified: web.dev: Interaction to Next Paint

That “all interactions… throughout the lifespan” phrasing is the whole story. INP is a visit-level metric, not a load-time one — and Google’s reasoning is that the vast majority of a user’s time on a page happens after it loads, so responsiveness during use matters more than the first impression alone.

The contrast with First Input Delay is the cleanest way to understand it: “FID only measured the input delay of the first interaction on a page. INP improves on FID by observing all interactions on a page, beginning from the input delay, to the time it takes to run event handlers.” FID timed one thing about one interaction — the wait before its handler started — and ignored both how long the handler ran and how long the screen took to update. INP measures the full latency of every interaction.

One nuance worth getting right, because it’s a common myth: INP is not literally the worst interaction. To avoid punishing a page for a single random spike, the browser drops one outlier for every 50 interactions, then reports the value at the 75th percentile of page views. On a low-interaction visit, that lands on the slowest interaction; on a heavy one, a couple of outliers get excluded first.

What counts as an interaction is also narrower than people assume. Only clicks, taps, and keyboard presses are measured. Scrolling, hovering, and zooming are explicitly excluded. And a single gesture can fire several events — a tap produces pointerdown, pointerup, and click — which INP groups as one interaction, not three. Within that group, INP takes the longest individual event duration, not the sum of all of them — so a fast pointerdown next to a slow click still reports as one interaction sized by the slow event. If a page has no qualifying interactions during a visit, INP simply isn’t reported for it.

The three parts of an interaction’s latency

Every interaction’s latency breaks into three sequential pieces. This is the model to keep in your head, because each part points at a different fix:

Interaction latency = Input delay + Processing duration + Presentation delay

  1. Input delay — the time before your event handlers can even start running, usually because the main thread is busy finishing a long task.
  2. Processing duration — the time it takes all of your event handler callbacks to execute.
  3. Presentation delay — the time from when your handlers finish until the browser paints the next frame on screen.

The web-vitals attribution build exposes all three (inputDelay, processingDuration, presentationDelay) so you can see which part dominates on a real interaction. Per the Web Almanac’s 2024 data, presentation delay is often the largest single piece at the median — but processing duration is where the optimization leverage usually lives, because it’s the part that balloons on poorly-built pages.

INP measures the whole interaction. Attribute the delay to the waiting, handler, or presentation phase before choosing a fix. Source: web.dev

The interaction begins with input delay while the event waits for the main thread. Processing duration follows while the event-handler callbacks execute. Presentation delay runs from the end of the handlers until the browser lays out and paints the next frame. Together these three sequential phases make up the interaction latency measured by INP.

© Patrick Stox LLC · CC BY 4.0 ·

The thresholds — and the p75 field caveat

RatingINP valueMeasured at
Good≤ 200 ms75th percentile, field
Needs improvement> 200 ms and ≤ 500 ms75th percentile, field
Poor> 500 ms75th percentile, field

Google Search Central states the target plainly — “an INP of less than 200 milliseconds” — and frames the whole program as: “We highly recommend site owners achieve good Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. for success with Search.” The 200 ms budget is genuinely tight when you remember the browser wants a frame every ~16.7 ms at 60 fps; all of your handler work plus renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. has to fit.

Evidence for this claim INP is good at 200 milliseconds or less and poor above 500 milliseconds, assessed at the 75th percentile. Scope: Current web.dev INP thresholds for field measurement. Confidence: high · Verified: web.dev: Interaction to Next Paint

Why INP is a field metric (and lab data isn’t enough)

This is the trap that catches a lot of SEOs: a green Lighthouse scoreLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. does not mean good INP. But “LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. can’t measure INP” needs three separate cases, not one, or you’ll misread your own tooling:

  1. A standard, noninteractive Lighthouse run reports no INP at all. It only observes the page loading — it never clicks, taps, or types anything — so there’s no interaction to time. Lighthouse falls back on Total Blocking Time (TBTTotal Blocking Time — the sum of the blocking portion (time above 50 ms) of every long task between First Contentful Paint and Time to Interactive. It's a lab-recommended metric and the lab proxy for INP, not a Core Web Vital.) as a load-time proxy instead. Google’s own framing: “Because TBT correlates well with INP, a page with a high TBT is a reasonable indicator that there may be high INP values during load.” The key words are “during load.” TBT says nothing about an interaction that goes bad ten seconds later when a lazy-loaded widget runs — it’s a proxy, never a substitute or a conversion formula.
  2. A manually or synthetically exercised interaction — clicking a real button in DevTools, or scripting a click in a lab tool — does produce a real INP-style latency number for that one interaction. That’s useful for reproducing a specific bug. But it’s still one scripted path on one device: it can’t stand in for the field’s mix of real devices, real users, real interaction targets, and a full visit’s worth of page lifetime. As Google puts it, the resulting value “will be dependent on what interactions are performed during the measurement period,” and real user behavior is too variable for a single lab run to represent it.
  3. The field distribution is the only thing INP actually is. That’s why the authoritative source is field data: the Chrome User Experience ReportChrome User Experience Report — Google's public dataset of real-world (field) performance data from eligible Chrome users. It's the official field-data source behind the Core Web Vitals program. (CrUXChrome User Experience Report — Google's public dataset of real-world (field) performance data from eligible Chrome users. It's the official field-data source behind the Core Web Vitals program.), surfaced through PageSpeed InsightsPageSpeed Insights (PSI) is a free Google tool at pagespeed.web.dev that reports two kinds of data for a URL: real-user field data from the Chrome UX Report and a single Lighthouse lab run with the 0–100 Performance score. Only the field Core Web Vitals are what Google uses for ranking. and the Search Console Core Web VitalsThe Google Search Console report (under Experience) that shows how your indexed URLs perform on the Core Web Vitals — LCP, INP, and CLS — using real-user field data from CrUX, grouped by device, status, and clusters of similar-performing URLs. report. “Field data is the best source of information you can draw on when it comes to understanding which interactions are problematic for actual users.”

Use the lab (cases 1 and 2) to find and reproduce a slow interaction; use the field (case 3) to confirm whether it’s actually dragging down real visitors’ scores.

Why your INP score is poor

Almost every INP problem traces back to the main thread being blocked when a user interacts. The usual suspects:

  • Long tasks. Any main-thread task over 50 ms is a long task; the amount over 50 ms is its “blocking period.” While one runs, your interaction can’t be handled. This is the single biggest cause.
  • Heavy event handlers. Doing too much synchronously inside a click/input handler inflates processing duration directly.
  • Large DOM size. Bigger DOMs cost more to render, which inflates both input and presentation delay.
  • Third-party scripts. Per the Web Almanac, consent providers, tag managers, analytics, and chat widgets are top offenders — and they hit even simple content sites. They’re the first place I look on a page I didn’t build.
  • Post-load JavaScript. Just because a page rendered doesn’t mean it finished loading — scripts evaluating after first paint can block early interactions.

How to fix it

The strategies, roughly in order of impact:

1. Break up long tasks. Google’s core advice on handlers is to “do as little work as possible in them.” Split a big job into smaller tasks so the browser can interleave a user interaction. When tasks are broken up, “the browser can respond to higher-priority work much sooner — including user interactions.”

2. Yield to the main thread. The modern, recommended way is scheduler.yield() (Chrome 129+, Firefox 142+): await scheduler.yield() pauses your code, lets the browser handle pending work, and resumes with priority — so other tasks won’t cut the line ahead of your continuation. The classic fallback is setTimeout(..., 0), which still works but sends your code to the back of the task queue (and browsers enforce a 5 ms floor after several nested calls). One thing to stop doing: isInputPending() — Google now says “we no longer recommend using this API.” See the Scripts tab for the pattern.

3. Do less in event handlers — defer the non-critical work. Run only the visual update the next frame needs synchronously; push everything else (saving, spell-check, analytics, word counts) behind requestAnimationFrame + setTimeout or a yield. The user sees the response immediately; the bookkeeping happens after.

4. Avoid layout thrashing. Reading layout properties right after writing styles in the same task forces the browser into synchronous layout it could otherwise have batched. Batch reads, then writes.

5. Reduce DOM size. Smaller trees render faster. content-visibility can lazily render off-screen elements so they don’t cost you during load or interaction.

6. Audit and defer third-party scripts. This is the highest-leverage SEO fix on real sites. Load consent/tag/analytics scripts lazily, gate them on interaction, or move them off the critical path. A “lightweight” content page can fail INP purely because of a heavy embedded widget.

Does INP affect rankings?

Yes — INP is one of the three Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data., and Core Web VitalsWeb Vitals is Google's initiative (launched May 2020) for unified page-experience quality signals. Core Web Vitals — LCP, INP, and CLS — are the subset used in ranking; the rest (TTFB, FCP, TBT, Speed Index) are diagnostic, not ranking factors. are part of Google’s page-experience signals. But it’s a lightweight signal: a tiebreaker between comparably relevant results, not a primary ranking factor. Don’t chase a perfect INP score at the expense of content and relevance.

Two practical SEO points. First, mobile is the hard number. In the 2024 Web Almanac, ~74% of mobile sites passed INP versus ~97% on desktop — and because Google indexes mobile-first, the mobile figure is the one that counts. Second, complex sites do worse: only ~53% of the top 1,000 sites passed, because feature-rich pages ship more JavaScript to block the main thread. Heavy feature development is an INP risk, and high-interaction pages — product pages, checkout, search results, forms — are far more exposed than static content.

INP vs FID — the full picture

FID (retired)INP (current)
InteractionsFirst onlyAll, whole visit
What it timesInput delay onlyInput delay + processing + presentation
Good threshold≤ 100 ms≤ 200 ms
StatusRemoved from tools Sept 2024Core Web Vital since Mar 12, 2024

FID is gone — removed from Search ConsoleGoogle's free tool for monitoring crawling, indexing, and search performance. on the day INP launched and from CrUX’s BigQuery/API by September 2024. If a tool or audit still references FID, it’s stale.

Edge cases that make INP data disagree

A handful of lifecycle quirks explain most “why doesn’t my RUM match CrUX” questions:

  • No interactions, no INP. If a visit never gets a click, tap, or key press — or only gets excluded gestures like scrolling and hovering — there’s no INP value for that page view. This is normal on read-only content pages and isn’t a bug in your monitoring.
  • IframesHTML element that displays one webpage inside another — how embeds work. count toward the metric, but your own JavaScript can’t see inside them. An interaction inside an embedded iframe (an ad, a widget, an embedded form) contributes to the page’s INP. But a first-party RUM script can’t read events from a cross-origin iframe the way the browser’s own metric can — so CrUX and a same-origin RUM setup can legitimately disagree on pages with third-party embeds. Document this gap rather than treating a RUM/field mismatch as a bug.
  • Back/forward cache restores reset INP to zero. A page pulled from bfcache (the back button, for instance) starts a fresh INP count — interactions from before the navigation away don’t carry over.
  • Long-lived and backgrounded tabs still need to report. Because a tab can sit open for hours without ever formally unloading — especially on mobile, where the OS may just kill it — INP should be captured when the page becomes hidden, not only on unload. RUM setups that only flush on unload will silently lose data from these visits.

Where this sits

INP is one piece of the Core Web Vitals picture, alongside Largest Contentful Paint (loading) and Cumulative Layout Shift (visual stability). Check it in PageSpeed InsightsPageSpeed Insights (PSI) is a free Google tool at pagespeed.web.dev that reports two kinds of data for a URL: real-user field data from the Chrome UX Report and a single Lighthouse lab run with the 0–100 Performance score. Only the field Core Web Vitals are what Google uses for ranking. and the Search Console report (field), and debug it in Lighthouse / Chrome DevTools (lab, via the TBT proxy). The data behind all of it comes from CrUX.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.