Skip to main content
Blog|
How-to guides

How to speed up WordPress: a complete optimization guide

|
Apr 11, 2026|13 min read
HOW-TO GUIDESHow to speed up WordPress: acomplete optimization guideHOSTNEYhostney.comApril 11, 2026

A slow WordPress site costs you visitors, rankings, and revenue. Google uses page speed as a ranking factor. Visitors who wait more than three seconds for a page to load are far more likely to leave than to engage. And every second of delay reduces conversions – whether that means fewer signups, fewer purchases, or fewer pages read.

The good news is that WordPress performance problems are predictable and fixable. Most slow sites share the same handful of causes: inadequate hosting, no caching, unoptimized images, bloated databases, too many plugins, and render-blocking CSS and JavaScript. Fix these in the right order and the improvement is dramatic.

This guide covers the optimization stack in priority order – from the changes that make the biggest difference to the ones that provide incremental gains on top of a solid foundation.

How to measure your site's speed#

Before optimizing anything, measure what you are working with. Two tools give you the data you need:

Google PageSpeed Insights (pagespeed.web.dev) tests your site against Google’s Core Web Vitals and provides both lab data and real-user data (if your site has enough traffic). It scores your site on a 0-100 scale and flags specific issues to fix.

GTmetrix (gtmetrix.com) provides a waterfall chart showing every resource your page loads, how long each takes, and what blocks rendering. The waterfall is where you diagnose specific bottlenecks – a slow database response, a massive image, a render-blocking script.

Core Web Vitals

Google’s Core Web Vitals are the three metrics that matter most for both user experience and SEO rankings:

  • Largest Contentful Paint (LCP) – how long until the largest visible element (usually the hero image or main heading) is rendered. Target: under 2.5 seconds.
  • Interaction to Next Paint (INP) – how quickly the page responds when a user clicks, taps, or types. This replaced First Input Delay (FID) in March 2024. Target: under 200 milliseconds.
  • Cumulative Layout Shift (CLS) – how much the page layout shifts unexpectedly as it loads (elements jumping around, images loading without reserved space). Target: under 0.1.

These are not abstract metrics. LCP directly correlates with perceived speed. INP determines whether the site feels responsive. CLS determines whether users accidentally click the wrong thing because a button moved. All three feed into Google’s ranking algorithm.

1. Hosting - the foundation#

No amount of optimization compensates for underpowered hosting. A WordPress site running on a shared server with a spinning hard drive, 512MB of RAM, and PHP 7.4 has a speed ceiling that no plugin can break through.

What matters in a hosting environment

Storage type. NVMe SSDs are 5-10x faster than SATA SSDs for random read/write operations, which is exactly what database queries produce. A MySQL query that takes 50ms on a SATA drive might take 10ms on NVMe. Multiply that by 30-50 queries per page load and the difference is measurable. See why NVMe storage affects your site speed for the technical details.

PHP version. PHP 8.x is significantly faster than PHP 7.x for WordPress workloads. PHP 8.0 introduced the JIT compiler. PHP 8.1 and 8.2 added further performance improvements. Running an end-of-life PHP version is both a security risk and a performance penalty.

PHP-FPM workers. Every concurrent visitor that hits an uncached page needs a PHP-FPM worker to process the request. If all workers are busy, new requests queue up and response times spike. Hosting plans with too few workers handle traffic spikes poorly even if the individual responses are fast.

Object cache availability. Having Memcached or Redis available for WordPress’s persistent object cache eliminates redundant database queries. This is infrastructure that needs to be provided by the host – it is not something a plugin can create on its own.

Resource isolation. On shared hosting where multiple accounts share the same CPU and memory, another account’s traffic spike can slow your site down. Container-based isolation prevents this by allocating dedicated resources per account. On Hostney, every account runs in its own container with guaranteed CPU, RAM, and PHP-FPM workers that are not shared with other accounts.

When hosting is the bottleneck

