Tags: web-dev concept

Time to First Byte

Date: 2026-08-16


Everything that happens before the browser has anything to work with. It’s the floor under every other loading metric — no amount of front-end optimisation renders content that hasn’t arrived.


What it is

Time to First Byte (TTFB) is the interval from the start of navigation to the arrival of the first byte of the response.

It isn’t a Core Web Vital, but it’s a component of Largest Contentful Paint — the first of its four phases — and a poor TTFB caps how good LCP can possibly be.

What’s inside it

│─────│──────│──────│───────│──────────────│─────────│
 redirect DNS   TCP    TLS    server thinks  first byte
                                              travels

  ↑ often the largest and most overlooked component
ComponentTypical cause of slowness
RedirectsEach is a full round trip before anything starts. http→https→www is two
DNSCold lookup, slow resolver, low TTL
TCPDistance. Round trips are physics
TLSHandshake, mitigated by session resumption and HTTP/2
Server processingDatabase queries, template rendering, API calls
TransitDistance again, plus response size

In plain terms: most of TTFB is usually not your server thinking. It’s round trips — and round trips are governed by distance and by how many you make, not by how fast your code is. See Latency and Bandwidth.

Rough targets

Under 800ms is a reasonable working target for the document request, and under 200ms is achievable for cached or statically-generated pages. [CHECK: Google’s published TTFB guidance against current web.dev documentation before quoting a threshold as authoritative.]

Worked, showing why redirects dominate on mobile:

mobile round trip ≈ 150ms

  http://example.com
    → 301 to https://example.com     150ms
    → 301 to https://www.example.com 150ms
    → DNS + TCP + TLS                ~450ms
    → server                          200ms
                                    ───────
                                      950ms before a single byte of HTML

Removing both redirects saves 300ms before anything else is touched. That’s more than most front-end work achieves, and it’s a DNS and server-config change.

Fixing it, in order of effect

  1. Remove redirect chains. Point DNS at the canonical host directly. Audit with curl -IL — chains accumulate silently over years, especially after migrations
  2. Cache the HTML. A cached document response is the difference between 600ms and 30ms. Full-page caching at the CDN is the single biggest lever available to most sites — CDN Caching
  3. Serve from closer. A CDN or edge rendering cuts the distance component, which is otherwise fixed — Edge Computing
  4. Fix the slow queries. An N+1 query pattern or a missing index is often the whole server component — N+1 Queries, Indexing
  5. Move work off the request. Sending an email, syncing to a CRM or calling an analytics API inline adds its latency to every page load. Queue it — Message Queues
  6. preconnect to origins you’ll definitely need, so their handshakes overlap with the document request rather than following it — Resource Hints

Where it hides

  • Only the document counts for LCP purposes, but subresources have their own TTFB. A slow API behind a client-rendered page moves the problem rather than fixing it
  • Cache hit rate is the real metric. A page cached at 60% has a bimodal TTFB, and the average hides that 40% of users wait for the origin. Look at the distribution, not the mean — Percentiles in Performance
  • Personalisation defeats caching. Any per-user content in the HTML makes the page uncacheable. The fix is usually to cache the shell and fetch the personal bits separately, not to give up on caching
  • Geography. A UK-hosted origin serving international traffic has a TTFB floor set by physics. Segment field data by country before concluding the server is slow
  • Cold starts. Serverless functions idle out; the first request after a quiet period pays initialisation. Shows up as a long tail rather than a raised median

Measuring

  • Field: the Navigation Timing API, responseStart − startTime, collected via Real User Monitoring
  • Lab: DevTools Network panel → Timing tab on the document request, which itemises every component above
  • curl -w for a quick server-side check without browser overhead:
    curl -w "dns %{time_namelookup} connect %{time_connect} ttfb %{time_starttransfer}\n" -o /dev/null -s https://example.com