At a glance the headline numbers for Total Blocking Time (lab)
Total Blocking Time on the lab crawl.
The typical site blocks the main thread for 16ms during the lab load.
Distribution & median CLS site count and median CLS at each level of total Blocking Time (lab)
Passing CLS by total Blocking Time (lab) which level passes the CLS most often
Total Blocking Time (lab) 16ms. p75 172ms. p99 6.5s. At the low end (0–99ms): CLS 0.00. At the high end (800+ms): CLS 0.00. computed
Why this matters for the Core Web Vitals, and where to start fixing it
Total Blocking Time counts the parts of long tasks where a click would have waited. It is the lab stand-in for INP: a crawler does not click, so instead we measure how often the main thread was too busy to answer if someone had.
High TBT with good field INP usually means real visitors interact after the dust settles. The risk lives in the early click, the visitor who taps the menu while the tag pile is still booting. The fix list is the script list: less of it, later, in smaller pieces.
How does this affect the Core Web Vitals?
Blocking time correlates with the CLS. Where the blocking time is low, 91% of sites pass the CLS. Where it is high, 85% do. The decline is gradual. There is no point where sites suddenly start failing.
Chrome field data from 189,915 sites, representing millions of real page loads. How we measured.
Live queries (2) — admin only
SELECT COUNT(*) AS count,
quantile_disc(m.synthetic.tbt_ms, 0.10) AS p10,
quantile_disc(m.synthetic.tbt_ms, 0.25) AS p25,
quantile_disc(m.synthetic.tbt_ms, 0.50) AS p50,
quantile_disc(m.synthetic.tbt_ms, 0.75) AS p75,
quantile_disc(m.synthetic.tbt_ms, 0.90) AS p90,
quantile_disc(m.synthetic.tbt_ms, 0.99) AS p99
FROM sites WHERE m.synthetic.tbt_ms IS NOT NULL;
SELECT CASE WHEN m.synthetic.tbt_ms >= 0 AND m.synthetic.tbt_ms < 100 THEN 0 WHEN m.synthetic.tbt_ms >= 100 AND m.synthetic.tbt_ms < 200 THEN 1 WHEN m.synthetic.tbt_ms >= 200 AND m.synthetic.tbt_ms < 300 THEN 2 WHEN m.synthetic.tbt_ms >= 300 AND m.synthetic.tbt_ms < 400 THEN 3 WHEN m.synthetic.tbt_ms >= 400 AND m.synthetic.tbt_ms < 500 THEN 4 WHEN m.synthetic.tbt_ms >= 500 AND m.synthetic.tbt_ms < 600 THEN 5 WHEN m.synthetic.tbt_ms >= 600 AND m.synthetic.tbt_ms < 700 THEN 6 WHEN m.synthetic.tbt_ms >= 700 AND m.synthetic.tbt_ms < 800 THEN 7 WHEN m.synthetic.tbt_ms >= 800 THEN 8 END AS bucket_idx, COUNT(*) AS n,
quantile_disc(crux."phone".cls, 0.5) AS median,
COUNT(*) FILTER (WHERE crux."phone".cls IS NOT NULL AND crux."phone".cls <= 0.1) * 1.0 / NULLIF(COUNT(*) FILTER (WHERE crux."phone".cls IS NOT NULL), 0) AS good_pct
FROM sites WHERE m.synthetic.tbt_ms IS NOT NULL GROUP BY bucket_idx;