If your Time to First Byte (TTFB) is consistently above 600ms on uncached pages, hosting is likely the bottleneck. TTFB measures how long the server takes to start sending a response. A well-configured WordPress site on decent hardware should have uncached TTFB under 400ms. If yours is over a second, no amount of frontend optimization will make the site feel fast.

2. Caching - the biggest single improvement#

Caching is the most impactful optimization for most WordPress sites. A properly cached page that takes 15 milliseconds to serve replaces a dynamically generated page that takes 300-800 milliseconds. For visitors, the difference is between a site that feels instant and one that feels sluggish.

Page caching (server-level)

Server-level page caching stores the complete HTML output of a page and serves it directly from Nginx or Apache without invoking PHP at all. The request never reaches WordPress – the web server reads the cached file and returns it. This is fundamentally faster than any PHP-based caching plugin because PHP is never loaded.

On Hostney, Nginx FastCGI caching is built into the stack. The Hostney Cache plugin connects WordPress to the server-level cache automatically – when you publish or update a post, the relevant cached pages are purged so visitors always see fresh content. There is nothing to configure beyond installing the plugin. The plugin also handles Gutenberg’s duplicate save requests, archive page purging, and bulk operation fallbacks without any manual setup.

On other hosts, you typically need a caching plugin like WP Rocket, W3 Total Cache, or LiteSpeed Cache to generate cached pages. These plugins work by creating static HTML files and serving them through PHP or .htaccess rewrite rules. This is faster than generating the page dynamically, but slower than server-level caching because PHP still loads on every request to determine whether a cached file exists.

Browser caching

Browser caching tells visitors’ browsers to store static files (images, CSS, JavaScript, fonts) locally so they do not need to be downloaded again on subsequent page loads. This is configured through HTTP cache headers.

Most WordPress hosts set these headers by default. If yours does not, a caching plugin can add them, or you can add them in your .htaccess or Nginx configuration:

# Example Nginx configuration for browser caching
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2|svg)$ {
    expires 365d;
    add_header Cache-Control "public, immutable";
}

Browser caching does not help first-time visitors, but it makes a significant difference for returning visitors and for navigation within your site (clicking from one page to another reuses cached CSS, JS, and fonts).

Object caching (Memcached/Redis)

WordPress runs dozens of database queries per page load, and many fetch the same data repeatedly: site options, active plugins, theme settings, rewrite rules, user roles. Without an object cache, WordPress re-fetches this data from MySQL on every request.

A persistent object cache stores these query results in memory (Memcached or Redis) and serves them in microseconds instead of querying the database. The impact is most significant on pages that cannot be fully cached – admin pages, WooCommerce cart and checkout, logged-in user dashboards – because those pages still benefit from faster underlying queries even though the full page is not cached.

On Hostney, Memcached is available on all plans. The Hostney Cache plugin installs the object-cache.php drop-in and connects to your account’s isolated Memcached instance automatically. On other hosts, you can use plugins like Redis Object Cache or W3 Total Cache’s object cache module, provided your host has Redis or Memcached available.

For a deeper understanding of how cache hits and misses affect your site’s performance and server capacity, see what is a cache miss and how does it affect performance.

3. Image optimization#

Images are typically the largest files on any WordPress page. An unoptimized hero image can be 2-5MB. A product page with ten unoptimized photos can load 20-30MB of images. This is the single biggest cause of slow LCP scores.

Serve images in modern formats

WebP is 25-35% smaller than JPEG at equivalent visual quality. AVIF is even smaller but has slightly less browser support. Convert your images to WebP (or AVIF with a JPEG fallback) before uploading, or use a plugin that converts them automatically.

Plugins that handle conversion: ShortPixel, Imagify, Smush Pro, EWWW Image Optimizer. These compress and convert images either on upload or in bulk for existing media.

Correctly size images

WordPress generates multiple sizes of each image you upload (thumbnail, medium, large, full). Your theme should use the appropriately sized version for each context. A 300px-wide thumbnail area should not load the 2000px-wide original.

Check your pages with GTmetrix – it flags images that are served at a larger size than they are displayed. If your theme’s content area is 720px wide, there is no reason to serve a 1920px-wide image.

