TTFB · Performance troubleshooting

How to Reduce TTFB: 12 Causes and Fixes for Slow Server Response

Diagnose where the first-byte wait comes from, then fix the network, cache or origin bottleneck that actually matters.

Real browser network timing and distributed server infrastructure illustrating DNS, TLS, cache and origin delays that affect TTFB

To reduce TTFB, work out which part of the wait is slow before changing anything. Time to First Byte covers redirects, DNS, connection setup, the trip to the server, the server's own work and the trip back. A fix aimed at the wrong segment leaves the number where it was. In practice, most slow results trace back to three things: HTML that is generated from scratch on every request, an origin that is far from the visitor, or a cache that exists but is not being hit.

The 12 causes below are grouped by where the time is lost, with a fix for each. If you are unsure whether your number is a problem at all, start with what counts as a good TTFB.

Find the slow segment first

A browser-level TTFB is a single composite number. For a first approximation of the network phases, use curl:

curl -o /dev/null -s -w "dns %{time_namelookup}\nconnect %{time_connect}\ntls %{time_appconnect}\nfirst byte %{time_starttransfer}\n" https://example.com/

Each value is cumulative from the start of the request. The gap between tls and first byte is roughly one round trip plus the server's thinking time. Add -L to follow redirects, then compare the total with a direct request to the final URL to estimate their cost.

Two more comparisons narrow things down quickly: the same URL from a nearby region and a distant one, and the same URL twice in a row.

What you seeLikely areaCauses to check
Slow from every region, including one next to the originOrigin work5, 7, 8, 9, 10
Fast near the origin, slow far awayNetwork distance3, 4, 5
First request slow, second request fastCold cache or cold start6, 11
Slow only for logged-in or cart pagesUncached dynamic work7, 8, 9
Slow in bursts, fine otherwiseCapacity or background jobs10
Large gap between the first URL and the final URLRedirects1

These are starting points, not diagnoses. One test is one sample, so repeat each comparison a few times before trusting a pattern.

Causes in the network path

1. Redirect chains

A request that goes from http://example.com to https://example.com to https://www.example.com/ pays for two extra round trips before the real document is even requested. If a hop changes hostname, it can add a new DNS lookup and a new TLS handshake as well.

Fix: Collapse the chain to a single hop at the server or edge. Update internal links, canonical tags, sitemaps and ad destination URLs to point at the final URL. HSTS removes the HTTP-to-HTTPS hop for returning browsers.

2. Slow DNS resolution

A DNS lookup happens before any connection can open. Slow authoritative nameservers, long CNAME chains and very short TTLs all make uncached lookups more frequent or more expensive.

Fix: Use an authoritative DNS provider with an anycast network. Keep CNAME chains short. Avoid TTLs of a few seconds unless you rely on fast failover. DNS is rarely the largest share of a slow TTFB, so measure it before migrating providers.

3. Expensive connection and TLS setup

A new connection costs round trips: one for TCP, at least one more for TLS 1.3, and two for a full TLS 1.2 handshake. Over a long path each round trip can be 150 ms or more, so setup alone can consume a visible part of the budget.

Fix: Enable TLS 1.3 and session resumption. Turn on OCSP stapling and keep the certificate chain short. HTTP/3 combines transport and encryption setup, which helps most on high-latency and lossy connections; the HTTP/2 vs HTTP/3 comparison covers where that gain is real and where it is small. Terminating TLS at a nearby edge shortens every one of these round trips.

4. Distance between visitor and origin

Server tuning cannot remove the travel time of a request that crosses an ocean. An origin in Virginia that responds in 80 ms locally will still look slow from Sydney, because the round trips themselves dominate.

Fix: Serve the HTML from closer to the visitor. For cacheable pages that means caching the document at a CDN edge, not only the images and scripts. For dynamic pages the options are regional origins or read replicas, or an edge layer that keeps warm connections to the origin. Why website speed varies by location explains how to tell distance apart from routing and caching effects.

Causes in the cache layer

5. The HTML is not cached at all

This is a common cause on CMS-driven sites. Every anonymous visit runs the full application stack, queries the database and renders templates, to produce a page identical to the one served a second earlier.

Fix: Add a full-page cache. Depending on the stack, that could be LiteSpeed Cache, Varnish, nginx fastcgi_cache, or a framework-level static or incremental build. Then extend it to the CDN so anonymous HTML is answered at the edge. Many CDNs cache static assets by default and pass HTML straight through, so this usually needs an explicit rule.

6. The cache exists but keeps missing

A page cache with a low hit rate behaves much like no cache. Typical reasons:

  • Marketing parameters such as utm_source or fbclid can create a separate cache entry for every click.
  • A cookie set on all visitors makes every response look personalized.
  • A broad Vary header, such as Vary: User-Agent, fragments the cache.
  • TTLs are short, or every content edit purges the whole cache.

