Time to First Byte (TTFB)

Time to First Byte (TTFB)

Appears in: Metrics

Time to First Byte (TTFB) is a foundational metric for measuring connection setup time and web server responsiveness in both the lab and the field. It helps identify when a web server is too slow to respond to requests. In the case of navigation requests—that is, requests for an HTML document—it precedes every other meaningful loading performance metric.

What is TTFB? #

TTFB is a metric that measures the time between the request for a resource and when the first byte of a response begins to arrive.

A diagram of network request timings. The phases from left to right are Redirect (which overlaps with Prompt for Unload), Cache, DNS, TCP, Request, Response, Processing, and Load. The associated timings are redirectStart and redirectEnd (which overlap with the Prompt for Unload's unloadEventStart and unloadEventEnd), fetchStart, domainLookupStart, domainLookupEnd, connectStart, secureConnectionStart, connectEnd, requestStart, responseStart, responseEnd, domInteractive, domContentLoadedEventStart, domContentLoadedEventEnd, domComplete, loadEventStart, and loadEventEnd.
A diagram of network request phases and their associated timings. TTFB measures the elapsed time between startTime and responseStart.

TTFB is the sum of the following request phases:

  • Redirect time
  • Service worker startup time (if applicable)
  • DNS lookup
  • Connection and TLS negotiation
  • Request, up until the point at which the first byte of the response has arrived

Reducing latency in connection setup time and on the backend will contribute to a lower TTFB.

What is a good TTFB score? #

Due to the wide variation of network and application backend stacks, an arbitrary number can't be placed on what consists of a "good" TTFB score. Because TTFB precedes user-centric metrics such as First Contentful Paint (FCP) and Largest Contentful Paint (LCP), it's recommended that your server responds to navigation requests quickly enough so that the 75th percentile of users experience an FCP within the "good" threshold.

How to measure TTFB #

TTFB can be measured in the lab or in the field in the following ways.

Field tools #

Lab tools #

Measure TTFB in JavaScript #

You can measure the TTFB of navigation requests in the browser with the Navigation Timing API. The following example shows how to create a PerformanceObserver that listens for a navigation entry and logs it to the console:

new PerformanceObserver((entryList) => {
const [pageNav] = entryList.getEntriesByType('navigation');

console.log(`TTFB: ${pageNav.responseStart}`);
}).observe({
type: 'navigation',
buffered: true
});

Caution: Not all browsers support PerformanceObserver or its buffered flag. To get the largest possible browser support, consider adopting the web-vitals package, which is discussed below.

The web-vitals JavaScript library can also measure TTFB in the browser with less complexity:

import {getTTFB} from 'web-vitals';

// Measure and log TTFB as soon as it's available.
getTTFB(console.log);

Measuring resource requests #

TTFB applies to all requests, not just navigation requests. In particular, resources hosted on cross-origin servers can introduce latency due to the need to set up connections to those servers. To measure TTFB for resources in the field, use the Resource Timing API within a PerformanceObserver:

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-Origin-Allow header set.
if (entry.responseStart > 0) {
console.log(`TTFB: ${entry.responseStart}`, entry.name);
}
}
}).observe({
type: 'resource',
buffered: true
});

The above code snippet is similar to the one used to measure the TTFB for a navigation request, except instead of querying for 'navigation' entries, you query for 'resource' entries instead. It also accounts for the fact that some resources loaded from the primary origin may return a value of 0, since the connection is already open, or a resource is instantaneously retrieved from a cache.

Gotchas!

TTFB for cross-origin requests will not be measurable in the field if cross-origin servers fail to set a Timing-Allow-Origin header.

How to improve TTFB #

Improving TTFB is largely dependent on your hosting provider and backend application stack. High TTFB values could be due to one or more of the following problems:

  • Hosting services with inadequate infrastructure to handle high traffic loads
  • Web servers with insufficient memory that can lead to thrashing
  • Unoptimized database tables
  • Suboptimal database server configuration

Minimizing TTFB is often done by choosing a suitable hosting provider with infrastructure to ensure high uptime and responsiveness. This—in combination with a CDN—can help.

Use the Server-Timing API to gather additional field data on the performance of application backend processes. This can help identify opportunities for improvements that might otherwise go unnoticed.

Other opportunities to improve high TTFB times and related perceptual delays include:

Last updated: Improve article