Interaction to Next Paint (INP) is a Core Web Vitals metric that measures how quickly a page visually responds to user input. For every click, tap and key press during a visit, the browser records the time from the input until the next frame is painted, and INP reports roughly the worst of those latencies for the page.
INP replaced First Input Delay (FID) as a Core Web Vital in March 2024. Google rates a page as good when INP is 200 milliseconds or less at the 75th percentile of page loads, needs improvement from 200 to 500 ms, and poor above 500 ms.
The browser measures INP with the Event Timing API. Only discrete interactions count: pointer down and up, clicks, taps and key presses. Hover and scroll are excluded. One tap can fire several events (pointerdown, pointerup, click), and the longest event duration in that group becomes the latency of the interaction. Durations are rounded to 8 ms granularity.
On a page with fewer than 50 interactions, INP is the single slowest one. On busier pages the browser ignores one highest interaction for every 50, which approximates the 98th percentile and stops one freak stall from defining a long session. A single-page app session with 120 interactions discards the two slowest and reports the third. The Chrome User Experience Report (CrUX) then takes the 75th percentile of those per-page values, separately for mobile and desktop.
The following is illustrative arithmetic, not a measurement. A user taps a filter button 40 ms into a 120 ms hydration task, so input delay is 80 ms. The click handler updates state and re-renders a product grid in 70 ms. Layout and paint over a 3,000-node DOM take 60 ms. Total: 210 ms, reported as 208 ms after 8 ms rounding, which still lands in "needs improvement".
Splitting hydration into chunks of 50 ms or less caps the worst-case input delay near 50 ms, bringing the same interaction to about 180 ms without touching the handler. The general lesson: input delay is usually the cheapest phase to cut, because it is caused by work that did not need to run at that moment.
A good INP score is 200 ms or less, measured at the 75th percentile of real page loads in the field, segmented by mobile and desktop. Scores from 200 to 500 ms need improvement, and anything above 500 ms is poor. Because the threshold applies at p75, one in four visits can exceed 200 ms while the page still passes.
| Metric | Good | Poor | What it covers |
|---|---|---|---|
| INP (Core Web Vital since March 2024) | 200 ms or less | Above 500 ms | All interactions, all three phases, whole page lifetime |
| FID (retired March 2024) | 100 ms or less | Above 300 ms | Input delay of the first interaction only |
INP's looser number hides a far stricter test, because it charges handler execution and rendering that FID never counted.
INP vs. First Input Delay: FID measured only the input delay of the first interaction, so a page whose handlers took 400 ms could still pass. INP covers every interaction across the visit and includes processing and presentation, which is why many sites that comfortably passed FID failed INP on mobile.
INP vs. Total Blocking Time: Total Blocking Time (TBT) is a lab metric in Lighthouse that sums the portion of each long task beyond 50 ms during load. It correlates with input delay during loading, but it sees no real interactions, no slow handlers and nothing after load. Use TBT as a CI regression guard, not as an INP substitute.
INP vs. Long Animation Frames: the Long Animation Frames (LoAF) API, shipped in Chrome 123 in 2024, reports frames that took more than 50 ms to render, with attribution down to script source URL and function. LoAF does not score anything. It explains why a specific INP interaction was slow.
Field data comes first, because lab runs rarely reproduce the interaction that hurts. The common setup is the web-vitals library's attribution build: its onINP callback reports the value plus interactionTarget (a CSS selector), inputDelay, processingDuration, presentationDelay, loadState and the matching long animation frame entries. Send those fields to your real user monitoring (RUM) pipeline and group by selector.
Without the library, create a PerformanceObserver for the event entry type with buffered set to true and durationThreshold set to 16. The default threshold is 104 ms, which hides the 100 to 200 ms interactions that decide whether you pass. Remember that CrUX covers Chrome users only, so your RUM numbers from other browsers will not match it exactly.
Then fix by phase:
"INP is an average." It is a near-worst value per page, then a 75th percentile across pages. A median of 80 ms can coexist with a failing score.
"Network time counts." INP stops at the next paint, not when a fetch resolves. A click that paints a spinner in 60 ms and loads data for two seconds has a 60 ms interaction. The slow fetch is a UX problem, not an INP problem.
"A faster CDN fixes INP." Delivery speed moves Time to First Byte and Largest Contentful Paint. INP is decided on the main thread. Compression shrinks bytes on the wire but not parse and execution cost, so only shipping less JavaScript helps both sides. More on the delivery half lives in the web performance articles on this blog.
"Lighthouse reports INP." A default navigation run performs no interactions. The timespan mode in Chrome DevTools does record INP for a flow you click through yourself.
INP is the Core Web Vitals responsiveness metric, measuring the time from a click, tap or key press to the next painted frame. It became a Core Web Vital in March 2024, replacing First Input Delay. Google treats 200 ms or less at the 75th percentile as good, with mobile and desktop assessed separately in Chrome User Experience Report field data.
INP replaced FID because FID measured only the input delay of the first interaction and ignored handler execution and rendering. Pages with slow event handlers or sluggish interactions after load could still pass FID. INP covers every discrete interaction during the visit and all three phases, input delay, processing and presentation, so it reflects what users actually feel.
A CDN rarely improves INP directly, because INP is determined by main-thread work in the browser rather than network delivery. A CDN improves Time to First Byte and Largest Contentful Paint. Indirect gains come only from shipping less JavaScript, since smaller bundles reduce parse and execution time that otherwise delays interactions during page load.
Mobile INP is usually worse because mid-range phones execute JavaScript several times slower than desktop CPUs, so the same hydration task or event handler takes far longer. CrUX reports mobile and desktop separately. Fix mobile first by profiling with CPU throttling in DevTools and by collecting field attribution data from real mobile sessions.
For pages with 50 or more interactions, INP ignores one highest-latency interaction per 50 and reports the next slowest, approximating the 98th percentile. A session with 120 interactions discards the two slowest. Pages with fewer than 50 interactions report the single worst one. Field tools then take the 75th percentile across all page loads.
Ship the web-vitals attribution build to a 10% sample of sessions and log INP with its three phases, loadState, the interaction selector and the long animation frame script URLs. After a week, rank selectors by count of interactions above 200 ms on mobile. The top three usually account for most failures, and the dominant phase tells you whether to split hydration, yield inside handlers or shrink the DOM. Add a TBT budget to CI so regressions in load-time blocking are caught before release.
INP lives on the main thread, but the same pages still depend on delivery for TTFB and LCP. BlazingCDN publishes its own download measurements, measured June 2026, on its CDN performance metrics page, with a public test file you can run from your users' regions.