Defining TTFB
Time to First Byte (TTFB) measures the duration from the start of a page navigation until the first byte of the response begins to arrive. It represents the sum of several request phases:
- Redirect time
- Service worker startup time (if applicable)
- DNS lookup
- Connection and TLS negotiation
- Request time up to the arrival of the first response byte
Lowering TTFB generally requires reducing latency in connection setup and improving backend response times.
TTFB and Early Hints
The introduction of 103 Early Hints has raised questions about what counts as the "first byte." A 103 Early Hints response does count as the first byte for TTFB purposes. The finalResponseHeadersStart timing entry complements responseStart by measuring the start of the final document response (typically an HTTP 200).
Early Hints is one example of a broader pattern: some servers flush parts of the response—such as HTTP headers or the <head> element—before the full body is ready. These early responses all land under responseStart and therefore affect TTFB. Sending data early is valuable when the complete response will take time, but it complicates cross-platform TTFB comparisons because measurement depends on the features and technologies in use. The key is understanding what your measurement tool captures and how the platform being tested influences it.
Interpreting TTFB scores
Since TTFB precedes user-centric metrics like First Contentful Paint (FCP) and Largest Contentful Paint (LCP), servers should respond to navigation requests quickly enough that the 75th percentile of users achieve an FCP within the "good" threshold. As a general guideline, most sites should aim for a TTFB of 0.8 seconds or less.
Measuring TTFB
TTFB can be assessed in both lab and field settings using various tools.
Field measurement
Lab measurement
- Chrome DevTools network panel
- WebPageTest
JavaScript measurement for navigation requests
For navigation requests, the Navigation Timing API provides the necessary data. The example below creates a PerformanceObserver that logs navigation entries:
new PerformanceObserver((entryList) => {
const [pageNav] = entryList.getEntriesByType('navigation');
console.log(`TTFB: ${pageNav.responseStart}`);
}).observe({
type: 'navigation',
buffered: true
});
The web-vitals library offers a more concise approach:
import {onTTFB} from 'web-vitals';
// Measure and log TTFB as soon as it's available.
onTTFB(console.log);
Measuring resource request TTFB
TTFB applies to all requests, not only navigations. Cross-origin resources are particularly relevant since establishing connections to additional servers introduces latency. The Resource Timing API within a PerformanceObserver handles this measurement:
new PerformanceObserver((entryList) => {
const entries = entryList.getEntries();
for (const entry of entries) {
// Some resources may have a responseStart value of 0, due
// to the resource being cached, or a cross-origin resource
// being served without a Timing-Allow-Origin header set.
if (entry.responseStart > 0) {
console.log(`TTFB: ${entry.responseStart}`, entry.name);
}
}
}).observe({
type: 'resource',
buffered: true
});
This snippet resembles the navigation example but queries for 'resource' entries instead of 'navigation'. It also accommodates same-origin resources that may report 0 because the connection is already established or the resource is served from cache.
Improving TTFB
For strategies to reduce your site's TTFB, consult the optimizing TTFB guide.



