/ โ† Core Web Vitals Fixes / High TTFB
In this guide
  1. What TTFB measures and what counts as high
  2. Common causes of a high TTFB
  3. How to measure TTFB and split it into stages
  4. The changes that cut TTFB most
  5. Platform notes
  6. A worked example
  7. The fix, step by step
  8. Edge cases worth knowing
  9. Keeping TTFB low
  10. Questions and answers

What TTFB measures and what counts as high

TTFB runs from the moment navigation starts to the moment the first byte of the response arrives. For a real visitor that includes more than your server's thinking time. It covers any redirects, the DNS lookup, the TCP connection, the TLS handshake, the time the request spends travelling, the time your server takes to build the page and the time the first byte takes to travel back.

TTFB at the 75th percentileRough rating
0.8 s or lessGood
Over 0.8 s up to 1.8 sNeeds improvement
Over 1.8 sPoor

TTFB is not one of the three Core Web Vitals, and Google describes these thresholds as a rough guide rather than a pass mark. It matters because it comes first. If the HTML takes 1.5 seconds to arrive, your LCP cannot be better than 1.5 seconds plus the time to load and draw the main element, which makes the 2.5 second LCP target very hard to meet. The LCP guide shows how TTFB fits into the four parts of LCP time.

In Lighthouse the related audit is called Reduce initial server response time, or document request latency in newer versions. It is measured from Google's test servers, so it shows the server's speed from one place at one moment. The TTFB in the field data section of PageSpeed Insights comes from real Chrome users and includes their redirects and network conditions.

Common causes of a high TTFB

CauseTypical signUsual fix
Redirect chainField TTFB much higher than a direct curl testLink to the final URL; one redirect at most
No page cacheEvery request takes the same long timeFull-page caching for anonymous visitors
Slow queries or pluginsHigh server time even on a quiet serverProfile, replace or fix the slow code
Calls to outside APIs during the requestTTFB varies wildly between runsCache API results or load them later
Too few PHP or Node workersFine when quiet, slow at busy timesRaise workers, or upgrade the plan
Server far from visitorsConnect and TLS times are highCDN that caches HTML, or a nearer server
Sleeping or cold serversFirst request after a pause is very slowKeep-warm settings or an always-on plan
Slow DNSLong DNS lookup on first visitsA fast DNS provider

Redirects are easy to miss because your own tests usually request the final URL. A visitor who types the bare domain or follows an old link may go from http:// to https://, then to www, then to a trailing slash version. Each step is a full round trip before your server even starts on the real page. The redirect chain guide explains how to collapse these.

How to measure TTFB and split it into stages

Use curl from a terminal, or from your server over SSH to remove network distance from the picture. This command prints each stage in seconds, measured from the start of the request:

curl -o /dev/null -s -w "dns %{time_namelookup}  connect %{time_connect}  tls %{time_appconnect}  ttfb %{time_starttransfer}  total %{time_total}\n" https://example.com/

Each figure is cumulative. Read the gaps between them:

Run it five times in a row. The first result may include a cold cache; the later ones show the steady state. To compare cached and uncached responses, add a random query string, which most page caches treat as a new page:

for i in 1 2 3 4 5; do
  curl -o /dev/null -s -w "%{time_starttransfer}\n" "https://example.com/?nocache=$RANDOM"
done

Add -L to follow redirects and see the total cost of a chain, and -I on its own to read headers such as x-cache, cf-cache-status or age, which tell you whether a cache answered.

In the browser

In Chrome DevTools, open the Network panel, reload, click the document request and open the Timing tab. Waiting for server response is the server time. The rows above it show the connection stages, and redirects appear as separate requests at the top of the list.

Ask the server where the time goes

A Server-Timing header lets your code report its own stages, and DevTools shows them in the Timing tab. For example, a page that reports database and template time:

Server-Timing: db;dur=420, tpl;dur=95, cache;desc="MISS"

The changes that cut TTFB most

Full-page caching

For pages that look the same to every visitor who is not logged in, the biggest win by far is serving a stored copy of the finished HTML instead of building it again. A cached page is typically returned in well under 100 ms from the server. On nginx you can cache responses from PHP-FPM directly:

# in the http block
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=PAGES:50m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
map $http_cookie $skip_cache { default 0; ~wordpress_logged_in 1; }

location ~ \.php$ {
    fastcgi_cache PAGES;
    fastcgi_cache_valid 200 10m;
    fastcgi_cache_bypass $skip_cache;
    fastcgi_no_cache $skip_cache;
    add_header X-Cache $upstream_cache_status;
    # existing fastcgi_pass and params here
}

