Time to First Byte (TTFB) is the time from the browser requesting a page to the first byte of the response arriving. It covers DNS lookup, the TCP/TLS handshake, and the part that usually dominates: the server thinking. Routing the request, running the CMS, hitting the database, assembling the HTML. Nothing else can start until the first byte lands, so a slow TTFB pushes FCP, LCP and every downstream metric back by the same amount.
Reading the thresholds
The Good / Needs-work / Poor bands sit in the summary panel. TTFB is reported in milliseconds and comes in both flavours, a field p75 from real visits and a single lab figure, so your two numbers can differ. It is not a Core Web Vital itself, but Google publishes it as a key diagnostic because it is so often the hidden cause of a poor LCP.
Fixing it is necessary and rarely sufficient
A page cache is the standard answer, and it works: it stores the finished HTML the first time the CMS builds it and serves that copy afterwards, so the server answers sooner. What it does not do is change what the response contains.
We tested that on the least forgiving sample we could find: nine WordPress sites run by the performance industry itself, plugin vendors and publications that write about speed. Their median mobile PageSpeed was 51. On the four where we could confirm the caching tool from outside, the plugin was demonstrably working and the score was still not good: LiteSpeed Cache 49, W3 Total Cache 51, Breeze 61, Cloudflare Rocket Loader 46.
Caching fixes when the response arrives. The stylesheets in its <head> still block, the
hero image is still fetched at the wrong priority, and on a throttled phone that is most of
the score.
The trap we walked into ourselves
Compression is the other classic TTFB lever, and it can move the wrong way. Our own marketing
site was shipping uncompressed HTML, about 126 KB with no Content-Encoding header at all.
The textbook fix was to switch on maximum-quality brotli in .htaccess, so we did:
| No compression | brotli-11 on the fly | gzip | |
|---|---|---|---|
| PageSpeed, mobile | 99 | 99 | 100 |
| Speed Index | 1.6 s | 3.8 s | 2.2 s |
Brotli at quality 11 is CPU-expensive, and on shared hosting, with modest cores contended
between tenants, compressing 126 KB on every request added more server time than the smaller
transfer saved. The page arrived smaller and later. gzip costs a rounding error of CPU and won
outright. If you want brotli’s payload without its per-request cost, pre-compress .br files
at deploy time.
What makes the server slow to answer
- No caching or CDN, so every request hits the origin cold.
- A heavy backend rebuilding the page per request, with database queries and template rendering on every hit.
- Redirect chains before the real response, each hop adding a round-trip ahead of the first byte.
- Slow or overloaded hosting, where a cheap or distant server simply thinks for too long.
- On-the-fly compression tuned too aggressively, as above.
Freshness against speed
Cutting TTFB is mostly a correctness trade rather than a fight with another metric:
- Caching pages risks serving stale content, the classic freshness-versus-speed tension, and it bites hardest on personalised pages that differ per visitor.
- A CDN in front adds a network hop, so an outright cache miss can be slightly slower than hitting the origin directly.
We take the first trade by caching with stale-while-revalidate: the fast cached response goes out immediately and refreshes in the background.
Serving from cache, in code
TTFB is a server-side metric, so the fix lives in server config rather than HTML:
- Cache-Control: no-store
+ Cache-Control: public, max-age=600, s-maxage=600
Or cache at the edge, so the app is only hit when the cache is cold:
location / {
proxy_cache app_cache;
proxy_cache_valid 200 10m;
add_header X-Cache $upstream_cache_status;
}
Where WebSpeed sits in the chain
WebSpeed sits in front of the origin and serves optimised pages from a stale-while-revalidate cache, so repeat requests get a fast first byte instead of waiting for the CMS. It cannot rewrite a slow origin on the very first uncached hit, but it takes the CMS off the critical path for the large majority of visits, and it compresses on dedicated hardware where brotli is free.