Fix: Check the response headers first. cf-cache-status, x-cache, age and similar headers show whether a request was a hit. Strip or ignore tracking parameters in the cache key, stop setting cookies on anonymous pages, narrow Vary, and purge by URL or tag. stale-while-revalidate lets the cache answer immediately while it refreshes in the background.

Causes at the origin

7. Slow database queries

Unindexed lookups, N+1 query patterns and oversized result sets add up on every uncached request. On WordPress, a bloated autoloaded options table is a frequent offender.

Fix: Turn on the slow query log and fix what it shows, since guessing rarely finds the real query. Add missing indexes, batch repeated queries, and put an object cache such as Redis or Memcached in front of results that rarely change.

8. Heavy application code

Each plugin, middleware layer and template helper runs before the first byte leaves. An outdated runtime or a missing opcode cache multiplies that cost.

Fix: Confirm OPcache, or your platform's equivalent, is enabled and has enough memory. Upgrade to a current runtime version. Then profile a real request and remove or replace the slowest components. Deactivating plugins one at a time works on small sites, but a profiler gives the answer faster.

9. Blocking calls to external services

If rendering waits on a remote API for inventory, personalization, geolocation or a licence check, that service's latency becomes part of your TTFB. When the service has a bad day, so does your page.

Fix: Set short timeouts with a sensible fallback. Cache responses that don't change per request. Move work that doesn't have to block the document into a background job, or fetch it from the browser after the page has loaded.

10. A saturated or under-provisioned server

When all PHP workers or application threads are busy, new requests queue. The code is no slower, but the visitor waits anyway. Shared hosting, memory swapping, backup jobs and aggressive crawlers all produce this pattern, which tends to show up as intermittent spikes.

Fix: Look at CPU, memory, swap and worker-pool saturation at the times TTFB spikes. Size the worker pool to available memory, rate-limit abusive bots, and move cron and backup jobs off peak hours. If the server is at its limit under ordinary traffic, more capacity is the fix; caching (cause 5) often reduces how much is needed.

11. Cold starts

Serverless functions, containers scaled to zero and idle application pools need time to spin up, and the first visitor after a quiet period pays for it. The same applies after a deploy or a full cache purge, when every cache is empty at once.

Fix: Keep a minimum number of warm instances for latency-sensitive routes. Trim startup work and dependency size. After a deploy or purge, preload the cache for the pages that matter most.

12. The response is held back before sending

Some stacks build the entire page in a buffer and release it only when rendering finishes, so TTFB equals total generation time. Compressing dynamic HTML on the fly at maximum Brotli level adds CPU time for a small size gain. Each proxy, WAF or load balancer in the chain can add its own buffering and inspection delay.

Fix: Where the framework supports it, flush the document head early or stream the response, so the browser can start fetching CSS while the rest renders. Use moderate compression levels for dynamic content and reserve the highest levels for precompressed static files. Review whether each layer in the proxy chain is needed.

Check that the fix worked

Test the same URL from the same location before and after the change, several times each. A single faster run can come from a warm cache or a reused connection.

Latixo's Website Speed Test loads the page in a real Chromium browser from a selected Browser Node and reports TTFB from navigation start to the first response byte. It also shows the main document's HTTP status and negotiated protocol. Eight locations are currently available: Virginia, Seattle, Nuremberg, Tokyo, Singapore, São Paulo, Beijing and Sydney. Running the same URL from a nearby and a distant location is a quick way to see whether an origin fix or an edge fix moved the number. Each run is a single lab sample from one location, not a measurement of what all visitors in that country experience. The metrics guide explains how to read the result.

If you have field data, watch the 75th percentile over the following weeks. That is where a real improvement shows up for actual visitors.

What a lower TTFB will not fix

TTFB ends when the first byte arrives. A page that responds in 200 ms and then loads 4 MB of JavaScript is still slow. Trading TTFB for a worse outcome is also possible: an empty application shell returns quickly, but the visitor waits longer for content than with a server-rendered page that took slightly more time to respond. Judge the change by what happens to Largest Contentful Paint as well as by TTFB itself.

Common questions

Does a CDN reduce TTFB?

Most directly when it can answer the response itself. If HTML passes through to the origin on every request, the CDN shortens the TLS handshake but the origin wait remains. The gain comes from caching the document at the edge.

Why is TTFB higher in a speed test than in my own browser?

Your browser usually has DNS cached and a connection already open, and you may be logged in near the origin. A test starts cold from another location. Both numbers are real; they describe different visits.

Does TTFB affect SEO?

TTFB is not a Core Web Vital. It matters indirectly, because a late document delays LCP, which is one. A very slow origin can also reduce how many pages a crawler fetches.

Should I aim for the lowest possible TTFB?

No. Once the document arrives early enough that it is no longer what delays rendering, further effort is better spent on what happens after the first byte.