WordPress Speed Optimisation Guide 2026: The 9-Step Stack
CouponZania runs on ScalaHosting’s Build #2 VPS. Our global TTFB averages 28ms. We got there by working through the WordPress performance stack in a specific order — hosting first, caching second, assets third. Skip that sequence and you optimise symptoms instead of causes.
This guide covers everything we actually did, with the exact settings, real benchmark numbers, and the mistakes that slow most sites down before any plugin is installed.
- Fix hosting and database first — no plugin overcomes a slow server or a bloated wp_options table.
- PHP 8.3+ with 384 MB OPcache, plus persistent Redis object caching, eliminates most TTFB problems on any VPS.
- Server-level page caching (LiteSpeed, Nginx FastCGI) delivers 35–106ms TTFB. Plugin-based caching delivers 200–400ms. The gap is where the cache intercepts the request — not configuration.
- Only 32% of WordPress sites pass Good TTFB. The fix is almost always infrastructure, not plugins.
- Core Web Vitals are measured at the 75th percentile of real user data — PageSpeed Insights scores are a diagnostic tool, not a ranking signal.
The Right Order
Do These in Order. The Sequence Is the Strategy.
Most WordPress speed guides treat every optimisation as equal. They’re not. The order you apply them determines how much each one actually delivers.
Applying a CDN over an uncached server with a bloated database is like repainting a house with a cracked foundation. The result looks better in screenshots but the underlying problem grows. Work from the server outward — always.
Hosting — the ceiling everything else operates within
CPU tier, PHP worker count, storage type, and web server all set hard limits. No plugin overcomes a slow server.
PHP version + OPcache — eliminate compilation overhead
PHP 8.3+ with correctly sized OPcache reduces per-request overhead by 50–95%. No infrastructure changes required.
Database cleanup — fix wp_options before caching it
Bloated autoload data means every uncached page load carries that query weight. Caching a bloated database just caches the inefficiency.
Redis object caching — eliminate repeat database queries
Reduces dynamic page database queries from 100+ per request to 2–5 on cache hits. Critical for authenticated sessions that bypass page cache.
Server-level page caching — serve HTML before PHP loads
LiteSpeed Cache, Nginx FastCGI Cache, or Varnish intercepts before PHP executes. TTFB: 35–106ms cached vs 400–900ms uncached.
Images — WebP conversion, explicit dimensions, lazy loading
Images cause LCP failures more than any other front-end asset. Fix them before touching JavaScript or CSS.
JavaScript and CSS — defer, minify, remove unused
Unnecessary JS blocks rendering. Unused CSS inflates payload. Both affect INP and LCP on mobile.
Fonts — self-host, font-display:swap, preload LCP font
Google Fonts adds a DNS lookup, a connection, and a blocking render request. Self-hosting eliminates all three.
CDN — cache assets and pages at the edge
Cloudflare (free) reduces geographic latency and eliminates repeat-visit asset roundtrips. Add last so bypass rules are configured against a clean cache stack.
Step 1: Hosting
Hosting Is the Ceiling. Choose It Like It Matters.
DebugHawk measured TTFB across 5.7 million WordPress pageviews in Q4 2025. Server-cached pages: 106ms median. Uncached pages: 723ms median. That 7× gap is set entirely by hosting infrastructure — not by any plugin.
Three factors determine hosting performance for WordPress: CPU tier, PHP worker count, and storage type. Every other specification is secondary.
CPU Tier Determines How Fast PHP Executes
PHP-FPM processes every WordPress request before the server sends a single byte. Faster CPUs execute PHP faster, which directly reduces TTFB on every uncached page load.
CouponZania’s ScalaHosting VPS runs AMD EPYC 9474F processors — ranked #31 of 1,190 server CPUs on PassMark, top 3% globally. Our 28ms TTFB is partly hardware. SiteGround uses Intel Xeon Gold 6268CL (PassMark #226 — 475% slower multithread). Shared hosting typically uses CPUs from 2012–2015.
PassMark CPU ranking — lower number = faster processor. Source: PassMark Performance Test, June 2026. ScalaHosting spec confirmed directly with CTO Vladislav Georgiev.
PHP Worker Count Determines Concurrency
Each uncached WordPress request occupies one PHP-FPM worker for 200–500ms while PHP executes and the database responds. Run out of workers and the next visitor waits in a queue.
Shared hosting typically provides 2–4 PHP workers per account. A VPS gives you 16–30+. This is why shared hosting TTFB spikes randomly at traffic peaks — you’re waiting in line, not waiting for the server.
Storage Tier Determines Database Query Speed
Every uncached WordPress request hits the database. Storage speed determines how fast those queries return. PCIe 5.0 NVMe: 2,457 MB/s. PCIe 3.0 NVMe: ~600 MB/s. SATA SSD: ~550 MB/s. Spinning disk: ~120 MB/s.
Sites migrated from SATA SSD to NVMe hosting typically see 50–70% TTFB reductions on uncached pages — with no other changes. [INTERNAL LINK: best WordPress hosting comparison]
| Host | Best for | Price/mo | CPU tier | Storage |
|---|---|---|---|---|
| ScalaHosting VPS | Best performance per dollar | $44.95 | AMD EPYC 9474F — top 3% | PCIe 5.0 NVMe |
| Kinsta | Fully managed, zero config | $115/mo | Google Cloud C2 | NVMe |
| Cloudways (GCP) | Flexible cloud VPS | $118/mo | GCP N2 | SSD |
| SiteGround Cloud | Beginner-friendly managed | $100/mo | Xeon Gold 6268CL | NVMe |
| Hostinger | Budget / starter sites | $3.99/mo | Shared (not disclosed) | NVMe SSD |
Prices are standard/promotional rates as of June 2026. ScalaHosting is at 3-year introductory rate. All competitor prices at standard annual rates. Verified June 2026.
Step 2: PHP + OPcache
PHP Version and OPcache: The Fastest Win With No Infrastructure Cost
PHP processes every WordPress page request. Upgrading PHP version and configuring OPcache is the highest-leverage change available on any hosting tier — including shared hosting where you can’t touch the server configuration.
Which PHP Version to Use in 2026
Throughput benchmarks: GCP C2 instance, WordPress 6.4.2, 15 concurrent users, OPcache enabled. Source: Kinsta/Boostedhost benchmarks. PHP 8.5 TTFB figure: 365i production monitoring, uncached homepage. WooCommerce PHP 8.4 gain: Kinsta benchmarks 2025.
PHP 8.3 is the safe minimum — it holds ~40% WordPress market share and is fully compatible with WordPress 6.8+. PHP 8.4 is the recommended target if you can test plugin compatibility in staging; it delivers a documented 21% WooCommerce throughput improvement over PHP 7.4. CouponZania runs PHP 8.5 and our 27% TTFB reduction from 8.3 is the single biggest improvement we made in 2025.
OPcache: The Setting Most Sites Get Wrong
By default, PHP reads and compiles every script file on every request. OPcache stores compiled bytecode in shared memory so subsequent requests skip the filesystem read and parse cycle entirely. PHP’s own documentation reports 50–95% overhead reduction.
The most common mistake: the default 128 MB allocation is insufficient for medium WordPress installations. When OPcache fills up, it silently stops caching new scripts. You get irregular TTFB spikes that look random but appear precisely at concurrent traffic peaks.
OPcache Settings by Site Size
Under 10 plugins: 128 MB (default is fine)
10–20 plugins: 256–384 MB
WooCommerce, Multisite, plugin-heavy installs: 384–512 MB
Key settings: opcache.validate_timestamps=0 eliminates filesystem stat calls per request. Flush manually after every plugin update. opcache.max_accelerated_files=10000 prevents cache-flush loops on large plugin stacks. Monitor via opcache_get_status() — hit rate below 98% means under-allocation.
Step 3: Database
Database Cleanup: Fix the wp_options Table Before You Cache Anything
Every WordPress page load queries the wp_options table for autoloaded options. When autoload data grows beyond 800 KB — which happens naturally over years of plugin installs and removals — each uncached page load carries that query weight before a single line of your site renders.
One documented cleanup reduced autoload query time by 82% and removed 2.58 MB of dead weight with no other infrastructure changes. Caching a bloated database just caches the inefficiency. Clean it first.
What to Clean
- Post revisions — WordPress keeps unlimited by default. Set
WP_POST_REVISIONS = 3in wp-config.php - Orphaned autoloaded options from uninstalled plugins
- Expired transients (WordPress should clean these but often doesn’t)
- Spam comments — they’re still counted in every comment query
- Trashed posts and pages older than 30 days
How to Clean It
- Run
wp option list --autoload=yes --format=tablevia WP-CLI to identify bloated entries - WP Sweep or Advanced Database Cleaner handle most cleanup tasks with a single click
- After cleanup, run
OPTIMIZE TABLE wp_optionsto reclaim fragmented space - Set a monthly scheduled database cleanup — WP Rocket includes this; WP-Cron handles it on standalone installs
Steps 4 & 5: Caching
The Two Caching Layers You Actually Need (and How They Differ)
Page caching and object caching solve completely different problems. Most WordPress speed advice conflates them. Here is what each one actually does.
| Cache layer | What it stores | TTFB impact | Bypassed by |
|---|---|---|---|
| Server-level page cache LiteSpeed, Nginx FastCGI | Full HTML per URL — served before PHP loads | 35–106ms | Logged-in users, cart, checkout, query strings |
| Plugin page cache WP Rocket, WP Super Cache | Full HTML per URL — PHP still loads to check cache | 200–400ms | Logged-in users, cart, checkout, query strings |
| Redis object cache | DB query results in RAM — serves everyone including logged-in users | 67% less PHP time | Nothing — works for all requests |
| PHP OPcache | Compiled PHP bytecode — skips filesystem reads on every request | 50–95% compile overhead cut | OPcache flush after updates |
Server-Level Page Caching: 7× Faster TTFB
Server-level caching intercepts the request before PHP loads. LiteSpeed Cache (on LiteSpeed/OpenLiteSpeed servers), Nginx FastCGI Cache, and Varnish all work this way. The HTML is returned directly from disk or memory — no PHP, no database.
Plugin-based caching (WP Rocket, WP Super Cache) intercepts after PHP loads. PHP still starts, checks whether a cached file exists, then serves it. The difference is where in the stack the interception happens. This is why server-level caching delivers 35–106ms TTFB and plugin caching delivers 200–400ms — even with identical configuration. [INTERNAL LINK: best WordPress caching plugins]
Redis Object Caching: Critical for WooCommerce and Membership Sites
WordPress’s built-in object cache only lasts for one PHP request. Every page load re-queries the database from scratch. Redis persistent object caching stores query results between requests and across simultaneous PHP workers.
A typical WordPress site runs 80–120 database queries per uncached request. With Redis: 2–5 queries on cache hits. The measured result across multiple case studies: 67% reduction in PHP execution time. For WooCommerce stores, LMS platforms, and membership sites that can’t serve logged-in users from page cache, Redis is the only mechanism that prevents the database from becoming the bottleneck at scale.
define('WP_REDIS_HOST', '127.0.0.1'); and define('WP_REDIS_PORT', 6379); to wp-config.php.Step 6: Images
Images: The Most Common LCP Failure in WordPress
Images are the LCP element on most WordPress pages. A 4 MB hero image discovered late in the waterfall fails LCP regardless of how fast the server is. Fix images before touching JavaScript or CSS — the payoff is higher and the implementation is simpler.
Format: Switch to WebP
WebP is 25–35% smaller than JPEG at equivalent quality. Browsers with 96%+ global support (Chrome, Firefox, Safari 14+, Edge). Serve with <picture> elements and JPEG fallback, or use a CDN that auto-converts on delivery (Cloudflare Image Resizing, Bunny.net Optimizer).
Dimensions: Always Set width and height
Missing width/height attributes cause CLS (Cumulative Layout Shift) as the browser doesn’t know how much space to reserve. WordPress core adds these automatically for images in the media library since 5.5 — but theme-injected images and plugin hero images often skip them.
LCP Image: Preload + fetchpriority
Add fetchpriority="high" and loading="eager" to your LCP element (usually the hero image or above-fold featured image). Add a <link rel="preload" as="image"> in the document head. This single change frequently moves LCP from 3–4s to under 2.5s on fast servers.
loading="lazy" to all images by default. Your LCP image is almost certainly above the fold. Lazy-loading it tells the browser to deprioritise it — then PageSpeed flags it as a critical issue. Override with loading="eager" on your hero/featured image explicitly.Steps 7 & 8: Assets and Fonts
JavaScript, CSS, and Fonts: Fix INP and Eliminate Render Blocking
JavaScript is the primary cause of INP failures on WordPress sites. Every plugin that loads scripts on pages where those scripts serve no function blocks the main thread and consumes INP budget. The fix is selective, not universal — audit which scripts actually run on each page type.
JavaScript: Defer Everything Except What’s Above the Fold
Add defer to all non-critical scripts. Use async only for truly independent scripts with no DOM dependencies. Never use either on scripts that must execute before the page renders (inline critical JS, WooCommerce cart listeners).
WP Rocket’s JavaScript deferral handles this automatically with a safe mode that excludes scripts by pattern. The manual approach: install Query Monitor, check which scripts load on which pages, and disable them per-page using plugin settings or filters.
Fonts: Stop Outsourcing Them to Google
Google Fonts adds: a DNS lookup, a TCP connection, a TLS handshake, and a blocking resource request — before the browser downloads the font itself. Self-hosting eliminates all of it.
CouponZania self-hosts Poppins in woff2 format in /wp-content/uploads/fonts/. Total setup time: 20 minutes. Always add font-display: swap so text renders in a fallback font immediately while the custom font loads. Without it, text is invisible until the font arrives — a guaranteed CLS and potential LCP failure.
Step 9: CDN
CDN: Add Last, Configure Correctly, and Get the Bypass Rules Right
A CDN delivers assets (images, CSS, JS, fonts) from geographically adjacent servers, eliminating the latency between your visitor and your origin server. Cloudflare’s free tier is sufficient for most WordPress sites.
Add it last because bypass rules need to be configured against a clean, correctly structured cache stack. If your Redis cache, page cache, and images aren’t clean yet, the CDN will cache broken states.
Cloudflare Bypass Rules for WordPress
Cloudflare’s page cache must bypass certain WordPress pages to avoid caching personalised or dynamic content. Without these rules, logged-in users see cached pages intended for anonymous visitors.
Required bypass conditions
- URL contains
/wp-admin/— bypass completely - URL contains
/wp-login.php— bypass completely - Cookie name contains
wordpress_logged_in— bypass page cache - Cookie name contains
woocommerce_— bypass page cache (cart, session) - URL contains
/cart/,/checkout/,/my-account/— bypass completely - Query string present — bypass (unless your caching plugin handles query string normalisation)
Measurement
How to Measure WordPress Performance Correctly
Most WordPress speed guides use PageSpeed Insights or GTmetrix scores as the success metric. Those are diagnostic tools, not ranking signals. Google ranks sites based on Core Web Vitals measured from real Chrome user data (CrUX) — not from lab simulations.
Core Web Vitals: What Actually Counts
| Metric | What It Measures | Good Threshold | Primary WordPress Cause of Failure |
|---|---|---|---|
| LCP — Largest Contentful Paint | How fast the main content loads | ≤ 2.5s | Slow TTFB (32% of WP sites fail this alone) |
| INP — Interaction to Next Paint | How fast the page responds to input | ≤ 200ms | Excessive JavaScript from plugins running on wrong pages |
| CLS — Cumulative Layout Shift | Visual stability — do elements jump? | ≤ 0.1 | Images without width/height; Google Fonts without font-display:swap |
Google evaluates Core Web Vitals at the 75th percentile of all CrUX field data. That means 75% of your real page loads must clear the threshold. A single slow network segment or underpowered device can fail you even if your site loads instantly for most users.
Who It’s For
Who Should Prioritise What
Redis object caching is non-negotiable. Cart and checkout pages bypass page cache, so every authenticated session hits the database. 8–16 dedicated PHP workers minimum. NVMe storage reduces checkout TTFB even when object caching is active. [INTERNAL LINK: WooCommerce speed optimization guide]
Server-level page cache delivers maximum impact since most traffic is anonymous. Prioritise TTFB (hosting + page cache) over everything else. Image optimisation (WebP + LCP preload) is the next biggest lever. Redis matters less unless you run heavy taxonomy filtering.
Logged-in users bypass all page caching. Redis object caching and dedicated PHP workers (16–30+) are your primary tools. Database cleanup is critical — membership plugins accumulate user meta rapidly. Consider dedicated Redis instances per site if user count exceeds 10,000.
Standardise on a VPS with SPanel or cPanel multi-account management. Run Redis per VPS (not per site) and configure WP_REDIS_PREFIX to isolate keys. Set WP_POST_REVISIONS = 3 in a must-use plugin deployed to all accounts to prevent database bloat over time.
Don’t spend $45/mo on a VPS yet. Shared hosting from Hostinger at $3.99/mo with WP Rocket and Cloudflare free tier handles this traffic comfortably. Revisit hosting when TTFB spikes correlate with traffic peaks — that’s the signal you’ve outgrown shared.
If you’re paying $80–120/mo at Kinsta or WP Engine and TTFB is still over 200ms, the bottleneck is usually plugin-heavy WordPress, not the host. Audit active plugins before migrating — you may fix performance without switching hosts.
FAQ
WordPress Speed Optimisation: Frequently Asked Questions
How do I speed up my WordPress website?
Work through the stack in order: hosting quality and PHP version first, then database cleanup, then Redis object caching, then page caching, then images, then JavaScript and fonts, then CDN last. Applying a CDN over an uncached server with a bloated wp_options table produces marginal gains. Each layer compounds on the one below it — sequence is the strategy.
What is the single most impactful WordPress optimisation?
Server-level page caching — delivering HTML before PHP loads — is the highest single-impact change available. It takes TTFB from 400–900ms to 35–106ms for anonymous visitors. The caveat: it only helps pages that can be cached (public, non-personalised content). For sites with heavy authenticated traffic (WooCommerce, membership), Redis object caching has comparable impact on those uncacheable requests.
Does WordPress hosting really matter that much?
More than any other factor. DebugHawk’s 2025 dataset across 5.7 million pageviews shows server-cached TTFB of 106ms versus 723ms uncached — a 7× difference set entirely by infrastructure. No plugin, image optimisation, or JavaScript deferral can overcome a shared server running on a 2013 CPU with 3 PHP workers and SATA storage. Hosting sets the ceiling; everything else operates within it.
What PHP version should I use for WordPress in 2026?
PHP 8.3 is the safe minimum — ~40% market share, full compatibility with WordPress 6.8+. PHP 8.1 reached end-of-life on 31 December 2025 and no longer receives security patches. PHP 8.4 is the recommended upgrade target if you can validate plugin compatibility in a staging environment first — it delivers a 21% WooCommerce throughput improvement and has active support through December 2028. CouponZania runs PHP 8.5 and recorded a 27% TTFB reduction compared to 8.3 on identical hardware.
What is Redis object caching and do I actually need it?
WordPress’s built-in object cache exists only for the duration of a single PHP request. Every page load re-queries the database from scratch. Redis persistent object caching stores query results in RAM between requests — so a site that runs 100 database queries per uncached request can drop to 2–5 on cache hits. You need it if you run WooCommerce, a membership platform, an LMS, or any site where a significant portion of traffic comes from logged-in users who bypass page cache. For anonymous-traffic-dominated content sites, page cache handles the heavy lifting and Redis is still useful but less critical.
What are Core Web Vitals and why do they affect WordPress specifically?
Core Web Vitals are three Google metrics: LCP (how fast main content loads), INP (how quickly the page responds to interaction), and CLS (visual stability). Google assesses them at the 75th percentile of real Chrome user data — not Lighthouse lab scores. WordPress fails LCP more than any other CMS because TTFB is the dominant LCP bottleneck and only 32% of WordPress sites pass Good TTFB. WordPress fails INP more than average because plugin JavaScript accumulates on pages where it serves no function, blocking the main thread on every page load.
How much does the wp_options table size actually matter?
Significantly, especially on sites with years of plugin history. Every uncached WordPress request queries wp_options for autoloaded options. When that data grows beyond 800 KB — which happens naturally through plugin installs and removals — each request carries that query weight. One documented case study reduced autoload query time by 82% and removed 2.58 MB of dead weight through a single cleanup operation. Check your autoload size via WP-CLI: wp option list --autoload=yes --format=table sorted by option value size. Anything over 100 KB per single option warrants investigation.
Is Cloudflare worth using for WordPress?
Yes, on every plan. Cloudflare’s free tier includes global CDN, basic DDoS protection, and image delivery optimisation — enough to eliminate geographic latency for static assets and reduce TTFB for international visitors by 30–50% on content that hits your origin. The critical configuration requirement: set correct bypass rules for logged-in users, WooCommerce cart/checkout, and admin pages. Without bypass rules, users receive stale personalised content from Cloudflare’s cache. Cloudflare Pro’s Automatic Platform Optimisation ($5/month) adds HTML-level edge caching that bypasses origin TTFB entirely for anonymous visitors.
How do I know which optimisation to do first?
Measure TTFB first using WebPageTest on a real mobile device profile from a location that represents your primary audience. TTFB above 600ms: your bottleneck is hosting or database — no frontend optimisation will move the needle. Between 300–600ms: caching is the missing layer. Below 300ms: the bottleneck is in the asset pipeline (images, JavaScript, fonts). Always fix from the server outward. A perfect PageSpeed score on a slow server is a diagnostic artefact, not a performance achievement.
