What is the Time To First Byte (TTFB) and how to improve it
What is the time to first byte and

What is the Time to First Byte
The time-to-first byte (TTFB) indicates how much time has elapsed in milliseconds between the start of the request and receiving the first response (byte) from a webpage. The TTFB is therefore also referred to as the waiting time. The TTFB is a way to measure the speed of a webpage. The TTFB is a foundational metric, this means that time added to the TTFB will also be added to the Largest Contentful Paint and the First Contentful Paint.
The Time To First Byte can be broken down into 5 pieces:
- Redirect time
- Worker & Cache time
- DNS lookup time
- TCP connect time
- SSL handshake
- Server response
Why is Time to First Byte important
The Time to First Byte is not a Core Web Vital and it is very possible to pass the Core Web Vitals while failing the TTFB metric. That does not mean that the TTFB is not important. The TTFB is an extremely important metric to optimize and fixing the TTFB will greatly improve pagespeed & the page experience!
The impact of TTFB for visitors
The time to first byte preceded all other paint metrics. While the browser is waiting for the Time to First byte it the browser cannot do anything an d will just show a blank screen! This means that any increase in time to first byte will result in extra 'blank screen' time and any decrease in the time to first byte will translate into less 'blank screen' time.
To get that 'feeling of instant loading pages' the time to first byte needs to be as fast as possible!
How to Measure the Time To First Byte TTFB
PageSpeed TIP: every resource has it's own time to first byte. In this context however we are talking about the time to first byte of the main page!
The Time to First Byte can greatly fluctuate between different user with different devices and from different locations. That is why self-measuring the time to first byte from your desktop computer is probably not a great idea. Using tools like pingdom or GTMetrix is not reliable for the same reason.
The best way to measure the Time To First Byte is to collect Real User Metrics (RUM) data from your visitors. You can do this yourself with this code or use a RUM tool like CoreDash
const formatTime = (time) => { //round by 2 decimals, use Math.round() for integer return Math.round(time * 100) / 100; }; new PerformanceObserver((entryList) => { const [pageNav] = entryList.getEntriesByType('navigation'); // timing start times are relative const activationStart = pageNav.activationStart || 0; const workerStart = Math.max(pageNav.workerStart - activationStart, activationStart); const dnsStart = Math.max(pageNav.domainLookupStart - activationStart, workerStart); const tcpStart = Math.max(pageNav.connectStart - activationStart, dnsStart); const sslStart = Math.max(pageNav.secureConnectionStart - activationStart, tcpStart); const requestStart = Math.max(pageNav.requestStart - activationStart, sslStart); const responseStart = Math.max(pageNav.responseStart - activationStart, requestStart); // attribution based on https://www.w3.org/TR/navigation-timing-2/#processing-model // use assosictive array to log the results more readable let attributionArray = []; attributionArray['Redirect Time'] = { 'time in ms': formatTime(workerStart - activationStart) }; attributionArray['Worker and Cache Time'] = { 'time in ms': formatTime(dnsStart - workerStart) }; attributionArray['DNS Time'] = { 'time in ms': formatTime(tcpStart - dnsStart) }; attributionArray['TCP Time'] = { 'time in ms': formatTime(sslStart - tcpStart) }; attributionArray['SSL Time'] = { 'time in ms': formatTime(requestStart - sslStart) }; attributionArray['Request Time'] = { 'time in ms': formatTime(responseStart - requestStart) }; attributionArray['Total TTFB'] = { 'time in ms': formatTime(responseStart - activationStart) }; // log the results console.log('%cTime to First Byte (' + formatTime(responseStart - activationStart) + 'ms)', 'color: blue; font-weight: bold;'); console.table(attributionArray); console.log('%cOrigininal navigation entry', 'color: blue; font-weight: bold;'); console.log(pageNav); }).observe({ type: 'navigation', buffered: true });
What is a good TTFB score?

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.
How to improve the TTFB - Avoid redirects
When a user requests a web page, the server may respond with a redirect to another page. This redirect can add additional time to the TTFB because the browser must make an additional request to the new page.
There are several ways to avoid redirects or minimize the impact of redirects:
- Update your internal links! Whenever you change the location of a page update your internal links to that page to ensure no references to the earlier page location remains.
- Handle redirects on the server level.
- Use relative URLs: When linking to pages on your own website, use relative URLs instead of absolute URLs. This will help prevent unnecessary redirects.
- Use canonical URLs: If you have multiple pages with similar content, use a canonical URL to indicate the preferred version of the page. This will help prevent duplicate content and unnecessary redirects.
- Use 301 redirects: If you must use a redirect, use a 301 redirect instead of a 302 redirect. A 301 redirect is a permanent redirect, while a 302 redirect is a temporary redirect. Using a 301 redirect will help prevent unnecessary redirects.
How to improve the TTFB - Speed up the initial connection
A high Time to First Byte can have multiple causes. However DNS, TCP and SSL affect all time to first bytes. So let's start there. Even though optimizing these 3 may not yield the biggest results optimizing these will optimize every single TTFB!
Speed up DNS
PageSpeed TIP: DNS TPC & SSL are usually a bigger issue when you are using a cheap host or when you serve to a global audience while not using a CDN. Use RUM tracking to view your Global TTFB and break down toe TTFB into it's sub-parts
Use a Fast DNS Provider. Not all DNS providers are as fast as others. Some (free) DNS providers are just slower then other (free) DNS providers. CloudFlare for example will give you one of the worlds fastest DNS providers for free!
Increase the DNS TTL. Another way is to increase the Time to Live (TTL) value . TTL is a setting that determines how long the lookup can be cached. The higher the TTL, the less likely the browser will need to perform another DNS lookup. It is important to note that ISPs also cache DNS.
Speed up TCP
The 'TCP part' of the TTFB is the initial connection to the webserver. When connecting the browser and the server share information about how information will be exchanged. You can speed up TCP by connecting to a server that is geographically close to your location and by ensuring the server has enough free resources. Sometimes changing to a lightweight server like NGINX can speed up the TCP part of the TTFB. In many cases using a CDN will speed up the TCP connection!
Speed up SSL/TSL
Once the TCP connection has been made the browser and the server will need to secure your connection through encryption. You can speed this up by using faster, newer and more lightweight protocols (SSL Cyphers) and by being geographically closer to your webserver (since the TSL negotiation takes quite a few back and forth round-trips). Using a CDN will often improve the SSL connection time since they are often very well configured and have multiple servers all across the globe. TLS 1.3 in particular is designed to keep TLS negotiation as short as possible.
How to improve the TTFB - Speed up the server side
Page Caching
By far the most efficient way to speed up the time to first byte is to server the HTML from the server cache. There are several ways to implement full page caching. The most effective way is by doing this directly at the web-server level with for example the NGINX caching module or by using Varnish as a reverse caching proxy.
There also are a lot of plugins for difference CMS systems that will cache full pages and many SPA frameworks like NextJS have their own implementation of full page caching along with different invalidation strategies.
If you would like to implement you own caching the basic idea is super simple. When a client requests a page check if it exists in the cache folder. If it does not exist, create the page, write it to cache and show the page like you normally would. On any next request to the page the cache file will exist and you can serve the page directly from cache.
Partial caching
With partial caching the idea is to cache frequently used, slow or expensive parts of the page or resources (like api calls, database results) for fast retrieval. This will eliminate bottlenecks when generating a page. If you are interested in these types of optimizations (you should be interested!!) look up these concepts: Memory Cache, Object Cache, Database Cache, Object-Relational Mapping (ORM) Cache,Content Fragment Cache and Opcode Cache.
Optimize the application code
Sometimes the page cannot be served from (partial) cache because the cache file does not exist, large parts of the pages are dynamic or because you run into other issues. That is why we need to optimize the application code. How this is done depends entirely on your application. Ir is based on re-writing and optimizing slow parts of your code.
Optimize database queries
Most of the time ineffective database queries are the root cause of a slow Time to First Byte. Start by logging 'slow queries' and 'queries not using indexes' to disk. Analyze them, add indexes or ask an expert to perform database tuning to fix these issues. See https://www.mongodb.com/docs/atlas/performance-advisor/ and https://dev.mysql.com/doc/refman/8.0/en/slow-query-log.html
Reduce internal network latency
A bad practice that I come across more times that I would like is a delay in time to first byte caused by slowness causes by communication between the web application and the data storage. This usually only happens with large sites that have outsourced their data storage to cloud API's.
How to improve the TTFB - speed up the client side
Client side caching
Client-side caching involves the user’s browser storing resources that they’ve already accessed, like images and scripts. So when the user comes back to your website, their browser can quickly retrieve the cached resources instead of having to download them again. This can significantly reduce the number of requests made to the server, which in turn can reduce the TTFB.
Service Workers
Speculation Rules API
<script type="speculationrules"> {"prerender": [{ "source": "document", "where": {"selector_matches": "nav a"}, "eagerness": "moderate" }]} </script>
Page Prefetching
If you do not want to use the Speculation Rules API because of it's poor browser support or you could use a small script called quicklink. This will prefetch all the links in the visible viewport and all but eliminate the Time To First Byte for these links!
The downside to quicklinks is that it requires more browser resources but for now it will outperform the speculation rules API.
How to improve the TTFB - leverage a CDN
CDN

TTFB with a CDN and edge caching

TTFB without a CDN hosted in Germany
Avoid redirects

