Back to Performance
Performance
easy
mid

What is Time to First Byte and how do you measure and improve it?

TTFB = time from navigation request to first byte of response. Target: < 200ms cached, < 600ms uncached. Drivers: DNS, TCP/TLS, server response time, redirect chain. Fix: CDN edge caching, geographically close origin, HTTP/2/3, reduce origin work (caching layer, async work moved off the critical path), eliminate redirects, persistent connections.

5 min read·~15 min to think through

TTFB is the time from "user hit Enter" to "first byte arrives" — the pre-render latency the browser can't do anything about. Fixing it improves every downstream metric (FCP, LCP, INP).

What's in TTFB

ts
TTFB = DNS + TCP + TLS + Request + Server processing + Initial response transit

Each segment is a target.

Targets

  • < 200ms when cached at the CDN.
  • < 600ms for uncached / dynamic responses.
  • > 1000ms is a serious problem.

Measured at p75 — averages hide tail latency.

Drivers of TTFB

DNS lookup

Cold lookups take 20–100ms. Mitigations:

  • <link rel="dns-prefetch"> for third-party origins.
  • Long DNS TTLs.

TCP + TLS handshake

100–300ms cold. Mitigations:

  • HTTP/2 multiplexing (one connection serves many requests).
  • HTTP/3 (QUIC) — 0-RTT resumption.
  • TLS session resumption.
  • Persistent connections.

Server processing

The biggest variable. Drivers:

  • DB queries (especially N+1).
  • External API calls in the request path.
  • Heavy template rendering.
  • Cold-starts (serverless).

Redirects

Each redirect adds an entire round trip + handshake. Eliminate or collapse.

Network distance

If origin is in us-east and user is in Singapore, base RTT is 200ms+. Edge caching is the answer.

Fixes

1. CDN edge caching

The biggest single win. Cache static assets (immutable, hashed) forever; cache HTML where possible (with smart invalidation):

  • Cache-Control: public, max-age=86400, stale-while-revalidate=600
  • ISR (Next.js) / per-route caching.
  • Personalized content — use ESI/edge personalization or split static shell from dynamic data.

2. Get the origin closer

  • Multi-region deployment.
  • Edge runtime for the API layer (Vercel Edge, Cloudflare Workers).
  • Geographically routed DNS (Anycast).

3. Reduce origin work

  • Cache DB results (Redis).
  • Eliminate N+1 queries.
  • Avoid synchronous external calls in the request path — push to background jobs.
  • Don't compute on render what you can compute on write.

4. HTTP/2 or HTTP/3

Multiplexing, header compression, 0-RTT resumption. Free wins if your stack supports them.

5. Eliminate redirects

  • HTTP → HTTPS via HSTS preload (one redirect saved on first visit, none after).
  • www ↔ non-www: pick one canonical.
  • Trailing slash policy: pick one.

6. Compression

Brotli for text — smaller than gzip; supported by all modern browsers.

7. Persistent connections

Keep-Alive is default in HTTP/1.1; HTTP/2 multiplexes. Don't kill it inadvertently.

How to measure

  • Navigation Timing API:
js
const nav = performance.getEntriesByType("navigation")[0];
const ttfb = nav.responseStart - nav.requestStart;
  • web-vitals library:
js
import { onTTFB } from "web-vitals";
onTTFB((m) => send(m));
  • Server logs for the server-processing portion.
  • WebPageTest for waterfall view per region/device.

TTFB in the funnel

TTFB is the floor for FCP. If TTFB is 800ms, FCP can never be under 800ms. Fixing TTFB lifts every downstream paint metric.

Interview framing

"TTFB is DNS + TCP + TLS + server processing + first-byte transit. Target < 200ms cached, < 600ms uncached. The biggest single lever is a CDN with aggressive edge caching — static assets immutable + hashed, HTML cacheable where possible with ISR or stale-while-revalidate for dynamic pages. Beyond caching: get origin closer (multi-region, edge runtime), reduce origin work (cache DB results, eliminate N+1, push non-critical work off the request path), use HTTP/2 or 3 for multiplexing and 0-RTT resumption, and eliminate redirects. Measure with the Navigation Timing API and the web-vitals library at p75. TTFB is the floor for FCP, so fixing it lifts every downstream paint metric."

Follow-up questions

  • Why is TTFB the floor for FCP?
  • How does HTTP/2 reduce TTFB on warm connections?
  • What's stale-while-revalidate and when is it appropriate?
  • How do you handle TTFB for authenticated, personalized pages?

Common mistakes

  • Optimizing FCP/LCP without first fixing TTFB.
  • Computing on render what could be computed on write.
  • Long redirect chains (especially HTTP→HTTPS→www→canonical).
  • Synchronous third-party API calls in the request path.

Performance considerations

  • Edge caching is the dominant lever. Origin work and redirects are next. HTTP/2/3 + Brotli are free wins.

Edge cases

  • Cold-start TTFB on serverless — first request after idle.
  • Personalized pages that can't cache at the CDN.
  • API workloads vs HTML — different caching strategies.

Real-world examples

  • Vercel + Next.js ISR; Cloudflare Workers; AWS CloudFront + Lambda@Edge.

Senior engineer discussion

Seniors fix TTFB first when paint metrics are bad, cache aggressively, get origin closer to users, and reduce origin work — they don't waste time inlining CSS while TTFB is 1.5s.

Related questions