Never cache pages that differ per visitor, such as baskets, checkouts and account pages, and make sure the cache bypasses logged-in users.

Find slow code

When pages must be built per request, profile them. On WordPress, the Query Monitor plugin lists every database query with its time and the plugin that ran it. Look for pages with hundreds of queries, single queries over 50 ms and HTTP API calls made during the page build. Turn on the MySQL slow query log to catch problems across the whole site:

sudo mysql -e "SET GLOBAL slow_query_log = 1; SET GLOBAL long_query_time = 0.5;"
sudo tail -f /var/lib/mysql/$(hostname)-slow.log

A persistent object cache such as Redis also helps database-heavy sites by keeping the results of repeated queries in memory between requests.

Move HTML closer to visitors

A CDN only helps TTFB if it caches the HTML itself. Putting images and CSS on a CDN is good for those files, but the page request still travels to your server. If your audience is spread across countries, cache HTML at the edge, for example with a Cloudflare cache rule set to cache eligible HTML for anonymous visitors, or with Cloudflare APO on WordPress. The CDN and origin redirects guide covers loops that can appear when you change CDN settings.

Platform notes

A worked example

A WordPress shop for a small UK business has a field TTFB of 1.9 seconds on mobile. A curl test with a random query string gives about 1.7 seconds each time, while the same page without the query string returns in 0.15 seconds with X-Cache: HIT. The server is fast when the cache answers, so the slow part is building the page.

Query Monitor shows 400 database queries on product category pages, almost all from a related-products plugin running a separate query for each item. Replacing it with the theme's built-in related products cuts the count to 60 queries and the uncached build time to 0.45 seconds. The team also finds that every visitor arriving from an old campaign link goes through two redirects, and updates the links. Four weeks later the field TTFB sits under 0.6 seconds, and mobile LCP has improved by a similar amount.

The fix, step by step

Step 1

Measure TTFB in stages

Run the curl stage command with time_namelookup, time_connect, time_appconnect and time_starttransfer against the page five times. Run it from your own computer and again from the server itself over SSH. Note the gap between the TLS and TTFB figures, which is the server build time. If the gap is small but the connect time is large, distance is the issue. Record the numbers so you can confirm later that each change made a measurable difference.

Step 2

Compare cached and uncached

Request the same page with a random query string such as ?nocache=123 and compare the TTFB with a normal request. Read the response headers with curl -I and look for a cache status header such as X-Cache or cf-cache-status. If the cached version is fast and the uncached one is slow, caching will give the biggest win. If both are slow, the cache is not answering at all, or the slowness comes before the server, such as DNS or distance.

Step 3

Remove redirect hops

Run curl -sIL on the bare domain with http:// and follow each Location header to the final URL. Every hop adds a full round trip before the page begins. Make sure any old address goes to the final URL in a single redirect, and update internal links, menus, canonical tags and campaign links to point at the final URL directly. Confirm by running the command again and checking that it shows one redirect at most before a 200 response.

Step 4

Turn on full-page caching

Enable full-page caching for anonymous visitors, using your host's cache, a caching plugin or nginx fastcgi_cache. Exclude baskets, checkouts, account pages and logged-in users. Use only one page cache layer to avoid conflicts. Set the cache to ignore marketing parameters such as utm_source. Confirm it works by requesting a page twice in a private window and checking that the second response shows a cache hit and a TTFB well under 200 ms from the server.

Step 5

Profile slow pages

For pages that cannot be cached, find where the build time goes. On WordPress, install Query Monitor and open a slow page while logged in as an admin, then sort queries by time and group them by component. Elsewhere, add a Server-Timing header or enable the slow query log. Look for plugins running hundreds of queries, missing database indexes and outside API calls during the request. Fix or replace the worst offender, then measure the uncached TTFB again.

Step 6

Check workers and hosting limits

Look at your server's error log for messages that PHP-FPM reached pm.max_children, and at CPU and memory use during busy periods. If requests queue, raise the worker limit within the memory you have, or move to a plan with more resources. Check whether your hosting puts idle sites to sleep, which makes the first request after a pause very slow. Confirm by testing TTFB at your busiest time of day and comparing it with a quiet period.

Step 7

Cache HTML near visitors

If your visitors are spread across countries, set up a CDN rule that caches HTML for anonymous visitors, not only images and CSS. On Cloudflare, use a cache rule that makes eligible pages cacheable, or APO for WordPress, and bypass the cache when login or basket cookies are present. Test from a distant location and read the cf-cache-status header. A value of HIT with a low TTFB confirms the edge is answering for you.

Step 8

Check field data after the change

