TTFB Explained: How Your Hosting Affects Site Speed, and How to Fix a Slow First Byte
Time to First Byte (TTFB) is the time from the moment a browser starts navigating to a page until the first byte of the server’s response arrives, and it is set mostly by your hosting, your caching and your redirects. Google’s web.dev guidance calls a TTFB of 0.8 seconds or less good and more than 1.8 seconds poor, measured at the 75th percentile of real visits.
TTFB is not a Core Web Vital, but every millisecond of it is added to Largest Contentful Paint (LCP), which is. This guide explains what TTFB includes, how to measure each part of it (with a curl command you can paste), the usual reasons a first byte is slow, and the fixes in the order they tend to pay off: full-page caching, PHP OPcache, a CDN that caches HTML, fewer redirects, modern protocols and 103 Early Hints.
Key facts
- ≤ 0.8 s — Good TTFB at the 75th percentile (web.dev)
- > 1.8 s — Poor TTFB; in between needs improvement
- 2,270 ms — Median p75 TTFB of origins with poor LCP (web.dev, 2024)
- 5 phases — Redirects, service worker, DNS, connection and TLS, request
What TTFB measures
TTFB covers everything that happens between a visitor starting a navigation and the first byte of the HTML response arriving, not just the time your server spends building the page.
According to web.dev’s TTFB definition, it is the sum of these phases:
- Redirect time: every 301 or 302 hop before the final URL, each of which may need its own DNS lookup and connection.
- Service worker startup time, if the site registers one.
- DNS lookup: turning your domain name into an IP address.
- Connection and TLS negotiation: the TCP handshake and the HTTPS handshake (or the combined QUIC handshake on HTTP/3).
- The request phase: sending the request and waiting until the first byte of the response comes back. This is where your server’s own work happens: PHP or Node starting up, database queries, template rendering.
That split matters because the fixes are different. A slow DNS provider, a redirect chain and a slow database query all show up as the same “slow TTFB” number, but only one of them is solved by better hosting.
The thresholds, and why TTFB drags down LCP
web.dev sets the TTFB thresholds at 0.8 seconds for good and 1.8 seconds for poor, assessed at the 75th percentile of page loads, so three out of four visits should get their first byte within 0.8 s.
- Good: 0.8 s or less
- Needs improvement: more than 0.8 s and up to 1.8 s
- Poor: more than 1.8 s
web.dev is explicit that TTFB is not a Core Web Vital, and says a site does not strictly need to hit the good threshold as long as TTFB does not stop it scoring well on the metrics that matter. The catch is that it almost always does. LCP is counted from the start of navigation, and the browser cannot discover your hero image, stylesheet or fonts until the HTML starts arriving, so TTFB is the first slice of every LCP. With a good LCP threshold of 2.5 seconds, a 1.5-second first byte leaves only one second for everything else.
This is not a theoretical problem. In an August 2024 analysis of Chrome field data, the web.dev team found that among origins with poor LCP, the median 75th-percentile TTFB was 2,270 ms: on its own, almost enough to guarantee a failing LCP before a single image is downloaded. Image compression does not help a page whose server takes two seconds to answer. Our Core Web Vitals explainer covers LCP and CLS, and the INP guide covers the responsiveness metric, which TTFB does not affect.
How to measure TTFB: field data, DevTools, curl and Server-Timing
Measure TTFB from real visitors first, because it varies with each visitor’s location, network and whether they hit a cached copy; then use lab tools to break a slow number into its phases.
Field data
- PageSpeed Insights: the top “Discover what your real users are experiencing” section lists TTFB under other notable metrics, from the Chrome UX Report (CrUX), at the 75th percentile over the previous 28 days. If the URL has too little traffic it falls back to origin-level data, and if the origin has none you only get the lab report.
- CrUX itself, through its API, BigQuery dataset or the CrUX Vis dashboard, for history over time.
- Your own real-user monitoring with the
onTTFB()function of Google’s web-vitals library, which covers pages that are too quiet for CrUX.
Chrome DevTools
Open the Network panel, reload, click the HTML document (the first row) and open the Timing tab. It splits the request into Queueing, DNS Lookup, Initial connection, SSL, Request sent and Waiting for server response; that last bar is your server’s think time. Lighthouse (in DevTools and PageSpeed Insights) also has a document request latency insight that flags redirects, slow server responses and missing text compression on the main document.
curl, from the command line
curl can print every phase of a single request. This works in macOS and Linux terminals, and on Windows 10 and 11 as curl.exe (in Windows PowerShell 5.1, type curl.exe, because plain curl is an alias for a different command):
curl -o /dev/null -s -L -w "dns: %{time_namelookup}s\ntcp: %{time_connect}s\ntls: %{time_appconnect}s\nredirects: %{time_redirect}s\nttfb: %{time_starttransfer}s\ntotal: %{time_total}s\nhttp: %{http_version} status: %{http_code}\n" https://www.example.com/On Windows, replace /dev/null with NUL. Each value is measured from the start of the request, so they are cumulative: time_starttransfer is curl’s TTFB, and the gap between time_appconnect and time_starttransfer is roughly the server’s processing time. time_redirect is the time spent on all redirect hops before the final request. Run it five or ten times and ignore the first run, which may hit a cold cache. Remember that curl measures from your machine, not your visitors’; a server in Virginia will look fast from Virginia.
Server-Timing: let the server explain itself
The Server-Timing response header reports how long named steps took on the server, and Chrome DevTools shows it in the request’s Timing tab. web.dev’s TTFB optimisation guide gives this format:
Server-Timing: db;desc="Database";dur=121.3, ssr;desc="Server-side Rendering";dur=212.2In PHP you can time a block with hrtime() and send the header before any output:
<?php
$t0 = hrtime(true);
$rows = $pdo->query("SELECT id, title FROM posts ORDER BY created_at DESC LIMIT 20")->fetchAll();
$dbMs = (hrtime(true) - $t0) / 1e6; // nanoseconds to milliseconds
header(sprintf("Server-Timing: db;desc=\"Database\";dur=%.1f", $dbMs));The same values are readable in the browser through performance.getEntriesByType("navigation")[0].serverTiming, so your real-user monitoring can collect them too. Server-Timing is visible to anyone who opens DevTools, so do not put internal hostnames or query text in the description.
Why a first byte is slow: the usual causes
Most slow TTFB on small-business sites comes from one of six causes, and the curl and Server-Timing numbers above usually tell you which.
- No full-page cache. Every visit makes PHP rebuild the page from scratch: load the CMS, run plugins, query the database, render templates. A WordPress page that takes 900 ms to build takes 900 ms for every visitor.
- Slow PHP or database work. Unindexed queries, dozens of queries per page, external API calls made during the request, or an outdated PHP version. If Server-Timing shows most of the time in
db, start with MySQL indexing. - Crowded shared hosting. web.dev’s guidance says plainly that shared hosting is not adequate for sites that do personalisation and database work. On a crowded server, the same page can take 300 ms one minute and 3 seconds the next, which shows up as a bad 75th percentile.
- Redirect chains.
http://example.comtohttps://example.comtohttps://www.example.comtohttps://www.example.com/home/is three extra round trips before the real request starts, and links from ads, email and social posts often hit the worst of them. - Distance and no CDN. A visitor in London requesting a page from a single server in Texas pays for the round trips of DNS, TCP, TLS and the request itself across the Atlantic.
- Cold starts. Serverless functions, containers that scale to zero and PHP-FPM pools with too few idle workers all add start-up time to the first request after a quiet period.
The fixes, in the order they usually pay off
The biggest TTFB win for most sites is to stop generating the same HTML on every request; after that, remove round trips, then move the bytes closer to the visitor.
1. Full-page caching
Store the finished HTML of each public page and serve it without running the CMS. On WordPress this is a caching plugin or your host’s built-in cache (LiteSpeed Cache on LiteSpeed servers, Nginx FastCGI cache on many managed hosts). On a custom PHP site, a few lines in front of your router do the job:
<?php
// Minimal file cache for anonymous GET requests; skip logged-in users and forms.
$cacheable = $_SERVER["REQUEST_METHOD"] === "GET" && empty($_COOKIE["session"]);
$file = __DIR__ . "/cache/" . md5($_SERVER["REQUEST_URI"]) . ".html";
if ($cacheable && is_file($file) && filemtime($file) > time() - 600) {
header("X-Cache: HIT");
readfile($file);
exit;
}
ob_start();
// ... build the page as usual ...
$html = ob_get_flush();
if ($cacheable && http_response_code() === 200) {
file_put_contents($file, $html, LOCK_EX);
}Adapt the cookie name to your own session cookie, and clear the cache when content changes.
2. PHP OPcache
The PHP manual describes OPcache as storing precompiled script bytecode in shared memory, so PHP does not have to load and parse scripts on each request. It ships with PHP but is not always switched on. A typical php.ini block:
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=10000
opcache.validate_timestamps=1
opcache.revalidate_freq=60Check it is active with php -i | grep opcache.enable or a phpinfo() page (delete it afterwards). Also run a supported PHP version; old versions are slower and no longer get security fixes.
3. Cut redirects and add HSTS
Link to final URLs everywhere: navigation, sitemaps, canonical tags, ads. web.dev recommends the Strict-Transport-Security header so returning browsers go straight to HTTPS without an HTTP-to-HTTPS redirect; our security headers guide covers setting it safely. Collapse http, www and trailing-slash rules into a single hop.
4. A CDN that caches HTML, not just images
A CDN puts your content on servers near visitors, and web.dev lists the side benefits: fast DNS, HTTP/2 and HTTP/3, TLS 1.3 and automatic compression. But a CDN only lowers TTFB if it caches the HTML too. Cloudflare, for example, does not cache HTML by default and will not cache a response that sets a cookie; you need a Cache Rule marking your public pages as eligible for cache, with logged-in users, carts and admin paths bypassed. Send a sensible Cache-Control header from the origin, and avoid tracking query strings that make every URL unique and defeat the cache.
5. HTTP/3 and TLS 1.3
HTTP/3 runs over QUIC, which combines the transport and encryption handshakes and avoids TCP’s head-of-line blocking. TLS 1.3 needs fewer round trips than TLS 1.2. Most CDNs offer both with a toggle; on your own server, check that your web server and TLS library support them. The gain is largest on mobile and long-distance connections.
6. Better hosting, when the server itself is the bottleneck
If an uncached request still takes over a second after the steps above, the server is underpowered or overcrowded. Move to hosting with dedicated CPU and memory, a current PHP version, and access to server configuration.
103 Early Hints: what it does and does not fix
103 Early Hints lets a server tell the browser which critical files to fetch or connect to while it is still building the HTML, so server think time is not wasted.
The server sends an interim 103 response with Link headers, then the real 200 response when it is ready. The example from MDN’s 103 reference:
103 Early Hints
Link: </style.css>; rel=preload; as=style
200 OK
Content-Type: text/htmlPoints to know before relying on it:
- Support: Chrome has supported Early Hints since version 103, for both
preconnectandpreload. Firefox implements both. Safari is reported to honour onlypreconnect. Browsers generally accept Early Hints only over HTTP/2 or HTTP/3. - Navigations only: it applies to the main document request, and browsers discard the hints if the final response is a cross-origin redirect.
- Where to enable it: Chrome’s documentation lists Cloudflare, Fastly and Akamai among platforms with built-in support, plus Apache (mod_http2), Nginx, H2O and Node.js.
- It can flatter your TTFB. web.dev notes that a 103 response can count as the first byte, so a site using Early Hints may report a fast TTFB while its HTML is still slow. Use Server-Timing or the
finalResponseHeadersStarttiming to see the real backend time.
Early Hints helps the resources that follow the HTML start sooner; it does not make the HTML itself arrive sooner. Fix the slow server first.
Why crawlers and AI fetchers care about your first byte
Search engine crawlers and AI fetchers request the same HTML your visitors do, and Google documents that slow responses reduce how much it crawls.
Google’s crawl budget guide says that if a site responds consistently and its response times, “including latency and Time-to-First Byte”, stay stable or improve, Googlebot’s crawl capacity limit goes up; if the site slows down or returns 5xx or 429 errors, the limit goes down and Google crawls less. That guide is written mainly for large sites, but the principle applies to any site: a slow server gets fewer pages crawled. Search Console’s Crawl Stats report shows Googlebot’s average response time for your host.
For AI assistants, be careful with claims. Some of their fetchers, such as ChatGPT-User and Claude-User, fetch pages live while a person is waiting for an answer. None of the AI operators we checked (OpenAI, Anthropic, Perplexity) publishes a fetch timeout, so any specific number you see quoted is a guess. What is safe to say is that a page returning its first byte in 200 ms is less likely to be dropped than one taking several seconds, and that a fast, server-rendered HTML response is the easiest kind for any fetcher to use. How AI assistants read a web page covers fetching and extraction in detail, and AI crawlers in server logs shows how to see which bots fetch what, and how long your server took to answer them.
One related trap: if a CDN or firewall challenges bots, their “first byte” is a challenge page, not your content. Check bot rules alongside speed; see Cloudflare AI Crawl Control.
Limits: when TTFB is not your problem
A good TTFB is necessary for a fast page but nowhere near sufficient, and chasing the last 100 ms is rarely worth it.
- If TTFB is already under about 0.8 s at p75 and LCP still fails, the time is going elsewhere: a late-discovered hero image, render-blocking CSS, web fonts or client-side rendering. See what makes a website load fast.
- Personalised and logged-in pages cannot be fully cached. Cache the public shell, and load the personal parts separately or accept a slower first byte for signed-in users.
- Lab numbers from one location do not represent a global audience. A CDN may cut TTFB for distant visitors far more than any server upgrade.
- Cached TTFB can hide a slow backend. web.dev warns about this: the cache-miss path still matters for crawlers, new pages and rarely visited URLs. Test with a cache-busting URL or header your setup recognises, not only the warm cache.
- Single-page apps can have an excellent TTFB and still show nothing useful, because the first byte is an empty shell. Server-render the main content.
Product facts: the AI Indexing Pack
The AI Indexing Pack is about how AI agents read your site, not about server speed: none of the items below is a cache or hosting layer, so it will not lower your TTFB. It is listed because it is the product we sell for the agent-readiness side of a site. Stated plainly, so it can be checked against the product page:
- What it is: the AI Indexing Pack is a set of files you upload to your own website. It is sold by Built2WinWeb as a one-time purchase, with no subscription.
- What it ships: (1) a working MCP server using the Streamable HTTP transport, with typed output schemas and tool annotations; (2) Markdown content negotiation, so agents can request a clean text version of each page; (3) llms.txt, agents.txt and agent cards; (4) the full
/.well-known/discovery tree; (5) OAuth protected-resource metadata; (6) bot access control that verifies crawler identity; (7) a README with a verification checklist. - Requirements: PHP 7.4 or newer, Apache or LiteSpeed with
.htaccesssupport, FTP access, and a domain you control. Installation takes about 30 minutes. - What it is not: it is not a WordPress plugin (that is the separate WordPress edition, which needs WordPress 6.0+ and PHP 8.0+), it does not write content for you, it does not guarantee rankings or citations, and it is not a managed service.
- Free routes in: sites built on AIWebBuilding get the core built in, and a 50-day streak on FreeAIBoost unlocks the pack for one domain. Current prices are on the product pages.
Related reading
Frequently asked questions
What is a good TTFB?
web.dev calls a TTFB of 0.8 seconds or less good and more than 1.8 seconds poor, measured at the 75th percentile of real page loads.
Is TTFB a Core Web Vital?
No. The Core Web Vitals are LCP, INP and CLS. TTFB matters because it is added to LCP: the browser cannot start loading the main content until the HTML starts arriving.
How do I check TTFB from the command line?
Run curl with -w and the %{time_starttransfer} variable, which reports the time until the first response byte; %{time_namelookup}, %{time_connect} and %{time_appconnect} show DNS, TCP and TLS. Run it several times and measure from more than one location if you can.
What is the fastest way to improve TTFB on a WordPress or PHP site?
Usually full-page caching, so public pages are served as stored HTML instead of being rebuilt on every request, together with PHP OPcache and removing redirect chains. If uncached pages are still slow, look at database queries and hosting.
Does 103 Early Hints reduce TTFB?
It lets the browser start fetching critical CSS or connecting to other origins while the server builds the HTML, but it does not make the HTML arrive sooner. Because a 103 response can count as the first byte, it can make TTFB look better than the real backend time.
Is your hosting slowing you down?
We build fast, server-rendered sites with caching set up properly from day one. Tell us about your site and we will look at where the time goes.
Get a free quote