Total Blocking Time (TBT)
Total Blocking Time measures how long the main thread was too busy to answer a tap or a click. Lighthouse finds every long task after FCPTime until the browser paints the first text or image.. A long task is any main-thread task longer than 50 milliseconds.
The blocking part of a task is the time above those 50 milliseconds. A 120 ms task adds 70 ms. A 45 ms task adds nothing. TBT is the sum.
TBT carries the largest single weight in the Lighthouse performance score: 30 percent, ahead of LCPTime until the largest thing in view (hero image, headline) has painted. and CLSHow much the page jumps around as it loads. Lower is better; 0 is rock-steady.. It is also the metric that moves most when you change the machine that measures it.
The window, and why the shape of the work matters
The window starts at First Contentful Paint. It ends at TTITime until the page reliably responds to input.. Work before the first paint does not count.
Two pages can run the same amount of JavaScript and get very different numbers:
- Page A runs six tasks of 45 ms. Main-thread time: 270 ms. TBT: 0 ms.
- Page B runs two tasks of 135 ms. Main-thread time: 270 ms. TBT: 170 ms.
The shape of the work matters more than the amount. That is why "break up long tasks" is the first item on every fix list. You do not always have to delete the work. You have to cut it into pieces below 50 ms.
The thresholds are a scoring curve, not a limit
Most pages quote "under 200 ms" as if it were a limit. It is one control point on the curve that turns milliseconds into a score from 0 to 100. Lighthouse stores two control points for each device profile:
- Mobile: p10 = 200 ms, median = 600 ms.
- Desktop: p10 = 150 ms, median = 350 ms.
A value at p10 scores 90. A value at the median scores 50. The curve is log-normal, so the middle is steep and the ends are flat. These are the scores it produces in Lighthouse 12.8.2, the version we run:
- 100 ms → 98 mobile, 97 desktop
- 200 ms → 90 mobile, 80 desktop
- 300 ms → 79 mobile, 59 desktop
- 600 ms → 50 mobile, 21 desktop
- 1,200 ms → 21 mobile, 3 desktop
Desktop is scored more strictly: 200 ms scores 90 on mobile, but only 80 on desktop.
TBT is 30 percent of the performance score, so metric points convert straight into overall points. A mobile page that slips from 200 ms to 600 ms loses 40 metric points. That costs 12 points of the overall score.
TBT is not a Core Web Vital. Google publishes no field threshold for it, and the Chrome UX Report does not carry it. The 200 ms number is a scoring choice, and the Lighthouse source says so plainly. The code comment records that real-world data pointed to 19 ms and 189 ms. Those values gave "surprisingly harsh scoring", so the team picked the current ones "semi-arbitrarily".
Why the same page returns a different TBT
TBT is a measure of CPU work. So it depends on the CPU that measured it.
Lighthouse does not run your page on a slow phone by default. It records a trace on the host machine at full speed. Then it simulates a slower device and multiplies the duration of each CPU task by four. Tasks that perform layout get a larger multiplier. The 50 ms rule applies to those simulated durations, not to the real ones.
That gives the 50 ms threshold a real value of about 12.5 ms on the measuring machine:
- A task of 12 ms on the host becomes 48 ms in the simulation. It adds 0 ms.
- A task of 13 ms on the host becomes 52 ms in the simulation. It adds 2 ms.
A faster host runs the same code in less time, so fewer tasks cross the line. This is why a laptop and a CI runner disagree about TBT far more than they disagree about CLS. Two TBT numbers are only comparable when the hardware and the Lighthouse version are the same. The same rule decides why two Lighthouse scores disagree.
TBT is not INP
TBT is a lab metric. Its field counterpart is Interaction to Next Paint (INP). The two do not measure the same thing:
- TBT only looks at the load, between FCP and TTI. INP looks at real interactions across the whole visit.
- TBT counts a busy main thread, even when nobody tried to interact. INP counts what a real visitor waited for.
- A page can report 0 ms TBT and still have a bad INP. The expensive work sits in a click handler that runs after the load.
Treat TBT as an early warning. Google's own documentation says it can flag problems that no visitor experiences.
How to reduce it
- Read the Lighthouse report first. It lists the long tasks, the main-thread work by category, and the JavaScript bootup time.
- Ship less JavaScript. Code splitting and dead-code removal cut download, parse, compile and execution time together.
- Cut the remaining long tasks into pieces below 50 ms. Give the main thread a chance to run between the pieces.
- Delay work that the first screen does not need. Move it after the load, or into a web worker.
- Rank your Third partyCode and assets loaded from another origin — analytics, fonts, ads, widgets. scripts by blocking time. They share the one main thread with your own code. Drop the expensive ones you cannot defer.
What we do about it
Every Lightscore run pins the Lighthouse and Chromium version, and the result records the Lighthouse version that produced the number. You can ask for up to 5 runs per region, and we return the median run, so one slow load does not decide your score. Each region runs on the same machine class, which is the condition that makes two TBT numbers comparable at all.
The raw Lighthouse JSON and HTML come back with every report. The JSON carries
environment.benchmarkIndex, a speed score for the machine that ran your page.
When two TBT numbers disagree, compare that number before you change any code.
What we cannot give you is INP. Our worker loads the page with no visitor and no clicks, so there is no interaction to measure. TBT is the closest lab answer. Get the real one from field data, and see Interaction to Next Paint for what a lab INP number actually contains.
what’s this
The small set of field metrics Google treats as a ranking input and reports in Search Console. We measure their lab equivalents here — real-user field data (CrUX) is a separate signal. TBT is the lab stand-in for INP, not a Core Web Vital itself.
Common questions
What is a good Total Blocking Time?
Under 200 ms on mobile, and under 150 ms on desktop. Those are the values at which Lighthouse scores the metric 90 out of 100. They are scoring control points, not a standard Google publishes for real-user data.
Is Total Blocking Time a Core Web Vital?
No. The three Core Web Vitals are LCP, CLS and INP. TBT is a lab metric that Lighthouse uses as a stand-in for INP, because you cannot collect INP from a single scripted page load.
Why does the same page get a different TBT in different tools?
TBT is a measure of CPU work, so the speed and the load of the machine that ran Lighthouse change the result. Two tools that run the same Lighthouse version on different hardware, or with different CPU throttling settings, report different TBT values for the same page.