debugjavascriptMajor
TTFB optimization: reducing server response time
Viewed 0 times
TTFBtime to first byteCDN edge cachingRedis cachestreaming HTMLserver response time
Problem
Time to First Byte (TTFB) is above 600ms. The server takes too long to respond before the browser can begin rendering anything. This delays all subsequent resource loading.
Solution
Attack TTFB from multiple angles: CDN edge caching, server-side caching, and database query optimization.
// 1. Serve from CDN edge — target < 20ms TTFB for cached responses
// Configure CDN (Cloudflare, Fastly) to cache HTML at edge
// Cache-Control: public, s-maxage=3600 for SSR pages
// 2. Server-side caching with Redis
const cached = await redis.get(
if (cached) {
res.setHeader('X-Cache', 'HIT');
return res.send(cached);
}
const html = await renderPage(req);
await redis.setex(
res.send(html);
// 3. Stream the response — send HTML head early
res.write('<!DOCTYPE html><html><head>...');
await fetchData();
res.write(
res.end();
// 1. Serve from CDN edge — target < 20ms TTFB for cached responses
// Configure CDN (Cloudflare, Fastly) to cache HTML at edge
// Cache-Control: public, s-maxage=3600 for SSR pages
// 2. Server-side caching with Redis
const cached = await redis.get(
page:${req.path});if (cached) {
res.setHeader('X-Cache', 'HIT');
return res.send(cached);
}
const html = await renderPage(req);
await redis.setex(
page:${req.path}, 3600, html);res.send(html);
// 3. Stream the response — send HTML head early
res.write('<!DOCTYPE html><html><head>...');
await fetchData();
res.write(
<body>${content}</body></html>);res.end();
Why
TTFB is the sum of: DNS lookup + TCP handshake + TLS negotiation + server processing time. CDN edge caching eliminates server processing for cached responses. Streaming flushes the head early so the browser can preload scripts while the body is still being generated.
Gotchas
- Good TTFB target: under 200ms for server-processed pages, under 20ms for CDN-cached responses
- Streaming HTML breaks with some CDN cache configurations — test that the CDN does not buffer the stream
- Database N+1 queries are a common cause of high server-side processing time — check slow query logs
- TTFB from Lighthouse uses a simulated connection — compare with field data (CrUX) for real-world numbers
Code Snippets
Measure TTFB via PerformanceNavigationTiming
// Measure TTFB from the browser
const [navEntry] = performance.getEntriesByType('navigation');
const ttfb = navEntry.responseStart - navEntry.requestStart;
console.log('TTFB:', ttfb.toFixed(0) + 'ms');Context
When Lighthouse or field data shows TTFB above 600ms and slowing down all Core Web Vitals
Revisions (0)
No revisions yet.