Skip to content

WordPress speed: the honest optimization guide

Most slow WordPress sites are fixed in the same order: hosting and server-level page caching first, an object cache for busy sites, then images, the database, plugin weight, and only then a CDN. This guide explains the mechanism behind each layer, which work pays, and where the returns collapse.

An hourglass with a widened neck pouring sand quickly, a few grains at the neck in vermilion.

By Sam Moreton

First-hand + researched

Most slow WordPress sites are slow for boring reasons, and the order you fix them in matters more than any individual trick. The sequence that works: hosting with server-level page caching first, an object cache if the site is busy, image weight next, then the database, then a plugin audit, then a CDN last. The order works because each layer near the top removes an entire class of work from every request, and the ones near the bottom shave margins. Work the order and you have fixed nearly everything fixable. Past a certain point the returns collapse, and a lot of popular speed advice lives in the collapsed zone. Here is where the cliff sits, so you can stop before the afternoons stop paying.

Page caching is the whole game for anonymous visitors

Every uncached request runs the full play. The web server hands the request to PHP, PHP loads WordPress, WordPress loads your theme and every active plugin, dozens or hundreds of database queries fire, and the assembled page goes back out. A full page cache stores that assembled page and hands it to the next visitor without waking PHP at all. The page becomes nearly as cheap to serve as a static file, and everything else in this guide is a smaller lever.

Where the cache lives matters. A caching plugin runs inside WordPress, which is better than nothing and still pays PHP's overhead on a miss. Server-level caching, Varnish on Cloudways, sits in front of PHP entirely and serves stored pages without touching the application. If your host offers that, the biggest speed decision you will ever make for the site is whether it is switched on and working. The Cloudways flavour of that decision has few enough settings to learn in an hour: Cloudways cache settings, explained.

The object cache, once the site is busy

Full page caching covers anonymous visitors, which on most sites is most traffic. It covers nothing for logged-in users, for carts in motion on a store, or for the WordPress admin, where every request runs the full play. An object cache, Redis or Memcached, keeps the results of repeated database lookups in memory: site options, transients, parsed menus, anything WordPress would otherwise fetch again on every request. On a busy site this is the difference between an admin that responds and an admin you visit when you have time to wait.

Skip it on a quiet brochure site without guilt: the page cache does the heavy lifting and Redis sits idle. Sites busy enough to want it usually sit on tiers where hosts bundle it.

Images, the heaviest bytes on the page

Images are usually the largest payload a WordPress page ships and the easiest weight to cut. The mechanics are unglamorous. Upload images at roughly the size they display instead of dumping 4000-pixel originals for the browser to shrink. Serve modern formats like WebP or AVIF, which compress far better than JPEG at similar visible quality. Let lazy loading hold offscreen images back; it has been in WordPress core since version 5.5, so a plugin for it is dead weight.

One honest limit: image work improves how fast the cached page renders and how much data a visitor downloads. It does nothing for the wait before the first byte, which belongs to hosting and caching. Both problems are real, and they are different. In the other direction, a page hauling multi-megabyte hero images stresses every hosting tier equally, so neither layer excuses skipping the other.

The database, and the autoload pile

The classic WordPress database problem is autoloaded options. WordPress loads a set of options on every single request, and plugins installed and deleted years ago leave their settings sitting in that set. The pile grows quietly, every request pays to load it, and one day wp-admin is slow and nobody can explain why. Cached pages escape the cost only because they skip PHP entirely.

The check takes minutes: WP-CLI lists the options flagged for autoloading so you can see the worst offenders. Cleaning the pile is careful work, confirming what reads each option before deleting it. On a neglected site the payoff is one of the few honest free wins in WordPress. Expired transients accumulate on similar timescales and merit an occasional clear. Post revisions barely matter, whatever the cleanup plugins claim.

Plugin weight, the audit nobody does

Plugin count is a weak metric. A site running forty quiet plugins can outrun a site running twelve chatty ones. What matters is what each plugin does on every request: external calls during page loads, license checks and telemetry hooked into every request, and overlaps, two plugins doing the same job and both charging you the overhead. Page builders are a category unto themselves, leaving shortcodes buried in content that keep executing long after the builder is gone.

The audit is an afternoon, once, and then a habit. Query Monitor, a free plugin, shows what each plugin contributes to page generation time. Deactivate the suspects on staging, measure, and be honest when a plugin you like turns out to be expensive. Then apply the habit at install time: before adding a plugin, ask what it will do on every request from now on.

The CDN goes last

A content delivery network serves your static files from servers nearer to each visitor, which helps distant visitors and takes static requests off your origin during spikes. A CDN in front of an uncached site is decoration on the problem. With caching and page weight handled, adding Cloudflare is a calm hour: Cloudflare and WordPress, the sane setup.

Where the effort stops paying

If the page cache is working, anonymous pages already load about as fast as they are going to, and further tuning fights for margins visitors cannot perceive. Score chasing is directional at best; the tools disagree and reward different things. And buying a bigger server before the cache is on wastes the money, because a caching misconfiguration presents exactly like an undersized server: both just look slow from the outside.

When every layer here is handled and the site still strains under real traffic, the question changes from speed to capacity, how much load the setup can carry before it degrades. The WordPress capacity estimator turns what you know about your traffic into a starting answer. And if you read this far while suspecting the hosting layer itself is the weak one, a crowded shared server with no server-level cache, that suspicion is usually correct. The managed WordPress buyer guide is the next click.