CINXE.COM
Optimize Time to First Byte | Articles | web.dev
<!doctype html> <html lang="en" dir="ltr"> <head> <meta name="google-signin-client-id" content="157101835696-ooapojlodmuabs2do2vuhhnf90bccmoi.apps.googleusercontent.com"> <meta name="google-signin-scope" content="profile email https://www.googleapis.com/auth/developerprofiles https://www.googleapis.com/auth/developerprofiles.award"> <meta property="og:site_name" content="web.dev"> <meta property="og:type" content="website"><meta name="theme-color" content="#3740ff"><meta charset="utf-8"> <meta content="IE=Edge" http-equiv="X-UA-Compatible"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="manifest" href="/_pwa/web/manifest.json" crossorigin="use-credentials"> <link rel="preconnect" href="//www.gstatic.com" crossorigin> <link rel="preconnect" href="//fonts.gstatic.com" crossorigin> <link rel="preconnect" href="//fonts.googleapis.com" crossorigin> <link rel="preconnect" href="//apis.google.com" crossorigin> <link rel="preconnect" href="//www.google-analytics.com" crossorigin><link rel="stylesheet" href="//fonts.googleapis.com/css?family=Google+Sans:400,500|Roboto:400,400italic,500,500italic,700,700italic|Roboto+Mono:400,500,700&display=swap"> <link rel="stylesheet" href="//fonts.googleapis.com/css2?family=Material+Icons&family=Material+Symbols+Outlined&display=block"><link rel="stylesheet" href="https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/web/css/app.css"> <link rel="stylesheet" href="https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/web/css/dark-theme.css" disabled> <link rel="shortcut icon" href="https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/web/images/favicon.png"> <link rel="apple-touch-icon" href="https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/web/images/touchicon-180.png"><link rel="canonical" href="https://web.dev/articles/optimize-ttfb"><link rel="search" type="application/opensearchdescription+xml" title="web.dev" href="https://web.dev/s/opensearch.xml"> <link rel="alternate" hreflang="en" href="https://web.dev/articles/optimize-ttfb" /><link rel="alternate" hreflang="x-default" href="https://web.dev/articles/optimize-ttfb" /><link rel="alternate" hreflang="ar" href="https://web.dev/articles/optimize-ttfb?hl=ar" /><link rel="alternate" hreflang="bn" href="https://web.dev/articles/optimize-ttfb?hl=bn" /><link rel="alternate" hreflang="zh-Hans" href="https://web.dev/articles/optimize-ttfb?hl=zh-cn" /><link rel="alternate" hreflang="zh-Hant" href="https://web.dev/articles/optimize-ttfb?hl=zh-tw" /><link rel="alternate" hreflang="fa" href="https://web.dev/articles/optimize-ttfb?hl=fa" /><link rel="alternate" hreflang="fr" href="https://web.dev/articles/optimize-ttfb?hl=fr" /><link rel="alternate" hreflang="de" href="https://web.dev/articles/optimize-ttfb?hl=de" /><link rel="alternate" hreflang="he" href="https://web.dev/articles/optimize-ttfb?hl=he" /><link rel="alternate" hreflang="hi" href="https://web.dev/articles/optimize-ttfb?hl=hi" /><link rel="alternate" hreflang="id" href="https://web.dev/articles/optimize-ttfb?hl=id" /><link rel="alternate" hreflang="it" href="https://web.dev/articles/optimize-ttfb?hl=it" /><link rel="alternate" hreflang="ja" href="https://web.dev/articles/optimize-ttfb?hl=ja" /><link rel="alternate" hreflang="ko" href="https://web.dev/articles/optimize-ttfb?hl=ko" /><link rel="alternate" hreflang="pl" href="https://web.dev/articles/optimize-ttfb?hl=pl" /><link rel="alternate" hreflang="pt-BR" href="https://web.dev/articles/optimize-ttfb?hl=pt-br" /><link rel="alternate" hreflang="ru" href="https://web.dev/articles/optimize-ttfb?hl=ru" /><link rel="alternate" hreflang="es-419" href="https://web.dev/articles/optimize-ttfb?hl=es-419" /><link rel="alternate" hreflang="th" href="https://web.dev/articles/optimize-ttfb?hl=th" /><link rel="alternate" hreflang="tr" href="https://web.dev/articles/optimize-ttfb?hl=tr" /><link rel="alternate" hreflang="vi" href="https://web.dev/articles/optimize-ttfb?hl=vi" /><link rel="alternate" hreflang="en-cn" href="https://web.developers.google.cn/articles/optimize-ttfb" /><link rel="alternate" hreflang="x-default" href="https://web.developers.google.cn/articles/optimize-ttfb" /><link rel="alternate" hreflang="ar-cn" href="https://web.developers.google.cn/articles/optimize-ttfb?hl=ar" /><link rel="alternate" hreflang="bn-cn" href="https://web.developers.google.cn/articles/optimize-ttfb?hl=bn" /><link rel="alternate" hreflang="zh-Hans-cn" href="https://web.developers.google.cn/articles/optimize-ttfb?hl=zh-cn" /><link rel="alternate" hreflang="zh-Hant-cn" href="https://web.developers.google.cn/articles/optimize-ttfb?hl=zh-tw" /><link rel="alternate" hreflang="fa-cn" href="https://web.developers.google.cn/articles/optimize-ttfb?hl=fa" /><link rel="alternate" hreflang="fr-cn" href="https://web.developers.google.cn/articles/optimize-ttfb?hl=fr" /><link rel="alternate" hreflang="de-cn" href="https://web.developers.google.cn/articles/optimize-ttfb?hl=de" /><link rel="alternate" hreflang="he-cn" href="https://web.developers.google.cn/articles/optimize-ttfb?hl=he" /><link rel="alternate" hreflang="hi-cn" href="https://web.developers.google.cn/articles/optimize-ttfb?hl=hi" /><link rel="alternate" hreflang="id-cn" href="https://web.developers.google.cn/articles/optimize-ttfb?hl=id" /><link rel="alternate" hreflang="it-cn" href="https://web.developers.google.cn/articles/optimize-ttfb?hl=it" /><link rel="alternate" hreflang="ja-cn" href="https://web.developers.google.cn/articles/optimize-ttfb?hl=ja" /><link rel="alternate" hreflang="ko-cn" href="https://web.developers.google.cn/articles/optimize-ttfb?hl=ko" /><link rel="alternate" hreflang="pl-cn" href="https://web.developers.google.cn/articles/optimize-ttfb?hl=pl" /><link rel="alternate" hreflang="pt-BR-cn" href="https://web.developers.google.cn/articles/optimize-ttfb?hl=pt-br" /><link rel="alternate" hreflang="ru-cn" href="https://web.developers.google.cn/articles/optimize-ttfb?hl=ru" /><link rel="alternate" hreflang="es-419-cn" href="https://web.developers.google.cn/articles/optimize-ttfb?hl=es-419" /><link rel="alternate" hreflang="th-cn" href="https://web.developers.google.cn/articles/optimize-ttfb?hl=th" /><link rel="alternate" hreflang="tr-cn" href="https://web.developers.google.cn/articles/optimize-ttfb?hl=tr" /><link rel="alternate" hreflang="vi-cn" href="https://web.developers.google.cn/articles/optimize-ttfb?hl=vi" /><title>Optimize Time to First Byte | Articles | web.dev</title> <meta property="og:title" content="Optimize Time to First Byte | Articles | web.dev"><meta name="description" content="Learn how to optimize for the Time to First Byte metric."> <meta property="og:description" content="Learn how to optimize for the Time to First Byte metric."><meta property="og:url" content="https://web.dev/articles/optimize-ttfb"><meta property="og:image" content="https://web.dev/static/articles/optimize-ttfb/image/thumbnail.jpg"> <meta property="og:image:width" content="1200"> <meta property="og:image:height" content="675"><meta property="og:locale" content="en"><meta name="twitter:card" content="summary_large_image"><script type="application/ld+json"> { "@context": "https://schema.org", "@type": "Article", "dateModified": "2024-01-10", "headline": "Optimize Time to First Byte" } </script><script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [{ "@type": "ListItem", "position": 1, "name": "Articles", "item": "https://web.dev/articles" },{ "@type": "ListItem", "position": 2, "name": "Optimize Time to First Byte", "item": "https://web.dev/articles/optimize-ttfb" }] } </script> <link rel="stylesheet" href="/extras.css"></head> <body class="" template="page" theme="web-theme" type="article" appearance layout="docs" display-toc pending> <devsite-progress type="indeterminate" id="app-progress"></devsite-progress> <a href="#main-content" class="skip-link button"> Skip to main content </a> <section class="devsite-wrapper"> <devsite-cookie-notification-bar></devsite-cookie-notification-bar><devsite-header role="banner"> <div class="devsite-header--inner nocontent"> <div class="devsite-top-logo-row-wrapper-wrapper"> <div class="devsite-top-logo-row-wrapper"> <div class="devsite-top-logo-row"> <button type="button" id="devsite-hamburger-menu" class="devsite-header-icon-button button-flat material-icons gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Navigation menu button" visually-hidden aria-label="Open menu"> </button> <div class="devsite-product-name-wrapper"> <a href="/" class="devsite-site-logo-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Site logo" track-type="globalNav" track-name="webDev" track-metadata-position="nav" track-metadata-eventDetail="nav"> <picture> <source srcset="https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/web/images/lockup-dark-theme.svg" media="(prefers-color-scheme: dark)" class="devsite-dark-theme" alt="web.dev"> <img src="https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/web/images/lockup.svg" class="devsite-site-logo" alt="web.dev"> </picture> </a> <span class="devsite-product-name"> <ul class="devsite-breadcrumb-list" > <li class="devsite-breadcrumb-item "> </li> </ul> </span> </div> <div class="devsite-top-logo-row-middle"> <div class="devsite-header-upper-tabs"> <devsite-tabs class="upper-tabs"> <nav class="devsite-tabs-wrapper" aria-label="Upper tabs"> <tab class="devsite-dropdown devsite-dropdown-full "> <button class="devsite-tabs-content devsite-tabs-dropdown-only gc-analytics-event devsite-icon devsite-icon-arrow-drop-down" track-type="nav" track-metadata-position="nav - resources" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Resources" track-name="resources" > Resources </button> <div class="devsite-tabs-dropdown" role="menu" aria-label="submenu" hidden> <div class="devsite-tabs-dropdown-content"> <div class="devsite-tabs-dropdown-column "> <ul class="devsite-tabs-dropdown-section build-icon web-dev-subnav"> <li class="devsite-nav-title" role="heading" tooltip>Web Platform</li> <li class="devsite-nav-description">Dive into the web platform, at your pace. </li> <li class="devsite-nav-item"> <a href="https://web.dev/html" track-type="nav" track-metadata-eventdetail="https://web.dev/html" track-metadata-position="nav - resources" track-metadata-module="tertiary nav" track-metadata-module_headline="web platform" tooltip > <div class="devsite-nav-item-title"> HTML </div> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev/css" track-type="nav" track-metadata-eventdetail="https://web.dev/css" track-metadata-position="nav - resources" track-metadata-module="tertiary nav" track-metadata-module_headline="web platform" tooltip > <div class="devsite-nav-item-title"> CSS </div> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev/javascript" track-type="nav" track-metadata-eventdetail="https://web.dev/javascript" track-metadata-position="nav - resources" track-metadata-module="tertiary nav" track-metadata-module_headline="web platform" tooltip > <div class="devsite-nav-item-title"> JavaScript </div> </a> </li> </ul> </div> <div class="devsite-tabs-dropdown-column "> <ul class="devsite-tabs-dropdown-section build-icon web-dev-subnav"> <li class="devsite-nav-title" role="heading" tooltip>User experience</li> <li class="devsite-nav-description">Learn how to build better user experiences. </li> <li class="devsite-nav-item"> <a href="https://web.dev/performance" track-type="nav" track-metadata-eventdetail="https://web.dev/performance" track-metadata-position="nav - resources" track-metadata-module="tertiary nav" track-metadata-module_headline="user experience" tooltip > <div class="devsite-nav-item-title"> Performance </div> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev/accessibility" track-type="nav" track-metadata-eventdetail="https://web.dev/accessibility" track-metadata-position="nav - resources" track-metadata-module="tertiary nav" track-metadata-module_headline="user experience" tooltip > <div class="devsite-nav-item-title"> Accessibility </div> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev/identity" track-type="nav" track-metadata-eventdetail="https://web.dev/identity" track-metadata-position="nav - resources" track-metadata-module="tertiary nav" track-metadata-module_headline="user experience" tooltip > <div class="devsite-nav-item-title"> Identity </div> </a> </li> </ul> </div> <div class="devsite-tabs-dropdown-column "> <ul class="devsite-tabs-dropdown-section productivity-icon web-dev-subnav"> <li class="devsite-nav-title" role="heading" tooltip>Learn</li> <li class="devsite-nav-description">Get up to speed on web development.</li> <li class="devsite-nav-item"> <a href="https://web.dev/learn/html" track-type="nav" track-metadata-eventdetail="https://web.dev/learn/html" track-metadata-position="nav - resources" track-metadata-module="tertiary nav" track-metadata-module_headline="learn" tooltip > <div class="devsite-nav-item-title"> Learn HTML </div> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev/learn/css" track-type="nav" track-metadata-eventdetail="https://web.dev/learn/css" track-metadata-position="nav - resources" track-metadata-module="tertiary nav" track-metadata-module_headline="learn" tooltip > <div class="devsite-nav-item-title"> Learn CSS </div> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev/learn/javascript" track-type="nav" track-metadata-eventdetail="https://web.dev/learn/javascript" track-metadata-position="nav - resources" track-metadata-module="tertiary nav" track-metadata-module_headline="learn" tooltip > <div class="devsite-nav-item-title"> Learn JavaScript </div> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev/learn/performance" track-type="nav" track-metadata-eventdetail="https://web.dev/learn/performance" track-metadata-position="nav - resources" track-metadata-module="tertiary nav" track-metadata-module_headline="learn" tooltip > <div class="devsite-nav-item-title"> Learn Performance </div> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev/learn/accessibility" track-type="nav" track-metadata-eventdetail="https://web.dev/learn/accessibility" track-metadata-position="nav - resources" track-metadata-module="tertiary nav" track-metadata-module_headline="learn" tooltip > <div class="devsite-nav-item-title"> Learn Accessibility </div> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev/learn" track-type="nav" track-metadata-eventdetail="https://web.dev/learn" track-metadata-position="nav - resources" track-metadata-module="tertiary nav" track-metadata-module_headline="learn" tooltip > <div class="devsite-nav-item-title"> More courses </div> </a> </li> </ul> </div> <div class="devsite-tabs-dropdown-column "> <ul class="devsite-tabs-dropdown-section experience-icon web-dev-subnav"> <li class="devsite-nav-title" role="heading" tooltip>Additional resources</li> <li class="devsite-nav-description">Explore content collections, patterns, and more.</li> <li class="devsite-nav-item"> <a href="https://web.dev/explore/ai" track-type="nav" track-metadata-eventdetail="https://web.dev/explore/ai" track-metadata-position="nav - resources" track-metadata-module="tertiary nav" track-metadata-module_headline="additional resources" tooltip > <div class="devsite-nav-item-title"> AI and the web </div> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev/explore" track-type="nav" track-metadata-eventdetail="https://web.dev/explore" track-metadata-position="nav - resources" track-metadata-module="tertiary nav" track-metadata-module_headline="additional resources" tooltip > <div class="devsite-nav-item-title"> Explore </div> </a> </li> <li class="devsite-nav-item"> <a href="https://pagespeed.web.dev/" track-type="nav" track-metadata-eventdetail="https://pagespeed.web.dev/" track-metadata-position="nav - resources" track-metadata-module="tertiary nav" track-metadata-module_headline="additional resources" tooltip > <div class="devsite-nav-item-title"> PageSpeed Insights </div> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev/patterns" track-type="nav" track-metadata-eventdetail="https://web.dev/patterns" track-metadata-position="nav - resources" track-metadata-module="tertiary nav" track-metadata-module_headline="additional resources" tooltip > <div class="devsite-nav-item-title"> Patterns </div> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev/shows" track-type="nav" track-metadata-eventdetail="https://web.dev/shows" track-metadata-position="nav - resources" track-metadata-module="tertiary nav" track-metadata-module_headline="additional resources" tooltip > <div class="devsite-nav-item-title"> Podcasts & shows </div> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev/newsletter" track-type="nav" track-metadata-eventdetail="https://web.dev/newsletter" track-metadata-position="nav - resources" track-metadata-module="tertiary nav" track-metadata-module_headline="additional resources" tooltip > <div class="devsite-nav-item-title"> Developer Newsletter </div> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev/about" track-type="nav" track-metadata-eventdetail="https://web.dev/about" track-metadata-position="nav - resources" track-metadata-module="tertiary nav" track-metadata-module_headline="additional resources" tooltip > <div class="devsite-nav-item-title"> About web.dev </div> </a> </li> </ul> </div> </div> </div> </tab> <tab > <a href="https://web.dev/baseline" class="devsite-tabs-content gc-analytics-event " track-metadata-eventdetail="https://web.dev/baseline" track-type="nav" track-metadata-position="nav - baseline" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Baseline" track-name="baseline" > Baseline </a> </tab> <tab > <a href="https://web.dev/blog" class="devsite-tabs-content gc-analytics-event " track-metadata-eventdetail="https://web.dev/blog" track-type="nav" track-metadata-position="nav - blog" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Blog" track-name="blog" > Blog </a> </tab> <tab > <a href="https://web.dev/case-studies" class="devsite-tabs-content gc-analytics-event " track-metadata-eventdetail="https://web.dev/case-studies" track-type="nav" track-metadata-position="nav - case studies" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Case Studies" track-name="case studies" > Case Studies </a> </tab> </nav> </devsite-tabs> </div> <devsite-search enable-signin enable-search enable-suggestions enable-query-completion project-name="Articles" tenant-name="web.dev" > <form class="devsite-search-form" action="https://web.dev/s/results" method="GET"> <div class="devsite-search-container"> <button type="button" search-open class="devsite-search-button devsite-header-icon-button button-flat material-icons" aria-label="Open search"></button> <div class="devsite-searchbox"> <input aria-activedescendant="" aria-autocomplete="list" aria-label="Search" aria-expanded="false" aria-haspopup="listbox" autocomplete="off" class="devsite-search-field devsite-search-query" name="q" placeholder="Search" role="combobox" type="text" value="" > <div class="devsite-search-image material-icons" aria-hidden="true"> </div> <div class="devsite-search-shortcut-icon-container" aria-hidden="true"> <kbd class="devsite-search-shortcut-icon">/</kbd> </div> </div> </div> </form> <button type="button" search-close class="devsite-search-button devsite-header-icon-button button-flat material-icons" aria-label="Close search"></button> </devsite-search> </div> <devsite-appearance-selector></devsite-appearance-selector> <devsite-language-selector> <ul role="presentation"> <li role="presentation"> <a role="menuitem" lang="en" >English</a> </li> <li role="presentation"> <a role="menuitem" lang="de" >Deutsch</a> </li> <li role="presentation"> <a role="menuitem" lang="es_419" >Español – América Latina</a> </li> <li role="presentation"> <a role="menuitem" lang="fr" >Français</a> </li> <li role="presentation"> <a role="menuitem" lang="id" >Indonesia</a> </li> <li role="presentation"> <a role="menuitem" lang="it" >Italiano</a> </li> <li role="presentation"> <a role="menuitem" lang="pl" >Polski</a> </li> <li role="presentation"> <a role="menuitem" lang="pt_br" >Português – Brasil</a> </li> <li role="presentation"> <a role="menuitem" lang="vi" >Tiếng Việt</a> </li> <li role="presentation"> <a role="menuitem" lang="tr" >Türkçe</a> </li> <li role="presentation"> <a role="menuitem" lang="ru" >Русский</a> </li> <li role="presentation"> <a role="menuitem" lang="he" >עברית</a> </li> <li role="presentation"> <a role="menuitem" lang="ar" >العربيّة</a> </li> <li role="presentation"> <a role="menuitem" lang="fa" >فارسی</a> </li> <li role="presentation"> <a role="menuitem" lang="hi" >हिंदी</a> </li> <li role="presentation"> <a role="menuitem" lang="bn" >বাংলা</a> </li> <li role="presentation"> <a role="menuitem" lang="th" >ภาษาไทย</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_cn" >中文 – 简体</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_tw" >中文 – 繁體</a> </li> <li role="presentation"> <a role="menuitem" lang="ja" >日本語</a> </li> <li role="presentation"> <a role="menuitem" lang="ko" >한국어</a> </li> </ul> </devsite-language-selector> <devsite-user enable-profiles id="devsite-user"> <span class="button devsite-top-button" aria-hidden="true" visually-hidden>Sign in</span> </devsite-user> </div> </div> </div> <div class="devsite-collapsible-section devsite-header-no-lower-tabs "> <div class="devsite-header-background"> </div> </div> </div> </devsite-header> <devsite-book-nav scrollbars hidden> <div class="devsite-book-nav-filter" hidden> <span class="filter-list-icon material-icons" aria-hidden="true"></span> <input type="text" placeholder="Filter" aria-label="Type to filter" role="searchbox"> <span class="filter-clear-button hidden" data-title="Clear filter" aria-label="Clear filter" role="button" tabindex="0"></span> </div> <nav class="devsite-book-nav devsite-nav nocontent" aria-label="Side menu"> <div class="devsite-mobile-header"> <button type="button" id="devsite-close-nav" class="devsite-header-icon-button button-flat material-icons gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Close navigation" aria-label="Close navigation"> </button> <div class="devsite-product-name-wrapper"> <a href="/" class="devsite-site-logo-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Site logo" track-type="globalNav" track-name="webDev" track-metadata-position="nav" track-metadata-eventDetail="nav"> <picture> <source srcset="https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/web/images/lockup-dark-theme.svg" media="(prefers-color-scheme: dark)" class="devsite-dark-theme" alt="web.dev"> <img src="https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/web/images/lockup.svg" class="devsite-site-logo" alt="web.dev"> </picture> </a> <span class="devsite-product-name"> <ul class="devsite-breadcrumb-list" > <li class="devsite-breadcrumb-item "> </li> </ul> </span> </div> </div> <div class="devsite-book-nav-wrapper"> <div class="devsite-mobile-nav-top"> <ul class="devsite-nav-list"> <li class="devsite-nav-item"> <span class="devsite-nav-title" tooltip data-category="Site-Wide Custom Events" data-label="Tab: Resources" track-name="resources" > <span class="devsite-nav-text" tooltip > Resources </span> </span> <ul class="devsite-nav-responsive-tabs devsite-nav-has-menu "> <li class="devsite-nav-item"> <span class="devsite-nav-title" tooltip data-category="Site-Wide Custom Events" data-label="Tab: Resources" track-name="resources" > <span class="devsite-nav-text" tooltip menu="Resources"> More </span> <span class="devsite-nav-icon material-icons" data-icon="forward" menu="Resources"> </span> </span> </li> </ul> </li> <li class="devsite-nav-item"> <a href="/baseline" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Baseline" track-name="baseline" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Baseline" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Baseline </span> </a> </li> <li class="devsite-nav-item"> <a href="/blog" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Blog" track-name="blog" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Blog" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Blog </span> </a> </li> <li class="devsite-nav-item"> <a href="/case-studies" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Case Studies" track-name="case studies" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Case Studies" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Case Studies </span> </a> </li> </ul> </div> <div class="devsite-mobile-nav-bottom"> <ul class="devsite-nav-list" menu="Resources" aria-label="Side menu" hidden> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Web Platform </span> </span> </li> <li class="devsite-nav-item"> <a href="/html" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: HTML" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > HTML </span> </a> </li> <li class="devsite-nav-item"> <a href="/css" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: CSS" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > CSS </span> </a> </li> <li class="devsite-nav-item"> <a href="/javascript" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: JavaScript" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > JavaScript </span> </a> </li> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > User experience </span> </span> </li> <li class="devsite-nav-item"> <a href="/performance" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Performance" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Performance </span> </a> </li> <li class="devsite-nav-item"> <a href="/accessibility" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Accessibility" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Accessibility </span> </a> </li> <li class="devsite-nav-item"> <a href="/identity" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Identity" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Identity </span> </a> </li> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Learn </span> </span> </li> <li class="devsite-nav-item"> <a href="/learn/html" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Learn HTML" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Learn HTML </span> </a> </li> <li class="devsite-nav-item"> <a href="/learn/css" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Learn CSS" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Learn CSS </span> </a> </li> <li class="devsite-nav-item"> <a href="/learn/javascript" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Learn JavaScript" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Learn JavaScript </span> </a> </li> <li class="devsite-nav-item"> <a href="/learn/performance" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Learn Performance" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Learn Performance </span> </a> </li> <li class="devsite-nav-item"> <a href="/learn/accessibility" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Learn Accessibility" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Learn Accessibility </span> </a> </li> <li class="devsite-nav-item"> <a href="/learn" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: More courses" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > More courses </span> </a> </li> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Additional resources </span> </span> </li> <li class="devsite-nav-item"> <a href="/explore/ai" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: AI and the web" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > AI and the web </span> </a> </li> <li class="devsite-nav-item"> <a href="/explore" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Explore" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Explore </span> </a> </li> <li class="devsite-nav-item"> <a href="https://pagespeed.web.dev/" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: PageSpeed Insights" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > PageSpeed Insights </span> </a> </li> <li class="devsite-nav-item"> <a href="/patterns" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Patterns" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Patterns </span> </a> </li> <li class="devsite-nav-item"> <a href="/shows" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Podcasts &amp; shows" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Podcasts &amp; shows </span> </a> </li> <li class="devsite-nav-item"> <a href="/newsletter" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Developer Newsletter" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Developer Newsletter </span> </a> </li> <li class="devsite-nav-item"> <a href="/about" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: About web.dev" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > About web.dev </span> </a> </li> </ul> </div> </div> </nav> </devsite-book-nav> <section id="gc-wrapper"> <main role="main" id="main-content" class="devsite-main-content" has-sidebar > <div class="devsite-sidebar"> <div class="devsite-sidebar-content"> <devsite-toc class="devsite-nav" role="navigation" aria-label="On this page" depth="2" scrollbars ></devsite-toc> <devsite-recommendations-sidebar class="nocontent devsite-nav"> </devsite-recommendations-sidebar> </div> </div> <devsite-content> <article class="devsite-article"> <div class="devsite-article-meta nocontent" role="navigation"> <ul class="devsite-breadcrumb-list" aria-label="Breadcrumb"> <li class="devsite-breadcrumb-item "> <a href="https://web.dev/" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="1" track-type="globalNav" track-name="breadcrumb" track-metadata-position="1" track-metadata-eventdetail="" > Home </a> </li> <li class="devsite-breadcrumb-item "> <div class="devsite-breadcrumb-guillemet material-icons" aria-hidden="true"></div> <a href="https://web.dev/articles" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="2" track-type="globalNav" track-name="breadcrumb" track-metadata-position="2" track-metadata-eventdetail="Articles" > Articles </a> </li> </ul> <devsite-thumb-rating position="header"> </devsite-thumb-rating> </div> <h1 class="devsite-page-title" tabindex="-1"> Optimize Time to First Byte </h1> <devsite-feature-tooltip ack-key="AckCollectionsBookmarkTooltipDismiss" analytics-category="Site-Wide Custom Events" analytics-action-show="Callout Profile displayed" analytics-action-close="Callout Profile dismissed" analytics-label="Create Collection Callout" class="devsite-page-bookmark-tooltip nocontent" dismiss-button="true" id="devsite-collections-dropdown" dismiss-button-text="Dismiss" close-button-text="Got it"> <devsite-bookmark></devsite-bookmark> <span slot="popout-heading"> Stay organized with collections </span> <span slot="popout-contents"> Save and categorize content based on your preferences. </span> </devsite-feature-tooltip> <div class="devsite-page-title-meta"><devsite-view-release-notes></devsite-view-release-notes></div> <devsite-toc class="devsite-nav" depth="2" devsite-toc-embedded > </devsite-toc> <div class="devsite-article-body clearfix "> <p>Learn how to optimize for the Time to First Byte metric.</p> <p> <div class="wd-authors" translate="no"> <div class="wd-author"> <img class="devsite-landing-row-item-icon" alt="Barry Pollard" src="https://web.dev/images/authors/tunetheweb.jpg" decoding="async" height="64" loading="lazy" width="64"> <div> <span> Barry Pollard </span> <div class="wd-author__links"> <a href="https://twitter.com/tunetheweb" aria-label="Barry Pollard on X" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 300 271"> <title>X</title> <path fill="currentColor" d="m236 0h46l-101 115 118 156h-92.6l-72.5-94.8-83 94.8h-46l107-123-113-148h94.9l65.5 86.6zm-16.1 244h25.5l-165-218h-27.4z"></path> </svg></a> <a href="https://github.com/tunetheweb" aria-label="Barry Pollard on GitHub" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 32.6 31.8"> <title>GitHub</title> <path d="M16.3 0C7.3 0 0 7.3 0 16.3c0 7.2 4.7 13.3 11.1 15.5.8.1 1.1-.4 1.1-.8v-2.8c-4.5 1-5.5-2.2-5.5-2.2-.7-1.9-1.8-2.4-1.8-2.4-1.5-1 .1-1 .1-1 1.6.1 2.5 1.7 2.5 1.7 1.5 2.5 3.8 1.8 4.7 1.4.1-1.1.6-1.8 1-2.2-3.6-.4-7.4-1.8-7.4-8.1 0-1.8.6-3.2 1.7-4.4-.1-.3-.7-2 .2-4.2 0 0 1.4-.4 4.5 1.7 1.3-.4 2.7-.5 4.1-.5 1.4 0 2.8.2 4.1.5 3.1-2.1 4.5-1.7 4.5-1.7.9 2.2.3 3.9.2 4.3 1 1.1 1.7 2.6 1.7 4.4 0 6.3-3.8 7.6-7.4 8 .6.5 1.1 1.5 1.1 3V31c0 .4.3.9 1.1.8 6.5-2.2 11.1-8.3 11.1-15.5C32.6 7.3 25.3 0 16.3 0z" fill-rule="evenodd" clip-rule="evenodd" fill="currentColor" /> </svg></a> <a href="https://webperf.social/@tunetheweb" aria-label="Barry Pollard on Mastodon" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 16 16"> <title>Mastodon</title> <path fill="currentColor" d="M 15.659 9.592 C 15.424 10.72 13.553 11.956 11.404 12.195 C 10.283 12.32 9.18 12.434 8.003 12.384 C 6.079 12.302 4.56 11.956 4.56 11.956 C 4.56 12.13 4.572 12.297 4.595 12.452 C 4.845 14.224 6.478 14.33 8.025 14.379 C 9.586 14.429 10.976 14.02 10.976 14.02 L 11.04 15.337 C 11.04 15.337 9.948 15.884 8.003 15.984 C 6.93 16.039 5.598 15.959 4.047 15.576 C 0.683 14.746 0.104 11.4 0.015 8.006 C -0.012 6.998 0.005 6.048 0.005 5.253 C 0.005 1.782 2.443 0.765 2.443 0.765 C 3.672 0.238 5.782 0.017 7.975 0 L 8.029 0 C 10.221 0.017 12.332 0.238 13.561 0.765 C 13.561 0.765 15.999 1.782 15.999 5.253 C 15.999 5.253 16.03 7.814 15.659 9.592 Z M 13.124 5.522 L 13.124 9.725 L 11.339 9.725 L 11.339 5.646 C 11.339 4.786 10.951 4.35 10.175 4.35 C 9.317 4.35 8.887 4.867 8.887 5.891 L 8.887 8.124 L 7.113 8.124 L 7.113 5.891 C 7.113 4.867 6.683 4.35 5.825 4.35 C 5.049 4.35 4.661 4.786 4.661 5.646 L 4.661 9.725 L 2.876 9.725 L 2.876 5.522 C 2.876 4.663 3.111 3.981 3.582 3.476 C 4.067 2.971 4.703 2.712 5.493 2.712 C 6.406 2.712 7.098 3.039 7.555 3.695 L 8 4.39 L 8.445 3.695 C 8.902 3.039 9.594 2.712 10.507 2.712 C 11.297 2.712 11.933 2.971 12.418 3.476 C 12.889 3.981 13.124 4.663 13.124 5.522 Z" style="stroke:none;stroke-miterlimit:10;fill-rule:evenodd;"></path> </svg></a> <a href="https://bsky.app/profile/tunetheweb.com" aria-label="Barry Pollard on Bluesky" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 568 501"> <title>Bluesky</title> <path fill="currentColor" d="M123.121 33.664C188.241 82.553 258.281 181.68 284 234.873c25.719-53.192 95.759-152.32 160.879-201.21C491.866-1.611 568-28.906 568 57.947c0 17.346-9.945 145.713-15.778 166.555-20.275 72.453-94.155 90.933-159.875 79.748C507.222 323.8 536.444 388.56 473.333 453.32c-119.86 122.992-172.272-30.859-185.702-70.281-2.462-7.227-3.614-10.608-3.631-7.733-.017-2.875-1.169.506-3.631 7.733-13.43 39.422-65.842 193.273-185.702 70.281-63.111-64.76-33.89-129.52 80.986-149.071-65.72 11.185-139.6-7.295-159.875-79.748C9.945 203.659 0 75.291 0 57.946 0-28.906 76.135-1.612 123.121 33.664Z"/> </svg> </a> <a href="https://www.tunetheweb.com" aria-label="Barry Pollard's homepage" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 30 30"> <title>Homepage</title> <circle cx="14.5" cy="14.5" r="13.5" stroke-width="2" stroke-miterlimit="10" fill="none" stroke="currentColor" /> <ellipse cx="14.5" cy="14.5" rx="6.1" ry="13.5" stroke-width="2" stroke-miterlimit="10" fill="none" stroke="currentColor" /> <path d="M1.6 9.6h25.8M1.6 19.4h25.8" stroke-width="2" stroke-miterlimit="10" fill="none" stroke="currentColor" /> </svg></a> </div> </div> </div> <div class="wd-author"> <img class="devsite-landing-row-item-icon" alt="Jeremy Wagner" src="https://web.dev/images/authors/jlwagner-v3.jpg" decoding="async" height="64" loading="lazy" width="64"> <div> <span> Jeremy Wagner </span> <div class="wd-author__links"> <a href="https://github.com/malchata" aria-label="Jeremy Wagner on GitHub" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 32.6 31.8"> <title>GitHub</title> <path d="M16.3 0C7.3 0 0 7.3 0 16.3c0 7.2 4.7 13.3 11.1 15.5.8.1 1.1-.4 1.1-.8v-2.8c-4.5 1-5.5-2.2-5.5-2.2-.7-1.9-1.8-2.4-1.8-2.4-1.5-1 .1-1 .1-1 1.6.1 2.5 1.7 2.5 1.7 1.5 2.5 3.8 1.8 4.7 1.4.1-1.1.6-1.8 1-2.2-3.6-.4-7.4-1.8-7.4-8.1 0-1.8.6-3.2 1.7-4.4-.1-.3-.7-2 .2-4.2 0 0 1.4-.4 4.5 1.7 1.3-.4 2.7-.5 4.1-.5 1.4 0 2.8.2 4.1.5 3.1-2.1 4.5-1.7 4.5-1.7.9 2.2.3 3.9.2 4.3 1 1.1 1.7 2.6 1.7 4.4 0 6.3-3.8 7.6-7.4 8 .6.5 1.1 1.5 1.1 3V31c0 .4.3.9 1.1.8 6.5-2.2 11.1-8.3 11.1-15.5C32.6 7.3 25.3 0 16.3 0z" fill-rule="evenodd" clip-rule="evenodd" fill="currentColor" /> </svg></a> <a href="https://www.linkedin.com/in/malchata" aria-label="Jeremy Wagner on LinkedIn" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 200 200"> <title>LinkedIn</title> <path d="M185.2 0H14.8C6.6 0 0 6.4 0 14.3v171.3c0 7.9 6.6 14.3 14.8 14.3h170.4c8.1 0 14.8-6.4 14.8-14.3V14.3C199.9 6.4 193.3 0 185.2 0zM60.6 167.3H30.4V77.1h30.2v90.2zM45.5 64.8h-.2c-10.1 0-16.7-6.9-16.7-15.6 0-8.8 6.7-15.6 17.1-15.6 10.3 0 16.7 6.7 16.9 15.6 0 8.6-6.5 15.6-17.1 15.6zm124 102.5h-30.2V119c0-12.1-4.4-20.4-15.3-20.4-8.4 0-13.3 5.6-15.5 11-.8 1.9-1 4.6-1 7.3v50.4H77.3s.4-81.8 0-90.3h30.2v12.8c4-6.1 11.2-14.9 27.2-14.9 19.9 0 34.8 12.9 34.8 40.6v51.8zm-62.2-77.1c0-.1.1-.2.2-.3v.3h-.2z" fill="currentColor" /> </svg></a> </div> </div> </div> </div></p> <p><a href="/articles/ttfb">Time to First Byte (TTFB)</a> is a foundational web performance metric that precedes every other meaningful user experience metric such as <a href="/articles/fcp">First Contentful Paint (FCP)</a> and <a href="/articles/lcp">Largest Contentful Paint (LCP)</a>. This means that high TTFB values add time to the metrics that follow it.</p> <p>It's recommended that your server responds to navigation requests quickly enough so that the <strong>75th percentile</strong> of users experience an FCP <a href="/articles/fcp#what_is_a_good_fcp_score">within the "good" threshold</a>. As a rough guide, most sites should strive to have a TTFB of <strong>0.8 seconds or less</strong>.</p> <figure> <picture> <source srcset="https://web.dev/static/articles/optimize-ttfb/image/good-ttfb-values.svg" media="(min-width: 640px)" width="800" height="200"> <img src="/static/articles/optimize-ttfb/image/good-ttfb-values-are-08-cf9b35258c90c.svg" alt="Good TTFB values are 0.8 seconds or less, poor values are greater than 1.8 seconds, and anything in between needs improvement" width="640" height="480"> </picture> <figcaption>Good TTFB values are 0.8 seconds or less, poor values are greater than 1.8 seconds</figcaption> </figure> <aside class="key-point"> <p> <b>Key point:</b> TTFB is not a <a href="/articles/vitals">Core Web Vitals</a> metric, so it's not absolutely necessary that sites meet the "good" TTFB threshold, provided that it doesn't impede their ability to score well on the metrics that matter. </p> <p> Websites vary in how they deliver content. A low TTFB is crucial for getting markup out to the client as soon as possible. However, if a website delivers the initial markup quickly, but that markup then requires JavaScript to populate it with meaningful content—as is the the case with Single Page Applications (SPAs)—then achieving the lowest possible TTFB is especially important so that the client-rendering of markup can occur sooner. </p> <p> Conversely, a server-rendered site that does not require as much client-side work could have a higher TTFB, but better FCP and LCP values than an entirely client-rendered experience. This is why the TTFB thresholds are a "rough guide", and will need to be weighed against how your site delivers its core content. </p> </aside> <h2 id="how_to_measure_ttfb" data-text="How to Measure TTFB" tabindex="-1">How to Measure TTFB</h2> <p>Before you can optimize TTFB, you need to observe how it affects your website's users. You should rely on <a href="/lab-and-field-data-differences#field-data">field data</a> as a primary source of observing TTFB as it affected by redirects, whereas lab-based tools are often measured using the final URL therefore missing this extra delay.</p> <p><a href="https://pagespeed.web.dev/">PageSpeed Insights</a> is one way to get both field and lab information for public websites that are available in the <a href="https://developer.chrome.com/docs/crux">Chrome User Experience Report</a>.</p> <p>TTFB for real users is shown in the top <strong>Discover what your real users are experiencing</strong> section:</p> <figure> <img src="/static/articles/optimize-ttfb/image/psi-real-user-data-updated.png" alt="PageSpeed Insights real user data, including field data for the TTFB metric." width="800" height="475" srcset="https://web.dev/static/articles/optimize-ttfb/image/psi-real-user-data-updated_36.png 36w,https://web.dev/static/articles/optimize-ttfb/image/psi-real-user-data-updated_48.png 48w,https://web.dev/static/articles/optimize-ttfb/image/psi-real-user-data-updated_72.png 72w,https://web.dev/static/articles/optimize-ttfb/image/psi-real-user-data-updated_96.png 96w,https://web.dev/static/articles/optimize-ttfb/image/psi-real-user-data-updated_480.png 480w,https://web.dev/static/articles/optimize-ttfb/image/psi-real-user-data-updated_720.png 720w,https://web.dev/static/articles/optimize-ttfb/image/psi-real-user-data-updated_856.png 856w,https://web.dev/static/articles/optimize-ttfb/image/psi-real-user-data-updated_960.png 960w,https://web.dev/static/articles/optimize-ttfb/image/psi-real-user-data-updated_1440.png 1440w,https://web.dev/static/articles/optimize-ttfb/image/psi-real-user-data-updated_1920.png 1920w,https://web.dev/static/articles/optimize-ttfb/image/psi-real-user-data-updated_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"> <figcaption>PageSpeed Insights field data.</figcaption> </figure> <p>For lab data, a subset of TTFB is shown in the <a href="https://developer.chrome.com/docs/lighthouse/performance/server-response-time">server response time audit</a>:</p> <figure> <img src="/static/articles/optimize-ttfb/image/lighthouse-server-response-time.png" alt="Server response time audit" width="800" height="213" srcset="https://web.dev/static/articles/optimize-ttfb/image/lighthouse-server-response-time_36.png 36w,https://web.dev/static/articles/optimize-ttfb/image/lighthouse-server-response-time_48.png 48w,https://web.dev/static/articles/optimize-ttfb/image/lighthouse-server-response-time_72.png 72w,https://web.dev/static/articles/optimize-ttfb/image/lighthouse-server-response-time_96.png 96w,https://web.dev/static/articles/optimize-ttfb/image/lighthouse-server-response-time_480.png 480w,https://web.dev/static/articles/optimize-ttfb/image/lighthouse-server-response-time_720.png 720w,https://web.dev/static/articles/optimize-ttfb/image/lighthouse-server-response-time_856.png 856w,https://web.dev/static/articles/optimize-ttfb/image/lighthouse-server-response-time_960.png 960w,https://web.dev/static/articles/optimize-ttfb/image/lighthouse-server-response-time_1440.png 1440w,https://web.dev/static/articles/optimize-ttfb/image/lighthouse-server-response-time_1920.png 1920w,https://web.dev/static/articles/optimize-ttfb/image/lighthouse-server-response-time_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"> <figcaption>PageSpeed Insights server response time audit.</figcaption> </figure> <aside class="key-point"> <b>Key point:</b> The server response time audit in Lighthouse excludes DNS lookup and redirect times, so it only represents a subset of TTFB. </aside> <p>To find out more ways how to measure TTFB in both the field and the lab, <a href="/ttfb#how-to-measure-ttfb">consult the TTFB metric page</a>.</p> <h3 id="understand_differences_between_field_and_lab_ttfb" data-text="Understand differences between field and lab TTFB" tabindex="-1">Understand differences between field and lab TTFB</h3> <p>Lab and field TTFB can differ for a number of reasons and when they do differ, it is important to understand why to be able to effectively use the lab data to improve your user experiences.</p> <ul> <li><p><strong>When lab TTFB is much larger than field TTFB</strong> this indicates that the lab environment is more constrained that the typical user experiences. This is not necessarily a problem, as the lab results and recommendations will likely sitll be valid, but just may exagerate the impact and the improvement.</p></li> <li><p><strong>When field TTFB is much larger than lab TTFB</strong> this indicates issues not apparent during the lab run, such as use of server-side caching, redirects, or network differences. In this case the lab results and recommendations may be less useful as they will miss one of the main issues.</p> <p>To see if server-side caching is impacting lab TTFB, try testing less common pages or using different URL parameters to get uncached content to see if the TTFB is more inline with field TTFB. It can also be useful to you have the ability to bypass server-side caching with a particular URL parameter. See the <a href="#use-caching">cached content section</a>.</p> <p>For redirects and network differences, analytics of how traffic is coming to our site, and where it is coming from, can be useful to diagnose if those are potential issues.</p></li> </ul> <h3 id="debug_high_ttfb_in_the_field_with_server-timing" data-text="Debug high TTFB in the field with Server-Timing" tabindex="-1">Debug high TTFB in the field with <code translate="no" dir="ltr">Server-Timing</code></h3> <p>The <a href="https://developer.mozilla.org/docs/Web/HTTP/Headers/Server-Timing"><code translate="no" dir="ltr">Server-Timing</code> response header</a> can be used in your application backend to measure distinct backend processes that could contribute to high latency. The header value's structure is flexible, accepting, at minimum, a handle that you define. Optional values include a duration value (via <code translate="no" dir="ltr">dur</code>), as well as an optional human-readable description (via <code translate="no" dir="ltr">desc</code>).</p> <aside class="note"><b>Note: </b> If measuring backend latency with <code translate="no" dir="ltr">Server-Timing</code> is not feasible, then a suitable alternative may be to rely on <a href="https://en.wikipedia.org/wiki/Application_performance_management">Application Performance Monitoring (APM)</a> to detect and diagnose backend performance problems. </aside> <p><code translate="no" dir="ltr">Serving-Timing</code> can be used to measure many application backend processes, but there are some that you may want to pay special attention to:</p> <ul> <li>Database queries</li> <li>Server-side rendering time, if applicable</li> <li>Disk seeks</li> <li>Edge server cache hits or misses (if using a CDN)</li> </ul> <p>All parts of a <code translate="no" dir="ltr">Server-Timing</code> entry are colon-separated, and multiple entries can be separated by a comma:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Bash Session"><code translate="no" dir="ltr"><span class="devsite-syntax-go">// Two metrics with descriptions and values</span> <span class="devsite-syntax-go">Server-Timing: db;desc="Database";dur=121.3, ssr;desc="Server-side Rendering";dur=212.2</span> </code></pre></devsite-code> <p>The header can be set using your application backend's language of choice. In PHP, for example, you could set the header like so:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="PHP"><code translate="no" dir="ltr"><<span class="devsite-syntax-x">?php</span> <span class="devsite-syntax-x">// Get a high-resolution timestamp before</span> <span class="devsite-syntax-x">// the database query is performed:</span> <span class="devsite-syntax-x">$dbReadStartTime = hrtime(true);</span> <span class="devsite-syntax-x">// Perform a database query and get results...</span> <span class="devsite-syntax-x">// ...</span> <span class="devsite-syntax-x">// Get a high-resolution timestamp after</span> <span class="devsite-syntax-x">// the database query is performed:</span> <span class="devsite-syntax-x">$dbReadEndTime = hrtime(true);</span> <span class="devsite-syntax-x">// Get the total time, converting nanoseconds to</span> <span class="devsite-syntax-x">// milliseconds (or whatever granularity you need):</span> <span class="devsite-syntax-x">$dbReadTotalTime = ($dbReadEndTime - $dbReadStartTime) / 1e+6;</span> <span class="devsite-syntax-x">// Set the Server-Timing header:</span> <span class="devsite-syntax-x">header('Server-Timing: db;desc="Database";dur=' . $dbReadTotalTime);</span> <span class="devsite-syntax-x">?</span>> </code></pre></devsite-code> <p>When this header is set, it will surface information you can use in both <a href="/articles/lab-and-field-data-differences#lab_data">the lab</a>, and in <a href="/articles/lab-and-field-data-differences#field_data">the field</a>.</p> <p>In the field, any page with a <code translate="no" dir="ltr">Server-Timing</code> response header set will populate the <code translate="no" dir="ltr">serverTiming</code> property in the <a href="https://developer.mozilla.org/docs/Web/API/Navigation_timing_API">Navigation Timing API</a>:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="JavaScript"><code translate="no" dir="ltr"><span class="devsite-syntax-c1">// Get the serverTiming entry for the first navigation request:</span> <span class="devsite-syntax-nx">performance</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">getEntries</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'navigation'</span><span class="devsite-syntax-p">)[</span><span class="devsite-syntax-mf">0</span><span class="devsite-syntax-p">].</span><span class="devsite-syntax-nx">serverTiming</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">forEach</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">entry</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span>><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-c1">// Log the server timing data:</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">console</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">log</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">entry</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">name</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">entry</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">description</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">entry</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">duration</span><span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">});</span> </code></pre></devsite-code> <p>In the lab, data from the <code translate="no" dir="ltr">Server-Timing</code> response header will be visualized in the timings panel of the <strong>Network</strong> tab in Chrome DevTools:</p> <figure> <img src="/static/articles/optimize-ttfb/image/a-visualization-server-t-9700559c46421.png" alt="A visualization of Server-Timing header values in the Network tab of Chrome DevTools. In this image, the Server-Timing header values are measuring whether or not a CDN edge server encountered a cache hit or miss, as well as the time to retrieve the resource from the edge and the origin server." width="777" height="143" srcset="https://web.dev/static/articles/optimize-ttfb/image/a-visualization-server-t-9700559c46421_36.png 36w,https://web.dev/static/articles/optimize-ttfb/image/a-visualization-server-t-9700559c46421_48.png 48w,https://web.dev/static/articles/optimize-ttfb/image/a-visualization-server-t-9700559c46421_72.png 72w,https://web.dev/static/articles/optimize-ttfb/image/a-visualization-server-t-9700559c46421_96.png 96w,https://web.dev/static/articles/optimize-ttfb/image/a-visualization-server-t-9700559c46421_480.png 480w,https://web.dev/static/articles/optimize-ttfb/image/a-visualization-server-t-9700559c46421_720.png 720w,https://web.dev/static/articles/optimize-ttfb/image/a-visualization-server-t-9700559c46421_856.png 856w,https://web.dev/static/articles/optimize-ttfb/image/a-visualization-server-t-9700559c46421_960.png 960w,https://web.dev/static/articles/optimize-ttfb/image/a-visualization-server-t-9700559c46421_1440.png 1440w,https://web.dev/static/articles/optimize-ttfb/image/a-visualization-server-t-9700559c46421_1920.png 1920w,https://web.dev/static/articles/optimize-ttfb/image/a-visualization-server-t-9700559c46421_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"> <figcaption>Server-Timing header values in the Network tab of Chrome DevTools.</figcaption> </figure> <p><code translate="no" dir="ltr">Server-Timing</code> response headers visualized in the network tab of Chrome DevTools. Here, <code translate="no" dir="ltr">Server-Timing</code> is used to measure whether a request for a resource has hit the CDN cache, and how long it takes for the request to hit the CDN's edge server and then the origin.</p> <p>Once you've determined that you have a problematic TTFB by analyzing the data available, then you can move onto fixing the problem.</p> <h2 id="ways_to_optimize_ttfb" data-text="Ways to optimize TTFB" tabindex="-1">Ways to optimize TTFB</h2> <p>The most challenging aspect of optimizing TTFB is that, while the web's frontend stack will always be HTML, CSS, and JavaScript, backend stacks can vary significantly. There are numerous backend stacks and database products that each have their own optimization techniques. Therefore, this guide will focus on what applies to most architectures, rather than focusing solely on stack-specific guidance.</p> <h3 id="platform-specific_guidance" data-text="Platform-specific guidance" tabindex="-1">Platform-specific guidance</h3> <p>The platform you use for your website can heavily impact TTFB. For example, WordPress performance is impacted by the number and quality of plugins, or what themes are used. Other platforms are similarly impacted when the platform is customized. You should consult the documentation for your platform for vendor-specific advice to supplement the more general performance advice in this post. The Lighthouse audit for reducing server response times also includes some limited <a href="https://developer.chrome.com/docs/lighthouse/performance/server-response-time#stack-specific_guidance">stack-specific guidance</a>.</p> <h3 id="hosting_hosting_hosting" data-text="Hosting, hosting, hosting" tabindex="-1">Hosting, hosting, hosting</h3> <p>Before you even consider other optimization approaches, hosting should be the first thing you consider. There's not much in the way of specific guidance that can be offered here, but a general rule of thumb is to ensure that your website's host is capable of handling the traffic you send to it.</p> <p>Shared hosting will generally be slower. If you're running a small personal website that serves mostly static files, this is probably fine, and some of the optimization techniques that follow will help you get that TTFB down as much as possible.</p> <p>However, if you're running a larger application with many users that involves personalization, database querying, and other intensive server-side operations, your choice of hosting becomes critical to lower TTFB in the field.</p> <p>When choosing a hosting provider, these are some things to look out for:</p> <ul> <li>How much memory is your application instance allocated? If your application has insufficient memory, it will thrash and struggle to serve pages up as fast as possible.</li> <li>Does your hosting provider keep your backend stack up to date? As new versions of application backend languages, HTTP implementations, and database software are released, performance in that software will be improved over time. It's key to partner with a hosting provider that prioritizes this kind of crucial maintenance.</li> <li>If you have very specific application requirements and want the lowest level access to server configuration files, ask if it makes sense to customize your own application instance's backend.</li> </ul> <aside class="note"> <b>Note:</b> If you're unsure how your hosting provider's real-user TTFB performance stacks up against competitors, <a href="https://ismyhostfastyet.com/">ismyhostfastyet.com</a> is a good place to get that information. </aside> <p>There are many hosting providers that will take care of these things for you, but if you start to observe long TTFB values even in dedicated hosting providers, it may be a sign that you might need to re-evaluate your current hosting provider's capabilities so that you can deliver the best possible user experience.</p> <h3 id="use_a_content_delivery_network_cdn" data-text="Use a Content Delivery Network (CDN)" tabindex="-1">Use a Content Delivery Network (CDN)</h3> <p>The topic <a href="/articles/content-delivery-networks">CDN usage</a> is a well-worn one, but for good reason: you could have a very well-optimized application backend, but users located far from your origin server may still experience high TTFB in the field.</p> <p>CDNs solve the problem of user proximity from your origin server by using a distributed network of servers that cache resources on servers that are physically closer to your users. These servers are called <em>edge servers</em>.</p> <p>CDN providers may also offer benefits beyond edge servers:</p> <ul> <li>CDN providers usually offer extremely fast DNS resolution times.</li> <li>A CDN will likely serve your content from edge servers using modern protocols such as HTTP/2 or HTTP/3.</li> <li>HTTP/3 in particular solves the head-of-line blocking problem present in TCP (which HTTP/2 relies on) by using the <a href="https://en.wikipedia.org/wiki/User_Datagram_Protocol">UDP protocol</a>.</li> <li>A CDN will likely also provide modern versions of TLS, which lowers the latency involved in TLS negotiation time. <a href="https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_1.3_handshake">TLS 1.3</a> in particular is designed to keep TLS negotiation as short as possible.</li> <li>Some CDN providers provide a feature often called an "edge worker", which uses an API similar to that of <a href="https://developer.mozilla.org/docs/Web/API/Service_Worker_API">the Service Worker API</a> to intercept requests, programmatically manage responses in edge caches, or rewrite responses altogether.</li> <li>CDN providers are very good at optimizing for compression. Compression is tricky to get right on your own, and may lead to slower response times in certain cases with dynamically generated markup, which must be compressed on the fly.</li> <li>CDN providers will also automatically cache compressed responses for static resources, leading to the best mix of compression ratio and response time.</li> </ul> <p>While adopting a CDN involves a varying amount of effort from trivial to significant, it should be a high priority to pursue in optimizing your TTFB if your website is not already using one.</p> <h3 id="use-caching" data-text="Use cached content where possible" tabindex="-1">Use cached content where possible</h3> <p>CDNs allow content to be cached at edge servers which are located physically closer to visitors, provided the content is configured with the appropriate <a href="https://developer.mozilla.org/docs/Web/HTTP/Headers/Cache-Control"><code translate="no" dir="ltr">Cache-Control</code> HTTP headers</a>. While this is not appropriate for personalized content, requiring a trip all the way back to the origin can negate much of the value of a CDN.</p> <p>For sites that frequently update their content, even a short caching time can result in noticeable performance gains for busy sites, since only the first visitor during that time experiences the fully latency back to the origin server, while all other visitors can reuse the cached resource from the edge server. Some CDNs allow cache invalidation on site releases allowing the best of both worlds—long cache times, but instant updates when needed.</p> <p>Even where caching is correctly configured, this can be ignored through the use of unique query string parameters for analytics measurement. These may look like different content to the CDN despite being the same, and so the cached version won't be used.</p> <aside class="caution"><strong>Caution:</strong> Caching is great, but it can mask a slow backend making diagnosing long TTFBs harder since testing a cached page will often show no TTFB issues. Having a way (such as a URL parameter) to skip the CDN and other caching layers lets you understand the full server time that some will experience as TTFB.</aside> <p>Older or less visited content may also not be cached, which can result in higher TTFB values on some pages than others. Increasing caching times can reduce the impact of this, but be aware that with increased caching times comes a greater possibility of serving potentially stale content.</p> <p>The impact of cached content does not just affect those using CDNs. Server infrastructure may need to generate content from costly database lookups when cached content cannot be reused. More frequently accessed data or precached pages can often perform better.</p> <h3 id="avoid_multiple_page_redirects" data-text="Avoid multiple page redirects" tabindex="-1">Avoid multiple page redirects</h3> <p>One common contributor to a high TTFB is <a href="https://developer.mozilla.org/docs/Web/HTTP/Redirections">redirects</a>. Redirects occur when a navigation request for a document receives a response that informs the browser that the resource exists at another location. One redirect can certainly add unwanted latency to a navigation request, but it can certainly get worse if that redirect points to another resource that results in <em>another</em> redirect—and so on. This can particularly impact sites that receive high volumes of visitors from advertisements or newsletters, since they often redirect through analytics services for measurement purposes. Eliminating redirects under your direct control can help to achieve a good TTFB.</p> <p>There are two types of redirects:</p> <ul> <li><strong>Same-origin redirects</strong>, where the redirect occurs entirely on your website.</li> <li><strong>Cross-origin redirects</strong>, where the redirect occurs initially on another origin—such as from a social media URL shortening service, for example—before arriving at your website.</li> </ul> <p>You want to focus on eliminating same-origin redirects, as this is something you will have direct control over. This would involve checking links on your website to see if any of them result in a <code translate="no" dir="ltr">302</code> or <code translate="no" dir="ltr">301</code> response code. Often this can be the result of not including the <code translate="no" dir="ltr">https://</code> scheme (so browsers default to <code translate="no" dir="ltr">http://</code> which then redirects) or because trailing slashes are not appropriately included or excluded in the URL.</p> <p>Cross-origin redirects are trickier as these are often outside of your control, but try to avoid multiple redirects where possible—for example, by using multiple link shorteners when sharing links. Ensure the URL provided to advertisers or newsletters is the correct final URL, so as not to add another redirect to the ones used by those services.</p> <p>Another important source of redirect time can come from HTTP-to-HTTPS redirects. One way you can get around this is to use the <a href="https://developer.mozilla.org/docs/Web/HTTP/Headers/Strict-Transport-Security"><code translate="no" dir="ltr">Strict-Transport-Security</code> header</a> (HSTS), which will enforce HTTPS on the first visit to an origin, and then will tell the browser to immediately access the origin through the HTTPS scheme on future visits.</p> <p>Once you have a good HSTS policy in place, you can speed things up on the first visit to an origin <a href="https://developer.mozilla.org/docs/Web/HTTP/Headers/Strict-Transport-Security#preloading_strict_transport_security">by adding your site to the HSTS preload list</a>.</p> <h3 id="stream_markup_to_the_browser" data-text="Stream markup to the browser" tabindex="-1">Stream markup to the browser</h3> <p>Browsers are optimized to process markup efficiently when it is streamed, meaning that markup is handled in chunks as it arrives from the server. This is crucial where large markup payloads are concerned, as it means the browser can parse that the chunks of markup incrementally, as opposed to waiting for the entire response to arrive before parsing can begin.</p> <p>Though browsers are great at handling streaming markup, it's crucial to do all that you can to keep that stream flowing so those initial bits of markup are on their way as soon as possible. If the backend is holding things up, that's a problem. Because backend stacks are numerous, it would be beyond the scope of this guide to cover every single stack and the issues that could arise in each specific one.</p> <p>React, for example—and other frameworks that can <a href="/articles/rendering-on-the-web#server-side_rendering">render markup on demand on the server</a>—have used a synchronous approach to server-side rendering. However, newer versions of React have implemented <a href="https://reactjs.org/docs/react-dom-server.html#overview">server methods for streaming markup</a> as it is being rendered. This means you don't have to wait for a React server API method to render the entire response before it's sent.</p> <aside class="note"> <b>Note:</b> Not every language runtime can take advantage of streaming server-side rendering. JavaScript runtimes such as <a href="https://deno.land/">Deno</a> and <a href="https://nodejs.org/">Node.js</a> support this out of the box, but other platforms may not support it. Check to see if this is the case for you, and see what you can do to upgrade or switch your runtime for better server-side rendering performance. </aside> <p>Another way to ensure markup is streamed to the browser quickly is to rely on <a href="/articles/rendering-on-the-web#static_rendering">static rendering</a> which generates HTML files during build time. With the full file available immediately, web servers can start sending the file immediately and the inherent nature of HTTP will result in streaming markup. While this approach isn't suitable for every page on every website—such as those requiring a dynamic response as part of the user experience—it can be beneficial for those pages that don't require markup to be personalized to a specific user.</p> <h3 id="use_a_service_worker" data-text="Use a service worker" tabindex="-1">Use a service worker</h3> <p>The <a href="https://developer.mozilla.org/docs/Web/API/Service_Worker_API">Service Worker API</a> can have a big impact on the TTFB for both documents and the resources they load. The reason for this is that a service worker acts as a proxy between the browser and the server—but whether there is an impact on your website's TTFB depends on how you set up your service worker, and if that setup aligns with your application requirements.</p> <ul> <li><strong>Use a <a href="https://developer.chrome.com/docs/workbox/caching-strategies-overview#stale-while-revalidate">stale-while-revalidate strategy</a> for assets.</strong> If an asset is in the service worker cache—be it a document or a resource the document requires—the stale-while-revalidate strategy will service that resource from the cache <em>first</em>, then will download that asset in the background and serve it from the cache for future interactions. <ul> <li>If you have document resources that don't change very often, using a stale-while-revalidate strategy can make a page's TTFB nearly instant. However, this doesn't work so well if your website sends dynamically generated markup—such as markup that changes based on whether a user is authenticated. In such cases, you'll always want to hit the network <em>first</em>, so the document is as fresh as possible.</li> <li>If your document loads non-critical resources that change with some frequency, but fetching the stale resource won't greatly affect the user experience—such as select images or other resources that aren't critical—the TTFB for those resources can be greatly reduced using a stale-while-revalidate strategy.</li> </ul></li> <li><strong>Use <a href="https://developer.chrome.com/blog/app-shell">the app shell model</a> for client-rendered applications.</strong> This model fits best for SPAs where the "shell" of the page can be delivered instantly from the service worker cache, and the dynamic content of the page is populated and rendered later on in the page lifecycle.</li> </ul> <h3 id="use_103_early_hints_for_render-critical_resources" data-text="Use 103 Early Hints for render-critical resources" tabindex="-1">Use <code translate="no" dir="ltr">103 Early Hints</code> for render-critical resources</h3> <p>No matter how well your application backend is optimized, there could still be a significant amount of work the server needs to do in order to prepare a response, including expensive (yet necessary) database work that delays the navigation response from arriving as quickly as it could. The potential effect of this is that some subsequent render-critical resources could be delayed, such as CSS or—in some cases—JavaScript that renders markup on the client.</p> <p><a href="https://developer.chrome.com/blog/early-hints">The <code translate="no" dir="ltr">103 Early Hints</code> header</a> is an early response code that the server can send to the browser while the backend is busy preparing markup. This header can be used to hint to the browser that there are render-critical resources the page should begin downloading while the markup is being prepared. For <a href="https://caniuse.com/mdn-http_status_103">supporting browsers</a>, the effect can be faster document rendering (CSS) and quicker page loading.</p> <aside class="note"> <b>Note:</b> If your website doesn't do a lot of processing on the backend to prepare markup—for example, static sites—then <code translate="no" dir="ltr">103 Early Hints</code> probably won't help much. It tends to work best for sites that involve considerable backend time before markup can be sent to the user. </aside> <p>One downside to 103 Early Hints is that, like caching, they can mask the "real" TTFB of a site. If a server infrastructure is slow (either because it's underpowered or the code needs optimizing), then that can be less obvious when 103 Early Hints is used as the TTFB looks fast. Sites using 103 Early Hints should consider measuring the actual server time (though <code translate="no" dir="ltr">Server-Timing</code> or <code translate="no" dir="ltr">finalResponseHeadersStart</code> of the <a href="https://developer.mozilla.org/docs/Web/API/PerformanceNavigationTiming">PerformanceNavigationTiming API</a>).</p> <h2 id="conclusion" data-text="Conclusion" tabindex="-1">Conclusion</h2> <p>Since there are so many combinations of backend application stacks, there's no one article that can encapsulate <em>everything</em> you can do to lower your website's TTFB. However, these are some options you can explore to try and get things going just a little bit faster on the server side of things.</p> <p>As with optimizing every metric, the approach is largely similar: measure your TTFB in the field, use lab tools to drill down into the causes, and then apply optimizations where possible. Not every single technique here may be viable for your situation, but some will be. As always, you'll need to keep a close eye on your field data, and make adjustments as needed to ensure the fastest possible user experience.</p> <p><em>Hero image by <a href="https://unsplash.com/@tvick">Taylor Vick</a>, sourced from Unsplash.</em></p> </div> <devsite-thumb-rating position="footer"> </devsite-thumb-rating> <div class="devsite-floating-action-buttons"> </div> </article> <devsite-content-footer class="nocontent"> <p>Except as otherwise noted, the content of this page is licensed under the <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 License</a>, and code samples are licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache 2.0 License</a>. For details, see the <a href="https://developers.google.com/site-policies">Google Developers Site Policies</a>. Java is a registered trademark of Oracle and/or its affiliates.</p> <p>Last updated 2024-01-10 UTC.</p> </devsite-content-footer> <devsite-notification > </devsite-notification> <div class="devsite-content-data"> <template class="devsite-content-data-template"> [[["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 2024-01-10 UTC."],[],[]] </template> </div> </devsite-content> </main> <devsite-footer-promos class="devsite-footer"> </devsite-footer-promos> <devsite-footer-linkboxes class="devsite-footer"> <nav class="devsite-footer-linkboxes nocontent" aria-label="Footer links"> <ul class="devsite-footer-linkboxes-list"> <li class="devsite-footer-linkbox wd-footer-promo"> <h3 class="devsite-footer-linkbox-heading no-link">web.dev</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <h3 class="devsite-footer-linkbox-heading no-link"> web.dev </h3> <div class="devsite-footer-linkbox-description">We want to help you build beautiful, accessible, fast, and secure websites that work cross-browser, and for all of your users. This site is our home for content to help you on that journey, written by members of the Chrome team, and external experts.</div> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Contribute</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="https://issuetracker.google.com/issues/new?component=1400680&template=1857359" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > File a bug </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://issuetracker.google.com/issues?q=status:open%20componentid:1400680&s=created_time:desc" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > See open issues </a> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Related Content</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="https://developer.chrome.com/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > Chrome for Developers </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://blog.chromium.org/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > Chromium updates </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/case-studies" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Case studies </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/shows" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > Podcasts & shows </a> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Follow</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="https://twitter.com/ChromiumDev" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > @ChromiumDev on X </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://www.youtube.com/user/ChromeDevelopers" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > YouTube </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://www.linkedin.com/showcase/chrome-for-developers" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Chrome for Developers on LinkedIn </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/static/blog/feed.xml" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > RSS </a> </li> </ul> </li> </ul> </nav> </devsite-footer-linkboxes> <devsite-footer-utility class="devsite-footer"> <div class="devsite-footer-utility nocontent"> <nav class="devsite-footer-utility-links" aria-label="Utility links"> <ul class="devsite-footer-utility-list"> <li class="devsite-footer-utility-item "> <a class="devsite-footer-utility-link gc-analytics-event" href="//policies.google.com/terms" data-category="Site-Wide Custom Events" data-label="Footer Terms link" > Terms </a> </li> <li class="devsite-footer-utility-item "> <a class="devsite-footer-utility-link gc-analytics-event" href="//policies.google.com/privacy" data-category="Site-Wide Custom Events" data-label="Footer Privacy link" > Privacy </a> </li> <li class="devsite-footer-utility-item glue-cookie-notification-bar-control"> <a class="devsite-footer-utility-link gc-analytics-event" href="#" data-category="Site-Wide Custom Events" data-label="Footer Manage cookies link" aria-hidden="true" > Manage cookies </a> </li> </ul> <devsite-language-selector> <ul role="presentation"> <li role="presentation"> <a role="menuitem" lang="en" >English</a> </li> <li role="presentation"> <a role="menuitem" lang="de" >Deutsch</a> </li> <li role="presentation"> <a role="menuitem" lang="es_419" >Español – América Latina</a> </li> <li role="presentation"> <a role="menuitem" lang="fr" >Français</a> </li> <li role="presentation"> <a role="menuitem" lang="id" >Indonesia</a> </li> <li role="presentation"> <a role="menuitem" lang="it" >Italiano</a> </li> <li role="presentation"> <a role="menuitem" lang="pl" >Polski</a> </li> <li role="presentation"> <a role="menuitem" lang="pt_br" >Português – Brasil</a> </li> <li role="presentation"> <a role="menuitem" lang="vi" >Tiếng Việt</a> </li> <li role="presentation"> <a role="menuitem" lang="tr" >Türkçe</a> </li> <li role="presentation"> <a role="menuitem" lang="ru" >Русский</a> </li> <li role="presentation"> <a role="menuitem" lang="he" >עברית</a> </li> <li role="presentation"> <a role="menuitem" lang="ar" >العربيّة</a> </li> <li role="presentation"> <a role="menuitem" lang="fa" >فارسی</a> </li> <li role="presentation"> <a role="menuitem" lang="hi" >हिंदी</a> </li> <li role="presentation"> <a role="menuitem" lang="bn" >বাংলা</a> </li> <li role="presentation"> <a role="menuitem" lang="th" >ภาษาไทย</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_cn" >中文 – 简体</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_tw" >中文 – 繁體</a> </li> <li role="presentation"> <a role="menuitem" lang="ja" >日本語</a> </li> <li role="presentation"> <a role="menuitem" lang="ko" >한국어</a> </li> </ul> </devsite-language-selector> </nav> </div> </devsite-footer-utility> <devsite-panel></devsite-panel> </section></section> <devsite-sitemask></devsite-sitemask> <devsite-snackbar></devsite-snackbar> <devsite-tooltip ></devsite-tooltip> <devsite-heading-link></devsite-heading-link> <devsite-analytics> <script type="application/json" analytics>[]</script> <script type="application/json" tag-management>{"at": "True", "ga4": [], "ga4p": [], "gtm": [{"id": "GTM-MZWCJPP", "purpose": 0}], "parameters": {"internalUser": "False", "language": {"machineTranslated": "False", "requested": "en", "served": "en"}, "pageType": "article", "projectName": "Articles", "signedIn": "False", "tenant": "web", "recommendations": {"sourcePage": "", "sourceType": 0, "sourceRank": 0, "sourceIdenticalDescriptions": 0, "sourceTitleWords": 0, "sourceDescriptionWords": 0, "experiment": ""}, "experiment": {"ids": ""}}}</script> </devsite-analytics> <devsite-badger></devsite-badger> <script nonce="5zrVr2ptJ/f5LVsrrCYPJdhqo2Es8y"> (function(d,e,v,s,i,t,E){d['GoogleDevelopersObject']=i; t=e.createElement(v);t.async=1;t.src=s;E=e.getElementsByTagName(v)[0]; E.parentNode.insertBefore(t,E);})(window, document, 'script', 'https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/web/js/app_loader.js', '[27,"en",null,"/js/devsite_app_module.js","https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f","https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/web","https://web-dot-devsite-v2-prod-3p.appspot.com",1,null,["/_pwa/web/manifest.json","https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/images/video-placeholder.svg","https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/web/images/favicon.png","https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/web/images/lockup.svg","https://fonts.googleapis.com/css?family=Google+Sans:400,500|Roboto:400,400italic,500,500italic,700,700italic|Roboto+Mono:400,500,700&display=swap"],1,null,[1,6,8,12,14,17,21,25,50,52,63,70,75,76,80,87,91,92,93,97,98,100,101,102,103,104,105,107,108,109,110,112,113,117,118,120,122,124,125,126,127,129,130,131,132,133,134,135,136,138,140,141,147,148,149,151,152,156,157,158,159,161,163,164,168,169,170,179,180,182,183,186,191,193,196],"AIzaSyCNm9YxQumEXwGJgTDjxoxXK6m1F-9720Q","AIzaSyCc76DZePGtoyUjqKrLdsMGk_ry7sljLbY","web.dev","AIzaSyB9bqgQ2t11WJsOX8qNsCQ6U-w91mmqF-I","AIzaSyAdYnStPdzjcJJtQ0mvIaeaMKj7_t6J_Fg",null,null,null,["Profiles__enable_developer_profiles_callout","MiscFeatureFlags__enable_firebase_utm","OnSwitch__enable","Analytics__enable_clearcut_logging","Cloud__enable_cloud_facet_chat","Cloud__enable_cloud_shell_fte_user_flow","DevPro__enable_cloud_innovators_plus","Profiles__enable_page_saving","Profiles__enable_dashboard_curated_recommendations","MiscFeatureFlags__enable_variable_operator","Search__enable_dynamic_content_confidential_banner","Search__enable_ai_eligibility_checks","Profiles__require_profile_eligibility_for_signin","MiscFeatureFlags__emergency_css","Cloud__enable_legacy_calculator_redirect","Cloud__enable_cloud_dlp_service","MiscFeatureFlags__developers_footer_dark_image","Profiles__enable_complete_playlist_endpoint","CloudShell__cloud_code_overflow_menu","MiscFeatureFlags__enable_project_variables","TpcFeatures__enable_mirror_tenant_redirects","TpcFeatures__enable_unmirrored_page_left_nav","Cloud__enable_cloud_shell","Profiles__enable_release_notes_notifications","Profiles__enable_join_program_group_endpoint","Search__enable_suggestions_from_borg","Cloud__enable_free_trial_server_call","Profiles__enable_recognition_badges","Cloud__enable_cloudx_ping","Profiles__enable_completequiz_endpoint","EngEduTelemetry__enable_engedu_telemetry","Cloud__enable_llm_concierge_chat","Concierge__enable_pushui","DevPro__enable_developer_subscriptions","Profiles__enable_completecodelab_endpoint","Profiles__enable_profile_collections","Cloud__enable_cloudx_experiment_ids","MiscFeatureFlags__developers_footer_image","Search__enable_page_map","BookNav__enable_tenant_cache_key","MiscFeatureFlags__enable_view_transitions","Experiments__reqs_query_experiments","CloudShell__cloud_shell_button","Profiles__enable_public_developer_profiles","Profiles__enable_stripe_subscription_management","MiscFeatureFlags__enable_explain_this_code","Profiles__enable_awarding_url"],null,null,"AIzaSyA58TaKli1DculwmAmbpzLVGuWc8eCQgQc","https://developerscontentserving-pa.googleapis.com","AIzaSyDWBU60w0P9hEkr29kkksYs8Z7gvZ8u_wc","https://developerscontentsearch-pa.googleapis.com",2,4,null,"https://developerprofiles-pa.googleapis.com",[27,"web","web.dev","web.dev",null,"web-dot-devsite-v2-prod-3p.appspot.com",null,null,[null,null,null,null,null,null,null,null,null,null,null,[1],null,null,null,null,null,null,[1],null,null,null,null,[1,null,1],[1,1,null,1,1]],null,[38,null,null,null,null,null,"/images/lockup.svg","/images/touchicon-180.png",null,null,null,1,1,null,null,null,null,null,null,null,null,2,null,null,null,"/images/lockup-dark-theme.svg",[]],[],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[],[1,1]],[[null,null,null,null,null,["GTM-MZWCJPP"],null,null,null,null,null,[["GTM-MZWCJPP",1]],1]],null,4],null,null,1]') </script> <devsite-a11y-announce></devsite-a11y-announce> </body> </html>