How to Reduce Time to First Byte (TTFB) on WordPress
How to measure Time to First Byte properly, tell a network problem from a slow application, and work through the usual WordPress causes: caching, autoloaded options, queries, remote calls, PHP and workers.

Time to First Byte is the gap between a visitor asking for a page and the first byte of the answer arriving. Nothing renders during that gap. On WordPress a slow TTFB nearly always means PHP is building the page on every visit and something in that build takes too long.
To reduce TTFB on WordPress you first have to find where the time goes: the network, the wait for a free PHP worker, PHP itself, the database, or a call to someone else's server. The checks below are in the order we run them.
Measure before you change anything
Google's guidance on Time to First Byte suggests 0.8 seconds or less for most sites, measured the way a visitor experiences it, so redirects, the DNS lookup and the TLS handshake are all inside that figure. It is not one of the Core Web Vitals, but it sets the floor for Largest Contentful Paint.
From a terminal, curl splits the time into its parts:
curl -s -o /dev/null -w "dns %{time_namelookup} connect %{time_connect} tls %{time_appconnect} ttfb %{time_starttransfer}\n" https://example.com/
The values are cumulative. Subtract the TLS figure from the TTFB figure and you have the time the server spent thinking. Run it several times, from a location close to your visitors, because a test from another continent mostly measures distance.
Then measure the same site two ways: a public page as a logged-out visitor, and a page the cache does not store, such as the cart or any page while logged in.
Cached and uncached pages are different problems
If the logged-out, cached page is slow, PHP is not the cause, because PHP never ran. Look at the network: a redirect chain from http to https to www, a server far from the audience, slow DNS, or no CDN in front of the HTML.
If the cached page is fast and the uncached one is slow, the cache is hiding a slow application. That still matters. Logged-in users, the cart, the checkout, search results, the admin and every AJAX call skip the page cache, and so does the first visitor after each purge. The rest of this article is about that uncached time.
And if a page you expected to be cached is not, start there. A plugin that calls session_start() or sets a cookie on every request, a Cache-Control: no-store header, or campaign query strings that create a new cache entry per click will each quietly defeat a page cache. Tools > Site Health runs its own page cache test, and the layers are described in WordPress caching explained.
See where PHP spends the time
Install Query Monitor on a staging copy, or briefly on the live site, and load the slow page as an administrator. The toolbar shows total generation time, time spent in database queries, the query count and peak memory. Those figures split the problem in two. When queries are a small share of the generation time, look at PHP code and external calls. When they are most of it, look at the database.
With shell access, the WP-CLI profile package gives the same split without a browser:
wp package install wp-cli/profile-command
wp profile stage --all --spotlight --url=https://example.com/slow-page/
It reports time, query count and cache hits for each stage of the load (bootstrap, main query, template) and for the hooks inside them, which usually leads to a plugin by name.
Reduce TTFB on WordPress by working through these causes
Autoloaded options
WordPress loads every option marked as autoloaded on every request. Plugins store settings, caches and sometimes logs there, and removed plugins leave theirs behind. Site Health flags the total once it passes 800 KB. Check the size, then list the heaviest entries:
wp option list --autoload=on --format=total_bytes
wp option list --autoload=on --fields=option_name,size_bytes | sort -n -k 2 | tail -n 20
An option left by a plugin you removed can be deleted. One that an active plugin needs only on its own settings screen can be switched with wp option set-autoload option_name off. Back up the database first and change one option at a time.
Slow and repeated database queries
In Query Monitor, open the queries panel, sort by time, then look at the view grouped by component. Two patterns stand out: a single query that takes a large share of the total (often a search across wp_postmeta on a value with no index), and the same small query repeated hundreds of times in a loop. Both are code problems in a theme or plugin. A persistent object cache softens the repeated kind. The slow kind needs the query rewritten or the data moved to a table built for it.
Calls to external services during the page load
A page that waits for another server is only as fast as that server. License checks, social feeds, currency rates, CRM lookups and geolocation calls all appear in Query Monitor's HTTP API Calls panel with their duration. Stop making them while a visitor waits: cache the response in a transient, refresh it from a scheduled task, and set a short timeout so a third-party outage cannot stall your pages.
An old PHP version or a starved OPcache
Newer PHP branches run WordPress faster than end-of-life ones, and the move is the cheapest speed gain available. Our guide to upgrading PHP on a WordPress site covers the testing.
OPcache keeps compiled PHP in memory so files are not compiled again on each request. Current WordPress versions show its status under Tools > Site Health > Info > Server. A site with many plugins can outgrow the defaults for opcache.memory_consumption and opcache.max_accelerated_files, described in the PHP manual. Once the cache is full, the scripts that did not fit are compiled on every request. Ask the host what the values are and how full the cache is.
Too few PHP workers
Each uncached request occupies one PHP worker until it finishes. When all workers are busy, new requests queue, and that wait is added to TTFB before your code has started. The sign is a site that is quick when you test it alone and slow at busy times. On your own server the limit is pm.max_children in the PHP-FPM pool. On managed hosting it is part of the plan.
Before paying for more workers, see what is using them. Bots crawling filter URLs, admin-ajax.php polling from open admin tabs and requests that should have been cached are the common waste.
Take scheduled tasks off visitor requests
By default WordPress checks for due scheduled tasks during page loads and starts them with a background request to wp-cron.php. On a busy site that puts backups, email batches and feed imports in competition with visitors for the same workers. Switch to a real cron job. In wp-config.php:
define( 'DISABLE_WP_CRON', true );
Then add a system cron entry that runs due events every five minutes:
*/5 * * * * cd /var/www/example.com && wp cron event run --due-now --quiet
Many hosts offer the same thing as a control panel setting. While you are there, run wp cron event list and look for events that fire every minute or have piled up overdue.
When better hosting is the answer and when it is not
Hosting fixes capacity problems. If a single request on an idle server is fast and the site slows down only under load, you need more workers, more CPU or an object cache, and a better plan is money well spent. If a single request on an idle server is slow, the cause is in the application, and it will follow you to the new server.
The measuring, the cron change and the autoload cleanup are things you can do yourself with the commands above. Bring in a developer when the profile points at a theme or plugin query, at custom code, or at a store or LMS where most traffic is logged in and nothing can be page-cached. That diagnosis, and the code fixes that follow, are what our WordPress performance optimization work consists of, and a maintenance plan keeps the numbers from drifting back.
Frequently asked questions
What is a good TTFB for a WordPress site?
Google's guidance is 0.8 seconds or less at the 75th percentile of visits, including redirects and connection setup. A page served from a page cache should come in well under that. For uncached pages such as the checkout, look at the server's own processing time and keep it as low as the application allows.
Does a CDN reduce TTFB?
For the HTML document, only if the CDN caches the page at the edge, or at least ends the connection closer to the visitor. A CDN in front of a slow uncached origin still waits for that origin. It does shorten delivery of images, CSS and JavaScript, which TTFB of the page does not measure.
Why is the WordPress admin slow when the front end is fast?
The admin is never page-cached, so you are seeing the real speed of PHP and the database. Dashboard widgets that call remote services, plugins that run heavy queries on every admin screen and a large autoloaded options total are the usual causes. Query Monitor works in the admin as well.
Will more RAM or CPU fix a slow TTFB?
Only if the server is short of them. More CPU helps when requests queue for workers, and more memory helps when the database cannot keep its indexes in memory. A slow query or a blocking external call takes the same time on a bigger machine.
Add worldwincoder.com as a preferred source on Google, or open this article in your AI assistant to use it as a source.