Lazy loading

Lazy loading defers the loading of images that are not visible in the viewport until the user scrolls to them. This dramatically reduces initial page load time because the browser only downloads images the visitor can actually see.

WordPress has native lazy loading built in since version 5.5. It automatically adds loading="lazy" to images and iframes in post content. Most modern themes support this without any additional configuration.

For the LCP image (typically the hero image or first visible image), lazy loading should be disabled. Lazy loading the LCP image delays it, which directly hurts your LCP score. Well-coded themes exclude above-the-fold images from lazy loading. If yours does not, you can add fetchpriority="high" to the LCP image element to tell the browser to prioritize it.

4. Database optimization#

WordPress databases accumulate bloat over time: post revisions, auto-drafts, trashed posts, expired transients, spam comments, and orphaned metadata. This bloat slows down queries because MySQL has to scan through more data.

What to clean up

  • Post revisions – WordPress saves every revision of every post by default, with no limit. A post edited 50 times has 50 revisions in the database, each a full copy of the post content. Limit revisions by adding to wp-config.php :
define('WP_POST_REVISIONS', 5);
  • Auto-drafts and trashed posts – WordPress creates auto-drafts as you type and keeps trashed posts for 30 days. Clean up old ones periodically.
  • Expired transients – transients are temporary cached values. WordPress is supposed to clean up expired ones, but some linger. Plugins that set transients with no expiry are especially problematic.
  • Orphaned post meta and term relationships – when posts are deleted, their metadata sometimes stays behind.
  • Spam and trashed comments – these accumulate if not purged regularly.

For a complete walkthrough, see WordPress database optimization: how to clean up and speed up your database.

wp_options table bloat

The wp_options table is queried on every page load and is the most common source of database-related slowness. Plugins that store large amounts of serialized data in wp_options with autoload=yes force WordPress to load that data into memory on every request.

Check what is autoloaded:

SELECT option_name, LENGTH(option_value) AS size
FROM wp_options
WHERE autoload = 'yes'
ORDER BY size DESC
LIMIT 20;

If you see entries that are hundreds of kilobytes or larger, those are candidates for investigation. Common culprits include analytics plugins caching report data, form plugins storing submission logs, and caching plugins storing configuration as serialized arrays.

5. CSS and JavaScript optimization#

Unoptimized CSS and JavaScript files can block page rendering and add significant weight to page loads.

Defer non-critical JavaScript

By default, JavaScript files in the <head> block rendering – the browser stops parsing HTML to download and execute each script. Deferring non-critical scripts allows the HTML to render while scripts load in the background:

<script src="script.js" defer></script>

The defer attribute tells the browser to download the script in parallel with HTML parsing and execute it after the document is fully parsed. The async attribute is similar but executes the script as soon as it downloads, regardless of parsing state – useful for independent scripts like analytics.

In WordPress, this is typically handled by plugins. Autoptimize, Asset CleanUp, Perfmatters, and WP Rocket all offer options to defer or delay JavaScript loading. If you are building a custom theme, you can set defer directly when enqueuing scripts.

Minify CSS and JavaScript

Minification removes whitespace, comments, and unnecessary characters from CSS and JavaScript files without changing functionality. A 100KB CSS file might become 70KB after minification. The savings are modest per file but add up across all assets.

Plugins: Autoptimize, WP Rocket, LiteSpeed Cache, and Asset CleanUp all handle minification.

Eliminate render-blocking resources

A CSS file in the <head> blocks rendering until it is fully downloaded and parsed. For a large CSS file loaded from a slow CDN, this can add hundreds of milliseconds to LCP.

The fix is to inline critical CSS (the minimum CSS needed to render above-the-fold content) and defer the rest. This is complex to do manually but plugins like WP Rocket and Perfmatters automate it. Critical CSS generation analyzes each page type and extracts only the CSS rules needed for the initial viewport.

Reduce plugin overhead

Each WordPress plugin adds its own CSS and JavaScript files, and many load these files on every page whether needed or not. A contact form plugin loading its CSS and JS on every page even though the form only appears on the Contact page wastes bandwidth and rendering time.

