Performance
How to run a WordPress performance audit without guessing.
The standard advice is to install a caching plugin and see if things feel better. That works often enough to be believed and rarely enough to be frustrating. Here is how to find out what is actually costing you time, before you change anything.
Measure first, and measure the right thing
Before touching a setting, get a number you can compare against later. Without a baseline you cannot tell whether a change helped, and you will keep every change you made because none of them obviously hurt.
Use PageSpeed Insights or WebPageTest on your home page and on one real content page. Write down three figures:
| Metric | What it means | Aim for |
|---|---|---|
| TTFB | How long the server took to begin replying | Under 600ms |
| LCP | When the biggest visible thing finished loading | Under 2.5s |
| CLS | How much the layout jumped while loading | Under 0.1 |
TTFB is the one that tells you whether your problem is WordPress or everything else. A slow TTFB means the server is slow to produce the page — that is PHP, the database, your plugins and your host. A fast TTFB with a slow LCP means the server is fine and your images, fonts or scripts are the problem. These need completely different fixes, and this single number tells you which article to read next.
Admin-bar, admin-ajax and a dozen plugins behave differently for a logged-in administrator. If you test while logged in you are measuring an experience nobody else has. Use a private window.
Where WordPress sites actually lose time
In rough order of how often it turns out to be the culprit:
1. The number of plugins doing work on every request
Not the count — the behaviour. Thirty well-written plugins can be lighter than three bad ones. What costs you is a plugin that runs a database query on every page load, loads its CSS and JavaScript everywhere including pages that do not use it, or calls an external API while the visitor waits.
That last one is worth dwelling on. If a plugin makes an HTTP request to someone else’s server during page generation and that server is slow, your page is slow, and there is nothing you can do about it from your end. This is precisely why Guru Site Health makes no external requests at all: a plugin that phones home is a plugin that can be slowed down by someone else’s outage.
To find the offenders, use Query Monitor — free, and the single best diagnostic plugin for WordPress. It breaks down page generation time by plugin, lists every database query with its caller, and flags slow ones in red. Install it, load a slow page, read the admin bar. Then deactivate it when you are done, because it is a development tool.
2. Autoloaded options
This is the one almost nobody checks, and it is often the largest single win on an older site.
WordPress loads every option marked autoload = yes from wp_options on
every single request, including requests that never use any of them. On a healthy site that is
a few hundred kilobytes. On a site that has had thirty plugins installed and removed over five years, it
can be several megabytes, read and unserialised on every page view, forever.
Plugins add autoloaded rows and frequently do not remove them on uninstall. Nothing in the WordPress admin shows you this. Autoloaded options covers how to measure yours and what is safe to remove.
3. Expired transients piling up
Transients are WordPress’s cache-with-an-expiry-date. The catch is that expiry is lazy: an
expired transient is not deleted when it expires, only when something asks for it again. If a plugin
writes a transient per product, per user, or per search query and then stops asking for them, they sit in
wp_options indefinitely.
Tens of thousands of expired transient rows bloat the options table, slow down queries against it, and inflate every backup you take. Clearing expired ones is safe by definition — they have already expired, so nothing is entitled to rely on them.
4. Post revisions
By default WordPress keeps every revision of every post forever. A page edited two hundred times has
two hundred rows in wp_posts, plus their meta. This matters less than people claim for page
speed, but it matters for database size, backup time, and how long an export takes.
You can cap it in wp-config.php:
define('WP_POST_REVISIONS', 10);
Be careful with tools that delete existing revisions in bulk. Revisions are your undo history, and deleting them is not reversible.
5. Images that were never resized
A 4000px photograph from a phone, uploaded straight into a post and displayed at 800px, is the most
common single cause of a slow page on a small site. WordPress generates smaller versions automatically
and modern themes use srcset to pick one — but only if the theme is doing its job, and
not if the image was placed by a page builder that hard-codes the full-size URL.
Check your media library for anything over about 500KB and ask whether it needs to be.
6. Your host
Last on the list, and sometimes the whole answer. If TTFB is 1.5 seconds on a near-empty site with two plugins, no amount of optimisation inside WordPress will fix that. You are on an oversubscribed shared server, and the fix is to move.
What to do, in what order
- Measure. Record TTFB, LCP and CLS, logged out, on two pages.
- Install Query Monitor and find out which plugins own your page generation time.
- Check your autoload size. It is the cheapest large win and almost nobody looks.
- Clear expired transients. Safe, free, and sometimes removes tens of thousands of rows.
- Fix the obvious images. Anything over 500KB that did not need to be.
- Only now, add page caching. Caching is genuinely effective, but adding it first hides the underlying problem rather than fixing it — and the problem is still there for logged-in users, for the admin, and for every uncached request.
- Measure again and compare to your baseline.
A cache makes the symptom go away for anonymous visitors. That is worth having. But a site that is only fast because it is cached is a site that is slow for everyone who is logged in, slow in the admin, and slow the first time anyone visits any page. Fix the generation time, then cache it.
Change one thing at a time
The reason performance work so often ends in a mess is that people apply eight changes in an afternoon, see an improvement, and have no idea which of the eight did it — or which of the eight quietly broke the checkout.
Change one thing. Measure. Keep it or undo it. It is slower for an afternoon and much faster over a year, and it means you can explain what you did.
Frequently asked questions
What is a good TTFB for a WordPress site?
Under 600ms is a reasonable target and under 200ms is good. If your TTFB is over about 1.5 seconds on a site with few plugins, the problem is usually the host rather than anything inside WordPress.
Do too many plugins slow down WordPress?
The count matters far less than what they do. Thirty lightweight plugins can easily outperform three that each run database queries on every request, load assets on pages that do not need them, or call an external API while the visitor waits. Use Query Monitor to see which of yours actually cost time.
Will a caching plugin fix a slow WordPress site?
It will usually make anonymous page loads much faster, which is worth having. It will not help logged-in users, the admin area, or the first request to any uncached page, because those still generate the page from scratch. Find and fix the generation cost first, then cache.
Is it safe to delete expired transients?
Yes. An expired transient has already passed its own expiry date, so nothing is entitled to rely on it — WordPress would regenerate it on the next request anyway. The only reason they linger is that WordPress deletes them lazily, when something asks for them, rather than when they expire.
How many post revisions should I keep?
Ten is a sensible cap for most sites: define('WP_POST_REVISIONS', 10); in wp-config.php. Be cautious with plugins that bulk-delete existing revisions — revisions are your undo history and deleting them cannot be undone.
What is the best free tool for diagnosing WordPress performance?
Query Monitor. It shows page generation time broken down by plugin, every database query with the code that triggered it, slow queries highlighted, and all HTTP requests made during the page load. Install it, load a slow page, then deactivate it when you are finished — it is a development tool, not something to leave running.
Find these on your own site in about ten seconds
Guru Site Health runs 32 checks across updates, security, database, media, accessibility and SEO, and gives you one score. Thirteen of the findings can be fixed from the dashboard in one click, and every fix can be undone. It makes no external requests — nothing about your site ever leaves it.