Lab tests confirm the fix works, but real-visitor TTFB includes redirects, distance and busy periods. Watch the TTFB and LCP figures in the field data section of PageSpeed Insights, which reflects the previous 28 days, and the Core Web Vitals report in Google Search Console. Expect the figures to move gradually over several weeks. If field TTFB stays high while your tests are fast, look again at redirects from external links and at visitors far from your server.

Edge cases worth knowing

Keeping TTFB low

Add a simple check to your routine: run the curl stage command on your home page and one page from each template every month, cached and uncached, and keep the numbers in a spreadsheet. A sudden rise usually follows a new plugin, a theme update or a hosting change, and it is far easier to trace within a week than within a year.

Watch the TTFB figure in the field data in PageSpeed Insights and the Core Web Vitals report in Search Console, because real-visitor numbers include redirects and distance that lab tests miss. Re-test after every caching or CDN change, and read the cache status header to confirm the cache is still answering.

Questions and answers

1. What is a good TTFB?

A good TTFB is about 0.8 seconds or less for most real visitors, measured at the 75th percentile. Google gives this as a rough guide, with values over 1.8 seconds considered poor. TTFB is not a Core Web Vital itself, but it is the first part of every page load, so a high value makes it hard for Largest Contentful Paint to reach the 2.5 second target. For cached pages served from a nearby server, well under 0.3 seconds is achievable.

2. Why is my TTFB high when my site is fast for me?

Your TTFB is probably high for visitors because they see a different path through your site than you do. You may be hitting a warm cache, testing the final URL directly or sitting close to the server. Visitors may arrive through redirects, land on uncached pages, come from far away or visit when the server is busy. Being logged in can make your own experience slower instead. Test in a private window, from several locations and with a random query string.

3. Does a CDN fix high TTFB?

A CDN fixes high TTFB only when it caches the HTML of your pages, not just images, scripts and stylesheets. If the CDN passes every page request to your server, visitors still wait for your server to build the page, and the CDN can even add a little time. Set up rules to cache HTML for anonymous visitors, and confirm with the cache status header. A CDN also shortens connection and TLS time for distant visitors, which helps a little on its own.

4. How do I check TTFB with curl?

You can check TTFB with curl by running it with the write-out option and the time_starttransfer variable, which reports the seconds until the first byte arrived. Adding time_namelookup, time_connect and time_appconnect shows the DNS, connection and TLS stages as well, so you can see where the wait comes from. Send the output to /dev/null so only the timings print. Run it several times, because the first request may hit a cold cache and give a misleading result.

5. Do redirects affect TTFB?

Yes, redirects add directly to the TTFB that real visitors experience. Each redirect is a full request and response before the browser can ask for the next address, and a change of host, such as from the bare domain to www, can also need a new connection. Field TTFB in PageSpeed Insights includes this time. A chain from http to https to www can add several hundred milliseconds on mobile, so link to the final URL and keep any redirect to a single hop.

6. Why is TTFB high on WordPress?

WordPress TTFB is usually high because pages are built from scratch on every request without a page cache, or because plugins run many slow database queries during each build. Other common causes are an old PHP version, too few PHP workers on busy hosting, scheduled WP-Cron tasks running during visitor requests and plugins that call outside services while the page is built. Full-page caching fixes most of it for visitors, and Query Monitor shows which plugin is behind the slow uncached pages.

7. Will lowering TTFB improve my LCP?

Lowering TTFB almost always improves LCP by a similar amount, because the browser cannot start drawing anything until the HTML arrives. A saving of 500 ms on TTFB usually brings LCP 500 ms earlier, unless something else, such as a lazy-loaded hero image or blocking scripts, was holding LCP back by more. Check the LCP breakdown in PageSpeed Insights after the fix. If TTFB is now small and LCP is still slow, look at how the main element is loaded and drawn.

Check your server response time

The PageSpeed checker on aiwebpageseo.com reports server response time alongside LCP and the files that slow your page, so you can see whether TTFB is the first thing to fix.

Open Core Web Vitals Fixes โ†’
๐Ÿ’ฌ Got a problem?
Related Guides: All Core Web Vitals Fixes  ·  Fixing Time to First Byte  ·  Slow LCP: fixing Largest Contentful Paint  ·  Fixing redirect chains that contain http  ·  Why is my LCP so high on mobile  ·  Learning Hub

About aiwebpageseo

aiwebpageseo.com is a data-driven SEO and AEO (Answer Engine Optimisation) platform providing a free suite of technical SEO tools. Rather than relying on AI-theorised assumptions, the platform analyses live URL performance, delivering objective diagnostics, page speed metrics, CLS debugging, and site crawl data alongside actionable technical tutorials.