Asset CleanUp and Perfmatters let you disable specific plugin assets on pages where they are not needed. This is one of the most effective optimizations for sites with many plugins because it directly reduces the number of HTTP requests and the total file size per page.

6. CDN for static assets#

A Content Delivery Network caches your static files (images, CSS, JavaScript, fonts) on servers distributed around the world. When a visitor in Tokyo loads your site hosted in London, the static files are served from a nearby CDN edge server instead of crossing the Atlantic.

CDNs help most when your audience is geographically distributed and your static assets are large (image-heavy sites, sites with many CSS/JS files). For a small site with a local audience, the improvement may be minimal.

The practical decision comes down to your traffic pattern, asset size, and budget. For a detailed breakdown of when a CDN is worth it and when it is not, see should I use a CDN for my website.

Setting up a CDN with WordPress

Most CDN providers (Cloudflare, Bunny CDN, KeyCDN, StackPath) offer WordPress plugins or straightforward DNS configuration. The typical setup involves:

  1. Sign up with a CDN provider.
  2. Configure your domain (either a full DNS proxy like Cloudflare, or a CDN subdomain like cdn.example.com ).
  3. Install the provider’s WordPress plugin or use a plugin like CDN Enabler to rewrite asset URLs.

Cloudflare’s free tier is a common starting point. It provides a global CDN, DDoS protection, and basic optimizations at no cost.

HTTP/2 and HTTP/3#

HTTP/2 allows the browser to download multiple files simultaneously over a single connection instead of opening a new connection for each file. This eliminates the latency overhead that HTTP/1.1 had with multiple assets – the browser no longer queues requests sequentially.

HTTP/3 takes this further with QUIC, a protocol built on UDP that eliminates head-of-line blocking and reduces connection setup time. For mobile users on unreliable networks, HTTP/3 makes a noticeable difference.

Both protocols are server-side configurations, not something you install as a plugin. Most modern hosts support HTTP/2. HTTP/3 support is less common but growing. You can check whether your site supports either by looking at the protocol column in your browser’s developer tools Network tab.

Plugins that help#

Rather than installing a dozen optimization plugins, choose a focused set that covers the areas you need:

All-in-one caching and optimization: WP Rocket (paid, easiest to configure), LiteSpeed Cache (free, best on LiteSpeed servers), W3 Total Cache (free, more complex). On Hostney, the Hostney Cache plugin handles page caching and object caching at the server level, so you do not need a separate caching plugin.

Image optimization: ShortPixel, Imagify, EWWW Image Optimizer, Smush Pro. These handle compression, WebP conversion, and lazy loading.

Asset optimization: Autoptimize (free, minification and deferral), Perfmatters (paid, asset management and script control), Asset CleanUp (free/paid, per-page asset control).

Database cleanup: WP-Optimize, Advanced Database Cleaner. Run these periodically rather than on every page load.

The single most important rule with optimization plugins: do not stack them. Running WP Rocket and W3 Total Cache simultaneously, or having two image optimization plugins both processing the same uploads, creates conflicts and can make performance worse. Choose one tool per job.

Quick checklist#

If you want a priority-ordered list to work through:

  1. Check your TTFB. If it is over 600ms on uncached pages, investigate hosting first.
  2. Enable server-level page caching (or install a caching plugin).
  3. Enable object caching (Memcached or Redis) if your host supports it.
  4. Update to the latest PHP version your plugins and theme support.
  5. Compress and resize images. Convert to WebP.
  6. Clean up the database – revisions, transients, auto-drafts.
  7. Defer non-critical JavaScript and minify CSS/JS.
  8. Disable plugin assets on pages where they are not needed.
  9. Consider a CDN if your audience is geographically spread.
  10. Measure again with PageSpeed Insights and GTmetrix. Compare before and after.

Start at the top. Each level builds on the one before it. Deferring JavaScript on a site with no caching and unoptimized images is polishing the wrong layer.

Related articles