惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 【当耐特】
WordPress大学
WordPress大学
T
The Exploit Database - CXSecurity.com
博客园_首页
MyScale Blog
MyScale Blog
The Cloudflare Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
美团技术团队
Stack Overflow Blog
Stack Overflow Blog
博客园 - 聂微东
M
MIT News - Artificial intelligence
Microsoft Security Blog
Microsoft Security Blog
F
Full Disclosure
V
V2EX
博客园 - Franky
博客园 - 三生石上(FineUI控件)
Hugging Face - Blog
Hugging Face - Blog
P
Proofpoint News Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
SecWiki News
SecWiki News
N
Netflix TechBlog - Medium
S
Secure Thoughts
酷 壳 – CoolShell
酷 壳 – CoolShell
Hacker News: Ask HN
Hacker News: Ask HN
爱范儿
爱范儿
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Webroot Blog
Webroot Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Martin Fowler
Martin Fowler
PCI Perspectives
PCI Perspectives
S
Security @ Cisco Blogs
Recorded Future
Recorded Future
Help Net Security
Help Net Security
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
AI
AI
Microsoft Azure Blog
Microsoft Azure Blog
K
Kaspersky official blog
G
GRAHAM CLULEY
H
Hackread – Cybersecurity News, Data Breaches, AI and More
C
CERT Recently Published Vulnerability Notes
U
Unit 42
T
Tor Project blog
Cloudbric
Cloudbric
Hacker News - Newest:
Hacker News - Newest: "LLM"
MongoDB | Blog
MongoDB | Blog
GbyAI
GbyAI
T
The Blog of Author Tim Ferriss
Security Latest
Security Latest
N
News and Events Feed by Topic
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO

web.dev: Articles

Rendering on the Web  |  Articles  |  web.dev Why is CrUX data different from my RUM data?  |  Articles  |  web.dev Responsive and fluid typography with Baseline CSS features  |  Articles  |  web.dev Ten modern layouts in one line of CSS  |  Articles  |  web.dev Color themes with Baseline CSS features  |  Articles  |  web.dev Preload responsive images  |  Articles  |  web.dev Optimize Time to First Byte  |  Articles  |  web.dev <dialog> and popover: Baseline layered UI patterns  |  Articles  |  web.dev How to implement an image gallery using Baseline features  |  Articles  |  web.dev
Time to First Byte (TTFB)  |  Articles  |  web.dev
2025-11-28 · via web.dev: Articles
Skip to main content

Time to First Byte (TTFB)

Barry Pollard

Jeremy Wagner

Published: October 26, 2021, Last updated: November 18, 2025

What is TTFB?

TTFB is a metric that measures the time between starting navigating to a page and when the first byte of a response begins to arrive.

A visualization of network request timings. The timings from left to right are Redirect, Service Worker Init, Service Worker Fetch event, HTTP Cache, DNS, TCP, Request, Early Hints (103), Response (which overlaps with Prompt for Unload), Processing, and Load. The associated timings are redirectStart and redirectEnd, fetchStart, domainLookupStart, domainLookupEnd, connectStart, secureConnectionStart, connectEnd, requestStart, interimResponseStart, responseStart, unloadEventStart, unloadEventEnd, 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 can lower your TTFB.

TTFB and Early Hints

The introduction of 103 Early Hints causes some confusion as to what "first byte" TTFB measures. The 103 Early Hints counts as the "first bytes". The finalResponseHeadersStart is an additional timing entry to responseStart that measures the the start of the final document response (typically an HTTP 200 response) to be measured.

Early Hints is just a newer example of responding early. Some servers allow early flushing of the document response to happen before the main body is available—either with just the HTTP headers, or with the <head> element, both of which could be considered similar in effect to Early Hints. This is another reason why all these are measured as responseStart and so TTFB.

There is real value in sending back data early if the full response is going to take some more time. However, this does make it difficult to compare TTFB across different platforms or technologies depending on what features they use, and how that impacts the TTFB measurement being used. What is most important is to understand what the measure the tool you are using measures and how that is affected by the platform being measured.

What is 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. As a rough guide, most sites should strive to have a TTFB of 0.8 seconds or less.

Good TTFB values are 0.8 seconds or less, poor values are greater than 1.8 seconds, and anything in between needs improvement
Good TTFB values are 0.8 seconds or less, and poor values are greater than 1.8 seconds.

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
});

The web-vitals JavaScript library can also measure TTFB in the browser more succinctly:

import {onTTFB} from 'web-vitals';

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

Measure resource requests

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

The previous 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.

How to improve TTFB

For guidance on improving your site's TTFB, see our in-depth guide to optimizing TTFB.

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025-11-28 UTC.

[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-11-28 UTC."],[],[]]