Are you tired of slow server responses on your WordPress website? If so, you may want to consider implementing object caching.
Object caching is a powerful technique that can greatly enhance your website’s performance by reducing database queries and speeding up page load times.
In this article, we’ll guide you through setting up Object Cache Pro and provide the steps to configure it properly.
Let’s get started!
Why Should You Use Object Cache Pro?
Object Cache Pro is a business-class Redis object cache backend for WordPress, providing reliable, highly optimized, and fully customizable caching for your website. It’s optimized for WooCommerce, Jetpack, and Yoast SEO – making it an ideal solution for businesses.
Object Cache Pro seamlessly integrates with WordPress and offers deep insights through its Site Health and Query Monitor integrations, as well as its Debug Bar panels. Object Cache Pro offers faster binary serialization support, LZF, LZ4, and ZSTD compression, asynchronous flushing, batch key prefetching, batcache, and cache analytics.
How to Configure Object Cache Pro for WordPress on RunCloud
Before installing the plugin, we recommend configuring the license key to avoid any hiccups during the installation. The easiest way to do this is by editing the wp-config.php file on the RunCloud dashboard.
Open the wp-config.php file in the file manager and add the following code below the line that says ‘Add any custom values between this line and the “stop editing” line’. Don’t forget to replace the license key in the text snippet.
After you have added the file, you can browse the list of configurations to change any other settings that you like. Once you are satisfied with it, you can save and close the file.
After adding the license token, verify that Redis is running on your server. To do this, go to the Services menu and check the status, making sure it says “Running” next to Redis. If it’s stopped, you can just start it.
How to Install Object Cache Pro for WordPress
Once you have configured the settings, you can install the plugin by uploading the zip file. Go to your WordPress dashboard and open the plugins tab. Click on “Add Plugins” and select “Upload Plugin”, then locate the zip file and install it.
After installation, click on the “Activate Plugin” to enable it.
Go to the plugins menu and click on “View Details” next to Object Cache Pro – a modal will appear with information about the plugin. Make sure it says “Latest Version Installed” on the bottom right. If you’re using an older version, simply update it.
After this, enable auto-updates to update the plugin automatically when a new version is released.
After installing the plugin, you can open its settings to check whether everything is working correctly. You should see “Status: Connected” in the widget on your Dashboard. If not, head to Tools > Site Health for more information.
After Action Report
Object Cache Pro can greatly enhance the performance and speed of your WordPress website by reducing the database load and server response time. The step-by-step guide provided in this article should help you successfully set up object caching on your WordPress website.
If you find this guide useful, you should also read:
If you are looking for an easy-to-use platform to manage your server and save time and resources, give your website the best chance to shine by signing up for RunCloud.
With RunCloud, you can easily deploy, manage, and monitor your server. Give RunCloud a try today and take your website’s performance to the next level.
If you have tested your WordPress site with PageSpeed Insights, you have probably seen the warning: “Reduce initial server response time.”
This warning relates to your site’s Time to First Byte (TTFB), which measures how quickly your server responds before the page begins loading. A slow TTFB can hurt Core Web Vitals, SEO performance, and user experience.
In most cases, the problem is not WordPress itself. It is the server stack underneath it. Slow PHP processing, missing server-side caching, unoptimized databases, and overloaded hosting environments can all significantly increase response times.
In this guide, we will show you how to reduce TTFB in WordPress using practical server-level optimizations you can manage directly from your RunCloud dashboard.
What TTFB Actually Measures (And What Google Wants to See)
Time to First Byte (TTFB) is one of the most important metrics of your website’s performance. It measures the time it takes a user’s browser to receive the first byte of data from your server after an HTTP request.
This includes the time taken for the following three steps:
DNS lookup time
Server processing time (executing PHP and database queries in WordPress)
Network latency (how quickly data travels)
According to Google’s official Core Web Vitals guidelines, a TTFB of under 800 milliseconds is considered “Good” and is the absolute baseline you must hit to pass their lab tests. However, WordPress performance experts aim for a TTFB of under 200 milliseconds.
How to measure TTFB correctly
Measuring TTFB accurately requires looking at both “lab data” (controlled tests) and “field data” (real-world user experiences).
PageSpeed Insights: This tool provides Chrome User Experience Report (CrUX) field data, showing the actual TTFB your users experience over 28 days, alongside real-time Lighthouse lab data.
GTmetrix: This is excellent for visualizing server response times with detailed Waterfall charts. It allows you to see exactly how much time is spent on DNS resolution versus the time the server spends waiting (the actual processing).
KeyCDN Performance Test: Physical distance of the server impacts network latency. This multi-location tool simultaneously checks your TTFB from 10+ global servers. If your TTFB is 150ms in New York but 1,200ms in Sydney, then it’s not good for your SEO.
Why Is Your WordPress Server Response Time Slow?
If your TTFB is failing Google’s benchmarks, the problem almost always lies under the hood of your WordPress configuration or your hosting environment. WordPress is a dynamic CMS, which means pages aren’t just sitting there ready to be served. Whenever a user visits your website, the pages are specially built for them. However, if you don’t optimize this process, it can feel slow.
Reason 1: Uncached PHP execution is hitting MySQL on every request
The number one killer of WordPress TTFB is a lack of page caching. When a visitor requests an uncached page, the server must spin up PHP workers, compile the theme and plugin code, query the MySQL database for the content, and stitch it all together into an HTML document.
This heavy server processing can take anywhere from 1,000ms to over 3,000ms on an average server.
By implementing a modern page caching solution, you can bypass this entire process and drop your page load times significantly.
Reason 2: Missing or misconfigured OPcache and object cache
Even with page caching, dynamic requests (such as WooCommerce checkouts, admin dashboards, or for logged-in users) still require server processing. This is where advanced caching layers save your TTFB.
PHP OPcache stores precompiled script bytecode in the server’s memory, eliminating the need for PHP to load and parse scripts on every request, which data shows can reduce PHP execution time by up to 70%.
Object caching (using Redis or Memcached) stores the actual results of complex MySQL database queries in memory. Without object caching, a complex WooCommerce page might trigger 150+ database queries; with Redis enabled, those repeated queries are served from RAM almost immediately, without any processing.
Reason 3: Shared hosting resource limits and server location distance
Shared hosting environments cram hundreds of websites onto a single server. This forces you to share limited CPU cores and RAM. When traffic spikes on a neighbor’s site, your server’s response time will increase, affecting your users.
Additionally, physical distance adds latency; data traveling from a server in London to a user in Tokyo naturally takes longer (often adding 200ms+ to TTFB). To fix this, it is a good idea to migrate to a dedicated cloud VPS managed by an optimized stack like RunCloud. Combining a high-performance VPS with a global CDN ensures you have dedicated CPU power and edge servers positioned within milliseconds of your visitors.
How to Reduce Server Response Time in WordPress
Optimizing your WordPress server response time is a multi-step process that requires addressing both software inefficiencies and hardware limitations. Follow the steps below to speed up your WordPress site:
Step 1: Enable full-page caching (FastCGI or Redis page cache)
The simplest way to reduce TTFB in WordPress is by enabling full-page caching. Normally, WordPress dynamically generates every page by executing PHP and querying the database, which is a highly resource-intensive process. Full-page caching bypasses this entirely by saving a page’s fully rendered HTML and serving it to subsequent visitors.
While most WordPress users rely on WordPress caching plugins, server-level caching delivers significantly better performance. RunCache supports FastCGI caching that intercepts the user’s request before it ever reaches WordPress. This eliminates PHP overhead and reduces server response times from hundreds of milliseconds to 20-50ms.
If you are running a blog, portfolio, or corporate site where content doesn’t change every minute, aggressive full-page caching is strongly recommended. You can set cache expiration times to automatically clear when a new post is published, ensuring visitors always get the fastest, most up-to-date version of your site.
The full-page caching can handle static visitors, but dynamic sites like WooCommerce stores, membership portals, and active forums must bypass the page cache to serve personalized content.
For these dynamic requests, WordPress has to query the database repeatedly, which quickly spikes server response times. Object caching stores the results of complex, frequently run database queries in RAM. When a user triggers a dynamic request, the object cache serves the stored data instantly, avoiding the need to query MySQL again.
Many site owners dread the intimidating SSH commands required to install and configure Redis on a server. To make things easier, RunCache includes a one-click Redis activation feature that automatically configures everything.
Step 3: Update to the latest PHP version
The PHP version running on your server plays a major role in your WordPress site’s performance. Each new major release of PHP comes with significant engine optimizations. For example, upgrading from PHP 7.4 to PHP 8.1 or 8.3 can drastically increase the number of requests your server can handle per second while simultaneously reducing memory consumption and TTFB.
Despite the obvious speed benefits, many users hesitate to upgrade because of the potential for fatal errors if a legacy theme or plugin is incompatible with the newer PHP code. Upgrading safely requires a staging environment and the ability to revert if things go wrong easily.
With RunCloud, you are given total control to manage this process without fear. The platform lets you switch your PHP version for each web app (e.g., upgrading from 7.4 to 8.3) directly from the dashboard with zero downtime. If you spot any errors, you can instantly switch back to the previous version to troubleshoot plugin conflicts.
Step 4: Optimize and clean your WordPress database
WordPress relies completely on its MySQL or MariaDB database to function. Over time, databases inevitably bloat with unnecessary data, including hundreds of post revisions, auto-drafts, trashed comments, expired transients, and orphaned settings left behind by deleted plugins. A bloated database means the server has to sift through massive, unindexed tables to find the right data, directly inflating your TTFB.
The most important area to monitor is the wp_options table, specifically the “autoloaded” rows. WordPress automatically loads this data on every single page view. If a poorly coded plugin leaves behind megabytes of useless autoloaded data, your server will choke on the processing. Performance experts strongly recommend auditing this table and keeping autoloaded data well under 1MB.
You can regularly optimize your database using lightweight plugins such as WP-Optimize or Advanced Database Cleaner. By regularly deleting orphaned data, optimizing database tables, and adding missing indexes, you can keep your server response times incredibly low.
Step 5: Replace wp-cron with a real cron job
WordPress uses a built-in scheduling system called wp-cron to handle background tasks like publishing scheduled posts, checking for theme updates, and running backup plugins. This wp-cron job is triggered when a user visits your website. On high-traffic sites, it can cause random, severe spikes in server response times.
To fix this, you should disable the default WordPress cron behavior by adding define(‘DISABLE_WP_CRON’, true); to your wp-config.php file. Once disabled, you must replace it with a real system-level cron job that pings the wp-cron.php file on a set schedule (e.g., every 5 to 15 minutes), completely decoupling background tasks from your users’ live page loads.
For many admins, setting up a system cron requires digging into Linux crontab configurations. However, if you need a real server cron instead of wp-cron, RunCloud provides a built-in cron job manager that instantly replaces WordPress cron with a single click.
Step 6: Use a CDN with full-page caching and a nearby Points of Presence
No matter how optimized your server is, the laws of physics dictate that data takes time to travel across the globe. If your hosting server is located in London, but your visitor is in Sydney, the geographic distance alone will introduce hundreds of milliseconds of network latency, resulting in a poor TTFB.
In this case, you must use a CDN to solve this physical bottleneck. While traditional CDNs are great for caching heavy assets like images and CSS files, they still require the initial HTML document to be generated by your origin server. To dramatically improve server response times globally, you need an advanced CDN setup that supports full-page Edge caching, such as Cloudflare’s Automatic Platform Optimization for WordPress.
By caching your pages’ HTML at the CDN’s Edge servers, your visitors can receive cached content from CDN edge locations closer to their region. This bypasses your origin server entirely for static page requests, delivering near-instantaneous server response times no matter where the user is located in the world.
Step 7: Enable HTTP/3
Using a newer, more advanced network protocol can significantly improve your website’s performance, particularly during the initial connection phase. In our recent post about HTTP/2 vs HTTP/3, we explained that Older protocols like HTTP/1.1 suffer from “head-of-line blocking”, which requires the browser to open multiple, sequential connections to download site assets. In comparison, newer HTTP protocols support multiplexing, which allows multiple files to be downloaded concurrently over a single connection.
In addition to the HTTP protocol, your SSL/TLS encryption standard matters. Secure connections require an SSL “handshake” before data can be transmitted. Older TLS 1.2 requires multiple round-trips between the browser and server to establish this secure connection. Upgrading to TLS 1.3 optimizes this by requiring only a single round-trip (and sometimes zero round-trips for returning visitors), shaving precious milliseconds off the TTFB.
RunCloud supports HTTP/3 without requiring manual server configuration, but if you are not using RunCloud yet, you can refer to our post on How to Enable HTTP/3 on NGINX to learn how to optimize your server.
Step 8: Audit and remove resource-heavy plugins
Plugins and themes can significantly impact WordPress performance. Every activated plugin injects its own PHP code that must be executed, and many inject their own CSS and JavaScript files that must be downloaded. Poorly coded, outdated, or resource-intensive plugins (such as page builders, analytics tools, or backup solutions) can hog server CPU and drastically slow TTFB for every visitor.
If you want to speed up your WordPress site, you should audit your plugin stack. You can use RunCloud’s built-in diagnostic tools, such as Slow Query Monitoring or Slow Script Monitoring, to profile your website’s backend.
Once you identify the worst offenders, replace them with lightweight alternatives or remove them entirely if the functionality isn’t strictly necessary. Offloading tasks like analytics to Google Analytics or backups to an external server panel (rather than using a WordPress plugin) drastically reduces your backend load.
Does Your WordPress Host Set the TTFB Ceiling?
No matter how aggressively you optimize your WordPress website, the underlying hardware and network infrastructure establish a hard limit on your maximum possible speed. You can compress your images, minify your CSS, and install premium caching plugins. Still, if your server takes a full second to process a basic request, your server response time will never meet Google’s Core Web Vitals standards. Simply put, you cannot out-optimize a slow, underpowered server.
Shared hosts place strict caps on your resource consumption. You are restricted by low PHP memory limits, throttled CPU cores, and strict I/O (Input/Output) usage limits. Premium performance plugins like WP Rocket or LiteSpeed Cache are excellent at reducing the number of dynamic requests. Still, they cannot magically generate more CPU power to process the requests that do get through. If your host throttles your account to a fraction of a single CPU core, your dynamic WooCommerce checkouts or admin dashboard will always suffer from a TTFB well over 800ms.
Finally, shared hosting completely locks you out of the server environment. You do not have root access to install powerful, modern server-side software. You cannot fine-tune PHP-FPM worker pools, install the latest enterprise-grade versions of Redis or Memcached, or tweak NGINX configurations to prioritize your specific traffic. You are permanently stuck with a generic, one-size-fits-all server stack that prioritizes hosting company profits over your website’s performance.
Why VPS with a server panel changes the equation
When you provision a server from modern cloud providers like DigitalOcean, Vultr, or Hetzner, you are allocated a dedicated, isolated CPU and RAM. Your server resources belong exclusively to your WordPress website.
Historically, the massive barrier to entry for using a VPS was the steep technical learning curve; you had to be a skilled Linux system administrator to manage security, databases, and web servers via the command line. This is exactly where a modern server control panel changes the equation entirely.
By pairing your cloud VPS with RunCloud, you can get unrestricted power of dedicated cloud hardware, along with a centralized management dashboard that makes server management as easy as traditional shared hosting.
RunCloud provides a hyper-optimized, enterprise-grade tech stack (NGINX, modern PHP, MariaDB, and Redis) designed specifically for maximum WordPress speed. It eliminates the need for SSH or terminal commands, letting you configure server-level caching, manage databases, and deploy one-click SSL certificates directly from the UI. This gives you control over your server environment, lets you bypass restrictive shared hosting limits, and permanently improves your WordPress server response times.
Want to improve your WordPress server response times without managing everything manually? Try RunCloud for yourself.
FAQs
What is a good TTFB for WordPress?
A good Time to First Byte (TTFB) for WordPress is typically under 200 milliseconds for optimal performance, though anything under 500 milliseconds is generally acceptable for SEO.
Does TTFB affect Google rankings?
Yes, TTFB directly affects your Google rankings because it acts as the critical foundation for Core Web Vitals metrics like Largest Contentful Paint (LCP). Slow server response time delays the entire page load, negatively impacting user experience, increasing bounce rates, and lowering your search engine visibility.
Why is my server response time high even with a caching plugin?
Your server response time might remain high if your website relies heavily on dynamic uncached requests, bloated plugins, or an unoptimized database. Even the best caching plugins cannot fix an underpowered server, which is why upgrading to a highly optimized hosting environment like RunCloud is essential for a permanent fix.
How do I reduce TTFB on shared hosting?
To reduce TTFB on shared hosting, you should configure an aggressive page caching plugin, optimize your database tables, and route your DNS through a Content Delivery Network (CDN). However, shared servers always have inherent resource limits, so migrating to a dedicated VPS managed by a platform like RunCloud will yield the best long-term performance.
Is your WordPress website loading quickly for local users, but frustratingly slow for visitors on the other side of the world?
In modern SEO, website speed is a key ranking factor. If your site takes too long to load, frustrated visitors will simply leave, costing you both traffic and sales.
In this beginner-friendly guide, we will break down exactly what edge caching means and why it drastically lowers your Time to First Byte (and what that is!).
You’ll learn how modern Content Delivery Networks cache full HTML pages and how to do it safely without breaking dynamic pages like WooCommerce.
Why Edge Caching Speeds Up WordPress
If your main WordPress hosting server is located in New York, a visitor from London will naturally experience a slower loading time than a visitor from Brooklyn. This happens because data has to physically travel across the ocean.
Edge caching solves this distance problem by ensuring your website loads instantly for everyone, no matter where they live.
What Edge Caching Means for WordPress
To understand edge caching, think of a massive central warehouse (your web host) and dozens of small, local retail stores (the “edge” servers).
Normally, whenever a user visits your website, their browser must request the website files directly from your main web host. Edge caching changes this by saving a copy of your WordPress site on a global network of servers (a Content Delivery Network, or CDN).
When someone visits your website, the server closest to them (the “edge”) serves it. Because the data travels a much shorter distance, your website appears on their screen in the blink of an eye.
How Caching HTML at the Edge Cuts TTFB for Global Visitors
TTFB stands for Time to First Byte. It’s a metric that measures exactly how long it takes a user’s browser to receive the very first data from your website. A lower TTFB means a faster website.
In the past, CDNs only saved “static” files like images or fonts. Your main server still had to do the heavy lifting of building the actual web page (the HTML) for every single visitor. Today, modern edge caching stores the entire, fully built HTML page directly on edge servers.
Here is why caching HTML is a game-changer for your SEO and speed:
Zero Database Queries: WordPress doesn’t have to waste time searching its database to build the page.
No PHP Processing: The server doesn’t have to run complex code. It just hands the pre-built page to the visitor.
Instant Delivery: Because the fully built page is waiting right next door to the user, your TTFB drops from over a second to just milliseconds.
While edge caching is incredibly powerful, it’s not a magic fix for everything. Because edge caching is designed to serve static copies of pages to the public, it automatically turns off in a few specific situations.
Edge caching will not speed up your site in these scenarios:
Logged-In Traffic: If a user is logged in to your site (e.g., a member or WordPress administrator), they need to see personalized, live content. The edge cache is bypassed, so they don’t see an old, cached version of the dashboard.
Uncached Dynamic Pages: E-commerce pages, such as WooCommerce Shopping Cart or Checkout pages, cannot be cached. If they were, shoppers might see other people’s items!
A Slow Backend Server: Edge caching hides a slow server from your public readers. However, anytime a visitor needs to do something dynamic (like submit a contact form, use a search bar, or process a payment), the request must go back to your original WordPress host. If your hosting provider is slow or your database is bloated, these actions will still feel slow.
Configuring edge caching for WordPress might sound highly technical, but the steps are quite simple. Here is the exact step-by-step process for implementing edge caching in WordPress.
Step 1: Pick your edge caching approach
Before changing any settings, you must decide how you want your CDN to interact with your WordPress host. There are two primary approaches:
Origin Page Cache + CDN (Traditional Method): Your WordPress server (the origin) generates and caches the HTML page locally. The CDN is used only to deliver static assets such as images, CSS, and JavaScript. While this is easy to set up, global visitors still have to wait for the HTML document to travel from your main server, keeping your Time to First Byte (TTFB) higher than ideal.
CDN HTML Cache (Full Page Edge Caching): The CDN stores a complete copy of the HTML document on its global edge servers. This is the preferred method for maximum speed worldwide. When a user requests a page, the edge server delivers the HTML instantly without ever contacting your WordPress host.
RunCache (All-in-one): For most users, Cloudflare Automatic Platform Optimization is the gold standard for CDN HTML caching. Cloudflare’s data shows that APO can improve TTFB by up to 72% globally. To get the absolute best results, we highly recommend using the RunCache Cloudflare Integration.
This integration seamlessly bridges your local WordPress cache with Cloudflare’s global edge network. It also ensures that whenever you update a post or change a product, the edge cache is purged and rebuilt instantly, giving you blazing-fast global speeds without the headache of showing outdated content.
Step 2: Enable Edge Caching on WordPress
For this tutorial, we will be using RunCache with Cloudflare’s global CDN to serve your entire website from edge locations closer to your visitors. Follow these steps to generate a secure API token and connect your site.
Step 2.1: Generate a Custom Cloudflare API Token
To maintain high security, we recommend creating a “Custom Token” with limited permissions rather than using your Global API Key.
In the left menu, click on Manage Account and select Account API tokens.
Click Create Token, then locate Create Custom Token at the bottom and click Get Started.
Token Name: Enter a name like RunCache – [Your Site Name].
Permissions: Add the following three permissions:
Zone: Cache Rules: Edit
Zone: Cache Purge: Purge
Zone: Zone: Read
Zone Resources: Under “Include,” select Specific zone and choose the domain you are currently configuring.
Click Continue to Summary, then Create Token.
After creating the token, copy it immediately and store it in a safe place – Cloudflare will not show it to you again.
Step 2.2: Ensure Your Domain is Proxied
Cloudflare caching only works if your traffic is flowing through their network.
In your Cloudflare Dashboard, go to the DNS tab for your domain.
Locate your A or CNAME records (usually for your root domain and the www subdomain).
Ensure the Proxy status toggle is set to Proxied (the cloud icon should be Orange). If it is “DNS Only” (Grey), Cloudflare’s cache will not be active.
Step 2.3: Enable Cloudflare in the RunCache Plugin
Now that you have your token and your DNS is ready, connect the plugin to Cloudflare.
Log in to your WordPress Admin Dashboard.
Navigate to RunCache in the sidebar and click on the Full Page Cache tab.
Enable Cloudflare from the list of cache providers.
Paste your newly created token into the API Token field.
Click Save Settings.
Once connected, RunCache will automatically communicate with Cloudflare to manage your cache, purge outdated content when you update posts, and ensure your visitors receive the fastest possible delivery via the Cloudflare edge network.
Step 2: Set the right cache headers for HTML and assets
Note: if you are using RunCache, all HTTP headers are handled intelligently by RunCache, and you don’t need to configure them manually.
CDNs don’t just guess what to cache – they follow strict instructions sent by your server, called HTTP Headers. To make edge caching work perfectly, you need to configure the following directives in Cache-Control headers correctly:
max-age: This tells the visitor’s local web browser how long to store the file. For edge-cached HTML, you usually want this set to a low value (e.g., max-age=3600) so browsers always request the latest version from the CDN.
s-maxage (Shared Max-Age): The “s” stands for shared cache (your CDN). This tells the edge server how long to hold onto the HTML file. A good rule for WordPress posts is s-maxage=604800 (7 days).
stale-while-revalidate: If an edge-cached page expires after 7 days, this directive tells the CDN to immediately serve the “stale” (expired) page to subsequent visitors so they don’t have to wait. In the background, the CDN quietly fetches the latest version from your WordPress server for future visitors. Setting stale-while-revalidate=86400 (24 hours) keeps your site feeling instantly fast 100% of the time.
Step 3: Add bypass rules for logged-in users, WooCommerce, and dynamic cookies
Note: if you are using RunCache, this step is handled automatically.
The biggest risk of edge caching is caching private or dynamic information by accident. If an edge server caches a page while you are logged in, it might show your WordPress admin bar to regular visitors. To prevent this, you must set up Bypass Rules (also known as Cache Exclusions) in your CDN dashboard or via your caching plugin.
If you’re using RunCache, you can manage these settings under the Rules tab.
Important Bypass Rules for WordPress:
Logged-in Users: Tell the CDN to completely bypass the cache if the browser contains the wordpress_logged_in_* cookie.
WooCommerce Cookies: Exclude caching for any user carrying the woocommerce_items_in_cart or wp_woocommerce_session_* cookies.
Dynamic URLs: Force the CDN to bypass the cache for specific URL paths, including:
/wp-admin/*
/cart/
/checkout/
/my-account/
By setting these rules, your public blog posts and landing pages will load from the edge instantly, while your secure, dynamic pages will safely load directly from your origin server.
Step 4: Verify edge caching is working using response headers and DevTools
Once you’ve configured your setup, you should test it to ensure the HTML is actually being served from the edge. You don’t need any fancy software to do this – just your web browser.
Open your website in an Incognito/Private window (to ensure you aren’t logged in).
Right-click on the page and select “Inspect” to open Developer Tools.
Click the “Network” tab, then refresh the page (press F5).
Then click the network request that you want to inspect.
Look at the “Response Headers” section on the right side.
In the response section, you need to look for the following response headers x-cache: HIT or x-runcache-status: HIT. If it says “MISS”, refresh the page one more time to prime the cache. Once it says “HIT”, your HTML is successfully loading from the edge.
Edge caching is the best strategy for delivering a lightning-fast WordPress experience to visitors worldwide. However, maximizing these speed benefits requires careful management to avoid common pitfalls.
Edge caching significantly reduces the daily workload on your origin server, but you still need a clean, conflict-free setup to keep your backend fast under heavy load. Running multiple overlapping caching layers often leads to messy system conflicts, which is why RunCloud built Runcache.
Runcache is a modern WordPress caching plugin that consolidates all caches (local page cache, Redis object cache, and edge network) into one streamlined layer.
And the best part is that RunCache works with any WordPress site on any host, not just those hosted on RunCloud.
Edge caching in WordPress stores a copy of your website on servers located very close to your visitors. These servers are part of a global Content Delivery Network (CDN) with hundreds of worldwide locations. When a user visits your site, the closest edge server delivers the content instead of your primary web host.
Does edge caching cache HTML or only static files?
Traditional CDNs only cache static files, such as images, CSS, and JavaScript. However, modern edge caching also caches your fully generated WordPress HTML pages. This advanced process is known as full-page edge caching. By caching HTML at the edge, your site can handle thousands of concurrent visitors without crashing. Only dynamic requests, such as form submissions, bypass the cache and reach your origin server.
What WooCommerce pages should never be cached?
You must never cache dynamic WooCommerce pages that contain personal user data. The three main pages to absolutely exclude from caching are the Cart, Checkout, and My Account pages. If you cache these pages, a customer might accidentally see another shopper’s private billing information.
Why do I still see old content after a purge?
You usually see old content because of local browser caching. You can easily fix this by performing a hard refresh using Ctrl+F5 on Windows or Cmd+Shift+R on a Mac. Another common reason is multiple active caching layers. You might have cleared your CDN edge cache, but your WordPress caching plugin or server object cache still holds the old data.
Should I use edge caching with a WordPress caching plugin?
Yes, you should absolutely use edge caching alongside a high-quality WordPress caching plugin. Edge caching excels at delivering your website files globally at lightning speeds. Meanwhile, a local caching plugin handles critical on-site performance optimizations.
If you want to build a completely custom frontend UI without giving up the powerful, built-in WordPress ecosystem, a headless setup is exactly what you need.
A headless WordPress architecture lets you use the WordPress CMS for content management while using the framework of your choice for the frontend. In this tutorial, we will use Astro, a modern framework built for speed that lets you fetch data from WordPress and render it as static HTML.
This combination provides the ultimate developer experience: you keep the familiar WordPress dashboard and plugin ecosystem while building a completely custom, high-performance frontend free from the limitations of legacy themes.
Benefits of Headless WordPress
Decoupling content creation and frontend development is a major benefit. Content teams use the familiar WordPress dashboard for posts and SEO without touching the Astro codebase, speeding up the content pipeline. Simultaneously, frontend developers focus purely on UX, features, and design optimization without interrupting content work.
Here are the primary advantages you can expect from this headless architecture:
Performance: Because Astro builds statically by default, it fetches your data from the WordPress REST API at build time and generates static HTML files, making your site incredibly fast.
Security: Your WordPress backend is not directly exposed through the frontend, reducing your attack surface while still allowing you to apply standard security controls where needed.
Flexibility: You have full developer control over the frontend code while still using WordPress as a robust CMS.
SEO: Static pages are easily crawled and indexed by search engines.
By the end of this tutorial, you will know exactly how to connect these two powerful tools. We will focus on producing static pages that are generated entirely at build time.
Once you are comfortable with this workflow, you can later customize how Astro behaves. For example, you can eventually change your category pages to dynamically fetch all pages via the API on the client side, rather than generating them during the build process.
Prerequisites
Before starting, you need a live WordPress site with the REST API accessible (at /wp-json/wp/v2/).
In this guide, we will not teach you how to install WordPress, as we have already covered this topic extensively in our previous blog posts. If you need help setting up your initial WordPress site, please refer to one of these guides:
Once your WordPress site is live on the internet, the built-in WordPress REST API will already be active. We just need to make sure it is properly formatted and accessible to Astro.
Set your Permalinks: The WordPress REST API relies on clean URLs to work properly.
Log in to your WordPress admin dashboard.
Navigate to Settings > Permalinks.
Select “Post name” (or any other clean URL structure).
Click Save Changes.
Verify the REST API is working
Open a new browser tab.
Visit your WordPress site’s API endpoint at https://[YOUR-WP-DOMAIN]/wp-json/wp/v2/ (replace the bracketed text with your actual domain name).
Check the screen for a JSON response containing the site data containing your posts. If you see this data, your headless backend is ready.
Set up Custom Post Types (Optional)
If you use Custom Post Types such as “Portfolios” or “Testimonials”, they are hidden from the REST API by default (unless a plugin actively enables show_in_rest). To use a CPT in your headless setup alongside standard posts and pages, you must configure them in your WordPress dashboard to allow REST API support.
Note: The upcoming examples will fetch data from a WordPress site whose content types have already been configured and exposed to the REST API.
Configure Authentication and Fetching Strategy (optional)
By default, the REST API is open to the public for reading content. If you are building a private application, you can configure your WordPress site to require authentication by following the official REST API Handbook.
Phase 2: Create WordPress Frontend with Astro
With your WordPress backend configured and its REST API ready to serve content, the next step is to build a fast frontend to display your posts. We’ll use Astro to fetch content from the API at build time, generating static HTML pages for maximum performance and security.
Step 1: Create a New Astro Project
With your WordPress site ready, create a new Astro project using the official starter template:
npm create astro@latest my-astro-wp
Select the following options when prompted:
Use A basic, helpful starter project: Yes
Install dependencies: Yes
Initialize git: Yes
Navigate to your project folder:
cd my-astro-wp
Step 2: Configure Environment Variables
Create a .env file in the project root to store your WordPress URL:
A note on pagination: The WordPress REST API limits the number of posts that can be returned in a single request. While per_page=20 works for small sites, larger sites will need pagination to fetch all posts.
The maximum value for per_page is typically 100. If you exceed this, the API will silently limit the results.
For production use, you should either:
Fetch multiple pages using the page parameter
Implement a loop to retrieve all posts during the build process
Step 4: Create Dynamic Post Pages
Create src/pages/posts/[slug].astro to handle individual post pages:
Visit http://localhost:4321 to see your headless WordPress blog in action. You should see all your WordPress posts displayed on the homepage, and clicking on any post will take you to its full article page.
Step 6: Build for Production
When ready to deploy, build your static site:
npm run build
The output will be in the dist/ folder, ready to deploy to any hosting provider, such as Netlify, GitHub Pages, or RunCloud.
Step 7: Keep Your Content in Sync with Rebuilds
The Astro project in the above example generates static pages at build time by default; any new or updated content published in WordPress will not appear on your live site immediately. To display the latest content, you must trigger a new build so Astro can fetch the fresh data from your REST API.
Depending on your publishing schedule and team size, you have a few ways to manage these rebuilds.
Option A: Manual Rebuilds (Simple)
If you only publish content occasionally, the simplest approach is to manually trigger a deployment from your RunCloud dashboard whenever you publish a new post.
Log in to your RunCloud dashboard.
Navigate to Atomic Deployment > your Astro project.
Click Force Deploy to force a manual rebuild.
RunCloud will run your deployment script, fetch the newest WordPress data, and update your live site using atomic deployment.
Option B: Automated API Triggers (Advanced)
By default, RunCloud automatically builds your site whenever new code changes are pushed to GitHub. However, publishing a post in WordPress does not push code to GitHub. To automate deployments based on content updates, you can use the RunCloud API to trigger a build programmatically.
You might be tempted to add a custom PHP function to your WordPress site that pings the RunCloud API every time a post is saved. However, if you have a team of writers constantly saving drafts and making simultaneous revisions, this can result in dozens of unnecessary deployments running back-to-back, which can consume server resources and cause conflicts.
Scheduled Deployments (Cron Jobs)
To avoid overwhelming your deployment pipeline, the best practice is to set up a cron job. Instead of deploying on every single save, you can configure a server cron job to ping the RunCloud deployment API on a predictable schedule.
Decide on a publishing schedule (for example, once every 12 hours or once a day at midnight).
Create a server-level cron job that sends a POST request to your RunCloud Webhook URL at that specific interval.
Instruct your content team that new posts will go live at those designated times.
Note: The need to constantly rebuild your application depends entirely on your Astro project architecture. The steps above apply to Static Site Generation (SSG), Astro’s default behavior that offers the best performance. However, if you configure Astro to use Server-Side Rendering (SSR), your application will dynamically fetch data from the WordPress API at runtime. In an SSR setup, any content changes saved in WordPress will appear on your frontend instantly, completely eliminating the need to rebuild your site after each post.
Phase 3: Deploy Astro Project to RunCloud
Now that your local Astro project is successfully fetching data from your headless WordPress setup, it is time to share it with the world.
In this phase, we will push your code to GitHub and set up a deployment pipeline on RunCloud.
We are going to configure an “atomic deployment.” The major benefit of this setup is that after you commit and push your code, it becomes available to users worldwide in often less than a minute. Furthermore, if a build fails for any reason, your old code will continue running smoothly with zero downtime.
Here is how to set up your professional deployment workflow.
Step 1: Push your Astro project to GitHub
First, we need to host your code in a repository so RunCloud can access it.
Open your web browser and log in to your GitHub account (or any supported Git provider).
Navigate to your dashboard, then click the New button to create a repository.
Give your repository a name.
Leave the option to add a README file unchecked. It is very important that the repository is completely empty.
Click Create repository.
GitHub will now show you a page with instructions for pushing an existing repository from the command line. Open your computer’s terminal, make sure you are in your Astro project folder, and copy and paste those specific commands to commit your code and push it to GitHub.
Step 2: Create a new RunCloud Web Application
Now, let’s tell RunCloud where to find your code.
Log in to your RunCloud dashboard.
Navigate to your server, then click Deploy New Web App.
Choose the option to install from a Git repository and select your Git provider.
Enter a suitable name for your application.
Locate the “Web Application Owner” section and uncheck the “Use existing system user” checkbox.
Enter a new name, such as astrowp.
Configure the domain name for your website. (You can use a test domain name for now and update it later manually or by using the RunCloud DNS manager.)
Enter the details for your new project into the “Repository name” and “Branch name” fields.
Copy the deployment key generated by RunCloud.
Open your GitHub repository and navigate to Settings > Deploy keys.
Click Add deploy key, paste the key provided by RunCloud, and save your changes.
Return to RunCloud and leave all other settings at their defaults.
Click Add Web Application.
Note: Steps for adding deployment keys can vary by provider. For exact steps, screenshots, and a detailed guide, check out your supported provider in the RunCloud documentation.
Step 3: Convert to Atomic Deployment and set Webhooks
Atomic deployments keep your site up while Astro builds your new pages.
Inside your RunCloud dashboard, click on Atomic Deployment in the left menu.
Follow the on-screen instructions to copy the provided webhook URL.
Go back to your GitHub repository, navigate to Settings > Webhooks, and click Add webhook.
Paste the RunCloud URL into the “Payload URL” field and save. This ensures that GitHub tells RunCloud to update your site whenever you push new code.
Step 4: Add your Environment Variables
Because your code is now on a live server, it needs your “.env” file to know where your WordPress API lives. RunCloud’s atomic deployment uses a shared folder so your environment variables persist across deployments.
In your RunCloud Web Application dashboard, navigate to Atomic Deployment > Your Project > Symlink.
Click Add New Symlink.
Set the “Symlink Type” to “Config”.
Enter “.env” in both the “Link From” and “Link To” fields.
Add your PUBLIC_WP_URL variable exactly as you did on your local machine.
Set a password for encryption. Remember this password if you want to edit this file again.
Click Save.
Step 5: Install NVM via SSH
RunCloud servers ship with a default version of Node.js, but Astro often requires a specific, modern LTS (Long-Term Support) version. We will install Node Version Manager to handle this safely.
Open your terminal and log in to your server via SSH using your new system user account (for example, “astrowp”). For step-by-step instructions and a detailed guide on connecting to your server via SSH, refer to the RunCloud documentation on How to Connect to Your Server via SSH.
Run the following command to download and install NVM:
Close your terminal completely and open a new SSH session so the system recognizes the new software.
Run nvm install –lts to install the latest long-term support version of Node.js.
Note: This is the only time you need to log in via SSH; all other processes will be handled automatically by the Git deployment pipeline.
Step 6: Create the Deployment Script
Now we will write the instructions that RunCloud follows every time it receives new code from GitHub.
In your RunCloud dashboard, navigate to Atomic Deployment > Your Project > Deployment Script.
Scroll down to the Activate Latest Release section and click “Add Script”.
Give this script a suitable name, and under the “When to Run This Script”, select “Before Activate latest release” from the dropdown menu.
Delete the default text and paste the following script:
# 1. Navigate to the current release directory
cd {RELEASEPATH}
# 2. Load NVM into the script environment
export NVM_DIR="/home/$USER/.nvm"[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
# 3. Tell the system to use the LTS version of Node.js
nvm use --lts
# 4. Install your Astro project dependencies
npm install
# 5. Build the static files using an absolute path to avoid version conflicts
npm run build
Note:By using the NVM in step 3, you ensure the system will not accidentally revert to RunCloud’s built-in Node version, preventing unexpected version conflicts.
Make sure to check the box next to “Run on Web Application” and then click Save to apply your new script.
After that, open the Settings tab for this atomic deployment project to configure the deployment configuration options.
Auto deploy on git push: Triggers a deployment every time you push code to the configured branch.
Install Composer dependencies: Ensure this is UNCHECKED. For this Astro project, we use npm install in the custom script, not Composer.
Install Dev Dependencies: Installs development-related PHP dependencies. (Not applicable to this Node.js/Astro project).
You can optionally configure notification channels such as Slack, Discord, Telegram, or Webhooks for both successful and failed deployments in the Notifications section of your RunCloud Web Application.
Step 7: Run your First Deployment
You are fully configured and ready to go.
Still inside the Atomic Deployment menu on RunCloud, locate the option to manually run a deployment on the top right.
Click Force Deploy.
Watch the deployment log. You will see RunCloud fetch your code, install dependencies, and build your Astro HTML files using your WordPress data.
Once the build passes, your headless website is officially live. Now, if you visit the URL configured in Step 2 for your frontend web application on RunCloud, you will be able to view your newly deployed, fast, headless WordPress site powered by Astro.
Phase 4: Advanced Steps (optional)
Now that your headless WordPress and Astro website is live, you can explore a few optional advanced steps to optimize your workflow, improve performance, and expand your site features.
Create a Staging Environment
To take complete advantage of the RunCloud environment, it is highly recommended to build a staging environment.
A staging environment is a private replica of your website where you can test WordPress plugins, Astro code updates, or new designs without breaking your live production site.
Because your backend (WordPress) and frontend (Astro) are separated, you will manage their staging environments separately. You can deploy two different branches of your Astro Git repository for this purpose.
Update the PUBLIC_WP_URL variable to match your new staging WordPress domain name.
Run your local development server to safely test your new WordPress plugins against your Astro frontend.
Create a cloud staging environment for your team:
Optionally, you can create a second project on the cloud so your entire team can test changes under load or for longer durations.
Open your GitHub repository and create a new branch named “staging”.
Log in to your RunCloud dashboard and navigate to Web Application.
Click Create Web App.
Follow the standard deployment steps, but enter “staging” into the “Branch name” field.
Assign a test domain name to this new web application and click Add Web Application.
Install RunCache
To make your headless website build even faster, you should pair it with an object caching plugin. Object caching saves the results of complex database queries and returns data instantly. This significantly speeds up your WordPress REST API responses.
RunCache is a free tool built for this exact purpose. While it is highly optimized for RunCloud servers, it can be used on any WordPress backend site.
Make More Pages and Endpoints
Your website is currently fetching blog posts, but you are only limited by your imagination. You can create custom views, pages, and features using the pre-built WordPress REST APIs. Astro can generate pages for any data that WordPress outputs.
Here are a few examples of what you can build next:
Author Pages: Fetch data from the /wp-json/wp/v2/users endpoint to create a directory of your blog authors and their biographies.
Category Pages: Fetch data from the /wp-json/wp/v2/categories endpoint to generate dynamic landing pages that group your posts by specific topics.
Custom Post Types: If you use a plugin to create a “Portfolio” or “Testimonials” post type, you can fetch them just like regular posts and design unique Astro layouts for them.
If you know a little PHP, you can even write your own WordPress plugins to create completely custom REST API endpoints tailored to your exact business needs.
To discover everything you can fetch and build, review the official WordPress API documentation:
Building a headless architecture with WordPress and Astro offers the best of both worlds: you get the unmatched content management experience of WordPress alongside Astro’s high-performance, developer-first environment.
While you are now free from the constraints of pre-built themes, a custom stack demands a fast server environment to handle deployments, security, and consistent uptime.
RunCloud bridges this gap by turning complex server administration into a streamlined, automated workflow. Once your site is deployed, RunCloud handles the “heavy lifting” (including server-level security, SSH access, system backups, and automated continuous deployments) so you can focus entirely on your work rather than managing your OS.
If you are looking for a professional-grade way to host and manage your headless infrastructure, RunCloud provides the stability and ease of use your project deserves.
Is your WordPress site failing Core Web Vitals checks despite having optimized images and minified code?
In some cases, slow typography loading can delay Largest Contentful Paint and cause visual instability known as Cumulative Layout Shift – but only when fonts are part of the critical rendering path.
In this guide, you will learn exactly how to preload fonts in WordPress to remove render-blocking delays and make your text appear instantly.
We will walk you through identifying the correct font files, adding the precise code snippets to your theme, and avoiding common mistakes that can actually slow your site down.
When This Guide Will Not Help
This guide will not improve your Core Web Vitals if your Largest Contentful Paint element is an image, background video, or slider. In those cases, font loading is not the bottleneck, and preloading fonts will have little or no measurable impact.
Before continuing, confirm that text (such as an H1 or hero heading) is identified as the LCP element in PageSpeed Insights or Lighthouse.
If fonts are not flagged under “Preload key requests”, this guide is not the correct fix.
Why Font Loading Causes CLS and LCP Issues in WordPress
Fonts are often the “heaviest” assets on a page after images, but browsers handle them differently than other files. In WordPress, themes frequently enqueue fonts via external requests (such as Google Fonts) or bury them deep within CSS files. This creates a “chain of delays” where the browser downloads the HTML, then the CSS, and only then realizes it needs to download a font file.
This delay exposes your site to slow server responses. If your hosting environment has a high Time to First Byte (TTFB), the browser waits even longer before starting the font download.
How Late Font Loading Triggers Layout Shift
Cumulative Layout Shift (CLS) occurs when elements on a page unexpectedly move. It happens in three parts:
When a browser loads a page, it may initially display a “system font” (like Arial) while the custom font is downloading. System fonts and custom fonts rarely have identical character widths.
Once the custom font finishes downloading, the browser swaps it in. If the new font is wider or taller, the text block expands, pushing buttons, images, and other content down the page. This movement penalizes your CLS score.
If your server is slow to deliver the font file due to poor caching or lack of compression, the user sees the system font for longer, making the eventual shift more noticeable and jarring.
Largest Contentful Paint (LCP) measures how long it takes for the main content to become visible. Font preloading only helps when that element is text, such as an H1 or hero heading. If the LCP element is an image or background asset, preloading fonts will not improve this metric.
This happens in the following manner:
Browsers are lazy by design; they won’t download a font until they build the “Render Tree” and confirm the font is actually used on the page. This means the browser parses HTML, downloads CSS, parses CSS, and then requests the font.
Many modern browsers will hide text completely until the font file is ready. If your H1 headline is waiting on a font, the screen stays blank. Since the H1 is often the LCP element, your LCP time increases by the exact amount of time it takes the font to download.
When Preloading Fonts Helps vs. When It Makes Things Worse
Preloading is a manual override that forces the browser to download the font immediately, skipping the “discovery chain.” However, it is a double-edged sword.
When it Helps: Preloading is excellent for the single primary font used in your LCP element (e.g., the H1 font). It ensures the text appears instantly, stabilizing LCP.
When it Hurts: If you preload too many files (e.g., body text, bold versions, icon fonts), you create network congestion. The browser has limited bandwidth; if it is busy downloading 5 font files, it cannot download your hero image or critical CSS. This actually worsens your page speed.
Preloading fonts is a powerful way to tell browsers to prioritize typography assets and improve Core Web Vitals. However, frontend optimizations like this work best when backed by a high-performance server environment.
Before you begin, remember that modifying site headers requires precise caching management. RunCloud’s server-level caching keeps your site fast, but you must clear the cache after applying these changes so visitors see the improvements immediately.
Step 1: Confirm Fonts Are The Problem in PageSpeed Insights and Lighthouse
Before adding code, verify that fonts are actually delaying your render time. Run a test on PageSpeed Insights or Google Lighthouse and look at the “Opportunities” section. If you see a warning labeled “Preload key requests,” expanding it will usually list specific font files that are delaying rendering.
If your fonts are not listed under “Preload key requests”, stop here. Font preloading will not improve your results; focus on server response time, image optimization, or render-blocking scripts instead.
At that point, ensure you are utilizing RunCloud’s optimized NGINX/Apache configurations.
RunCloud helps reduce Time to First Byte (TTFB) so that when the browser finally requests the font, the server delivers it instantly without lag.
Preloading changes the order in which files load, but it does not make the files smaller or the server faster.
Step 2: Identify the Exact Font File Used Above the Fold in DevTools
You should never preload every font on your site, only the ones used immediately on the screen (above the fold). To find these, open your website in Chrome, right-click, and select Inspect to open DevTools. Navigate to the Network tab, reload the page, and click the Font filter. Look for the font files that load first and are critical for your main headings or navigation.
Hover over the file name to see the full URL. You are specifically looking for .woff2 files, as these are the modern standard for compression and performance. Copy the URL of the font file you want to preload.
Step 3: Add The Preload Tag
Once you have the URL, you need to construct the HTML tag. The syntax for this HTML tag must be correct, or the browser will ignore it. The tag should look like this:
In the above tag, replace /fonts/your-font-file.woff2 with the path of the font that you noted down earlier. In addition to the path, make sure you include the crossorigin attribute. Even if the font is hosted on your own domain, the browser fetches it in anonymous mode. If you omit crossorigin, the browser may treat it as a different file request.
Step 4: Implement it in WordPress (theme header or wp_head hook)
There are two ways to add this tag to your WordPress site. The first method requires editing your header.php file in a child theme and pasting the line between the <head> tags.
The second approach is safer and more manageable. It requires adding a code snippet to your functions.php file, using the wp_head hook, to dynamically inject the link.
Here is the code snippet to add a tag to your site header using the functions.php file and the wp_head hook. You should add this code to your child theme’s functions.php file or use a code snippet plugin.
If you prefer not to use a plugin, you must access the functions.php file through your hosting provider, as the WordPress dashboard for Block Themes often does not allow this.
Log in to your RunCloud dashboard and open the File Manager.
Navigate to the folder wp-content/themes/your-active-theme-name/.
Locate the functions.php file, then click it to edit it.
Paste the code at the bottom of the file and save.
After saving the file, it will automatically be included in the HTML head of your WordPress site. You can verify it by opening the devtools and searching for the tag that you noted in the previous step.
Warning: After adding this code, you might notice that the changes appear when you are logged in but not when you inspect the site as a visitor. This happens because the server page cache is serving old HTML. Instead of hoping a browser cache clear fixes it, go to your RunCloud dashboard and purge the RunCloud server cache. This ensures the new preloading headers are served to all users immediately.
Step 5: If using Google Fonts, add Required Preconnect Hints
If you are not self-hosting fonts and rely on Google Fonts, true font preloading is not possible because the file URLs change dynamically.
In this case, preconnect is only a partial mitigation, not an equivalent replacement for preloading. It helps reduce connection setup time, but it does not remove third-party latency entirely.
While this helps, reliance on external servers introduces latency you cannot control. A better long-term strategy for performance is using RunCloud’s Redis full-page caching. By efficiently caching the rest of your database content on your own server, you give the browser more time to handle external third-party connections without affecting the user’s perceived load speed.
After implementing the above steps, watch out for “double downloads” in your Waterfall chart, where the font loads once as a preload and again via CSS. This is almost always a cross-origin mismatch.
Another common issue is CORS errors, where the font refuses to load entirely. This is frequently a server configuration issue regarding Access-Control-Allow-Origin headers.
If you see “Cache TTL” warnings, you can fix them by using the RunCache plugin for WordPress. It uses intelligent caching rules to speed up a WordPress website without requiring code changes. If purging cache to fix these errors causes load spikes, use RunCloud’s monitoring to correlate the purges with CPU pressure and adjust your settings accordingly.
Step 7: Re-test and Verify Improvements
Finally, return to PageSpeed Insights and WebPageTest. Look for the specific metrics: Largest Contentful Paint (LCP) should be faster, and Cumulative Layout Shift (CLS) should decrease because the text renders immediately rather than swapping fonts later.
If you still see inconsistent results where some visitors get fast speeds and others don’t, your edge caching or object caching might be fragmented.
This is where RunCache shines.
RunCache combines page, object, and edge caching into one dashboard with auto-purging logic. If you are tired of manually debugging caching layers,create a test site to experience RunCache and see how a unified caching strategy stabilizes your font loading and overall performance.
Troubleshooting: What if Preloading Doesn’t Improve CLS or LCP?
If you have implemented preloading tags but your Largest Contentful Paint and Cumulative Layout Shift scores haven’t changed, the issue is likely related to the total weight of your page or server response times.
Minimize Font Variants to Reduce File Size and Load Time
One of the most common reasons for slow LCP is loading too many font weights and styles (e.g., loading Light, Regular, Semi-Bold, Bold, and Extra Bold in both italics and normal). Each variation is a separate file that the browser must download, and preloading five or six files will clog your network bandwidth, blocking other critical assets like your logo or hero image.
Audit your typography: Check your CSS to see which weights are actually being used on the site.
Remove unused variants: If your specific theme only uses “Regular (400)” and “Bold (700),” remove all other weights from your request.
Update the preload tags: Ensure you preload only the single most important variant (usually the body text or main heading weight), not the entire family.
Implement ‘font-display’ Strategies to Prevent Layout Shifts
If your LCP is good but your CLS is poor, it is likely because the text is “swapping” and changing size after the font loads. You can control this behavior using the font-display property in your CSS @font-face declaration.
Use font-display: swap: This tells the browser to display a fallback system font immediately (improving LCP) and swap to your custom font once it downloads. This prevents the “invisible text” phenomenon.
Use font-display: optional: For maximum speed, this setting tells the browser to use the custom font only if it is already cached or loads instantly. If it takes too long, the browser sticks with the system font for that page view, resulting in zero layout shift.
Relying on Google Fonts or Adobe Fonts introduces external variables you cannot control, such as DNS lookups and connection latency to their servers. If their server is slow, your site is slow. Self-hosting the font files (uploading them to your own /wp-content/uploads/ folder) places the control back in your hands.
When you self-host, you benefit directly from RunCloud’s high-performance NGINX/Apache configurations. RunCloud ensures that static assets hosted on your server are served with optimized compression standards. By removing the external “round trip” to Google’s servers, you stabilize your LCP scores and ensure consistent site performance regardless of external network conditions.
Wrapping Up
While preloading fonts can improve perceived load speed when fonts are the bottleneck, it is only one part of a broader performance strategy.
If fonts are not delaying your render path, preloading will not change your Core Web Vitals scores.
RunCloud helps you manage server-level caching, including Redis and optimized NGINX configurations, ensuring your site loads instantly even if a user has a stale browser cache.
RunCache is a completely free, vendor-independent caching solution that works on any hosting provider. It lets you unify page, object, and edge caching without migrating your site or changing hosts.
If font preloading alone does not stabilize your Core Web Vitals, RunCache gives you a practical next step without committing to new infrastructure.
Should I preload fonts on every page or only key templates?
You should preload only the fonts used immediately “above the fold” across your entire site, such as your main navigation and heading fonts.
How many font files should I preload?
You should limit preloading to only one or two critical font files (typically in WOFF2 format) to avoid blocking the main thread and slowing down your Largest Contentful Paint. If you preload too many files, you risk congesting the network, which negates the benefits of preloading.
Why are fonts downloading twice after I add preload?
This usually occurs if the crossorigin attribute is missing from your preload code, causing the browser to treat the request as two separate assets.
Does preconnect help with Google Fonts?
Yes, using preconnect establishes an early network handshake with Google’s servers, significantly reducing the delay before the font file starts downloading. This works best when paired with RunCache Redis object caching, ensuring that while the external connection is being built, your database content is served without delay.
Should I self-host Google Fonts to improve Core Web Vitals?
Self-hosting is generally better for Core Web Vitals because it eliminates external DNS lookups and prevents layout shifts caused by slow third-party connections.
You publish an update, refresh the page, and nothing changes for your visitors.
If your WordPress changes are not showing after an update, then you are in the right place. In this cache troubleshooting guide, we will move past the basic advice of “have you tried turning it off and on again?” We will dive deep into why your logged-out view differs from what you see as an admin, and how to verify whether you are hitting the page cache or the Redis object cache.
This guide explains why those failures happen and shows you how to fix them in the correct order, without guessing.
How to Identify Which Cache Is Causing the Problem
Before clearing anything, use the quick checks below to identify which cache layer is actually blocking your update.
Changes are visible when logged in, but not logged out
Server-level page cache or CDN cache is serving stale HTML
Skip to Step 3 and Step 5
Content updates show, but CSS or layout does not
Browser, CDN, or server is caching static assets
Skip to “How to Handle Real-Time Updates with Stale Cached Assets”
Dynamic elements are wrong – cart counts, menus, widgets
Object cache or transients are stale
Skip to Step 4
Code changes to the theme or plugin are not reflected
PHP opcode cache or object cache issue
See “Clear PHP OPcache” and “Clear Object Cache”
Nothing updates anywhere
Multiple cache layers active
Follow all steps in order
Why WordPress Changes Are Not Showing After an Update
If your WordPress website is not showing changes after an update, caching is the most common cause.
Caching is the process of storing commonly accessed information on the server. To make your site load faster, browsers, plugins, servers, and CDNs show visitors a “snapshot” instead of rebuilding the page from scratch every time. This works well in most scenarios, but the problem arises when you update the site, and the cache keeps showing the old snapshot.
Most WordPress setups rely on disjointed tools, one plugin for page cache, another for object cache, and a separate dashboard for your CDN. This makes it hard to know which layer is holding onto the old data. With RunCache, server-level NGINX configuration and full-page caching are managed from a single dashboard, which reduces overlap between cache layers.
How to Fix WordPress Changes That Are Not Showing
When troubleshooting a website, we should start with the easiest fix (your browser) and work our way back to the server.
Step 1: Hard Refresh the Page and Verify
Before changing any settings, force your browser to reload the page. On Windows, press Ctrl + F5, or Cmd + Shift + R on Mac. Alternatively, you can open the URL in an Incognito/Private window.
If the Incognito window still shows the old version, the issue is not your browser and must be upstream.
If you are using a third-party caching plugin, clear its cache once before moving on. If this does not resolve the issue, do not keep purging here.
If you find yourself constantly modifying plugin settings, consider RunCache. It combines page, object, and edge caching into a single dashboard, which eliminates the need for complex plugins that don’t effectively communicate with your server.
Block themes – re-save global styles or theme settings
If these files are stale, server purging will have no effect because WordPress is still outputting old asset references.
Only proceed to server-level cache clearing after completing this step.
Step 3: Purge Server Page Cache (FastCGI / NGINX cache)
Even if you disable the caching plugin on your WordPress website, your server (NGINX/FastCGI) might still be holding a cached version of your HTML to speed up load times.
If you need to clear the NGINX FastCGI cache manually, delete the temporary files NGINX has created, then reload the service. Here is how to do it safely.
1. Locate the Cache Path
First, you need to find out where NGINX stores the cache. This is defined in your NGINX.conf or sites-available files under the directive fastcgi_cache_path.
Run this command to find the path:
sudo grep -r "fastcgi_cache_path" /etc/nginx/
Standard Install: Usually /var/cache/nginx or /var/run/nginx-cache.
RunCloud Server: located at /var/cache/nginx-rc/
In the above example, the cache is stored in a folder located at /var/cache/nginx-rc
Once you have the path, you can remove the cache files. Be extremely careful with the rm -rf command. A single mistake can delete critical system files.
Option A: Clear Everything (Root/Sudo)
Run the following command to clear all the cache created by NGINX:
sudo rm -rf /var/run/nginx-cache/*
Option B: Clear for a Specific Site (If separated by folder)
If your configuration separates caches by folder, then you can delete only a part of the cache without changing anything else. To do this, first run the following command to see a list of all the available folders in the Nginx cache:
sudo ls -lah /path/to/cache
In the above example, remember to replace /path/to/cache with the path identified in the previous step.
In the above example, we can see there are two different folders present on the server. You can delete the folder you want to clear the cache from. For example, if you want to clear the cache for runcloud-hub-fastcgi-app-auer, run the following command:
After deleting the files, you must reload the NGINX configuration to ensure it stops serving any lingering pointers to deleted files.
sudo systemctl reload nginx
# OR
sudo service nginx reload
Note: If you are using RunCloud, then you don’t need to touch the command line for this. Simply log in to your RunCloud Dashboard and navigate to the RunCloud Hub settings page for your web application. On this page, click the Purge button. This clears the cached HTML immediately, even without SSH access.
When parts of your site that update automatically (like a “Recent Posts” widget, shopping cart count, or user login status) remain stuck, the issue is likely within your Object Cache (typically Redis).
This caching layer stores the results of database queries in memory to speed up PHP execution, but it can sometimes hold onto stale data even after the content has changed. If you only clear your page cache (HTML), these database-driven elements will persist because the server continues to retrieve the old query results from memory instead of the database.
To resolve this via the command line, you will need to SSH into your server and interact with the Redis instance directly. You can run redis-cli flushall to remove all keys from the Redis database, forcing all applications using that instance to rebuild their cache from scratch.
However, if you only want to flush the cache for a particular WordPress site, navigate to your WordPress root directory and run the wp cache flush command. This will clear the object cache for that site specifically, without risking data loss for other applications sharing the same Redis instance.
RunCloud offers a much simpler solution that eliminates the need for SSH access or complex commands. You can manage Redis directly from the WordPress Dashboard by navigating to your RunCache settings and clicking the Clear Redis Object Cache button.
Object cache issues can also originate from WordPress transients stored in the database. Themes and plugins commonly use these for time-based data such as menus, pricing, or scheduled updates.
If clearing Redis does not resolve the issue, temporarily disable the object cache and reload the page to confirm whether a transient is responsible.
If the issue disappears, the problem is application logic, not caching.
Clear PHP OPcache After Code Changes
If theme or plugin code changes do not appear, PHP’s opcode cache may still be serving an older compiled version.
This is common after:
Theme file edits
Plugin updates
Custom PHP changes
On most servers, OPcache persists until PHP-FPM is reloaded.
On RunCloud servers, PHP-FPM reloads are handled automatically through the dashboard and do not require manual intervention.
If you are not using RunCloud, reload PHP-FPM to force OPcache to rebuild.
This step is not required for content edits but is critical for code-level changes.
Step 5: Purge CDN Cache
Since every Content Delivery Network (CDN) operates differently, the exact steps here will vary depending on whether you use Cloudflare, BunnyCDN, or Fastly.
However, the process is generally the same: log in to your CDN provider’s dashboard, navigate to the Cache or Purge section, and look for the option to clear the cache. You should always select Purge by URL (or “Custom Purge”) and enter the specific link that is stuck, rather than clearing the entire cache.
Warning: Avoid the “Purge Everything” or “Purge All” button if you can. This forces the origin server to rebuild the entire cache at once, which can cause CPU spikes and slow site-wide performance.
RunCache supports smart purging. It handles edge caching logic for you, ensuring that when you update content, the specific URL is automatically cleared from the CDN. This keeps your site fast and your server happy, without you ever needing to log in to a separate CDN dashboard.
Guessing wastes time. Confirm the cache status before making any changes.
Open your browser’s developer tools and reload the page with the Network tab visible. Click the main HTML request and inspect the response headers. Look for indicators such as:
X-Cache or X-RunCache – server page cache
cf-cache-status – Cloudflare edge cache
Status 304 – browser or intermediary cache revalidation
A cached response confirms that the issue is not WordPress itself but an upstream cache layer.
If the response is a fresh 200 but the content is still wrong, the issue lies inside WordPress logic or asset generation.
How to Handle Real-Time Updates with Stale Cached Assets
Sometimes, even after clearing every cache, the old design still appears. This usually happens not because the server is broken, but because the browser thinks it already has the correct file and refuses to ask for a new one. This is common with CSS (styles) and JS (functionality) files.
Step 1: Fix CSS/JS Cache Busting With File Versioning
The most reliable mechanism to force a browser to discard stale data and retrieve a fresh asset is not by manually renaming the file on the server, but by implementing versioning query strings (such as requesting style.css?ver=2.1), which instantly tells the browser that the underlying content has been modified. By appending this unique identifier to the resource URL, you can bypass local browser caches and CDN edges.
RunCloud allows you to control exactly how the server handles these dynamic parameters through its advanced NGINX caching rules:
Include cache based on matching query string: This setting lets you specify parameters that trigger the creation of a unique cache file, ensuring that visitors viewing ?currency=USD see a different cached version than those viewing ?currency=EUR without slowing the page.
Exclude cache based on matching query string: Conversely, this option lets you define specific query strings that will force the server to bypass the page cache entirely whenever they are present, ensuring that dynamic or sensitive URLs are always served live from the backend.
Step 2: Confirm the Browser is Requesting the New CSS/JS URL (Not a Cached URL)
Before you assume the server is broken, you need to determine if WordPress is actually telling the browser to fetch the new file. This diagnostic step determines whether the failure occurs within the WordPress application logic or at the server/network level.
Here is how you can do this:
Open a Fresh Session: Open your website in an Incognito (Chrome) or Private (Firefox/Safari) window to ensure your local browser history isn’t interfering with the test.
Access the Source Code: Right-click anywhere on the page background and select “View Page Source” (or press Ctrl + U on Windows / Cmd + Option + U on Mac). Do not use “Inspect Element” for this, as the DOM can sometimes differ from the raw source delivered by the server.
Locate the Specific File: Press Ctrl + F (or Cmd + F) to open the search bar. Type in the name of the file you modified, such as style.css, main.js, or the specific plugin stylesheet handle.
Analyze the Query String: Focus on the filename’s ending. You are looking for a version parameter, which typically looks like ?ver=1.2.3 or ?ver=time_stamp. Compare this number to the version you expect (e.g., if you just updated a plugin from version 2.0 to 2.1, the tag should read plugin.css?ver=2.1).
How to interpret the results and fix the issue:
Scenario A: The Version Number Has Not Changed
If the source code still shows the old version, the issue is not the server cache. The issue lies within WordPress itself. Your caching plugin might be serving a stale HTML page that contains the old link tags, or your theme might be “hardcoding” the version number instead of using the dynamic wp_enqueue_style function.
To fix this, you need to clear the cache of your WordPress page cache plugin first. If that fails, check your functions.php file to ensure you are updating the version number on your enqueued scripts.
Scenario B: The URL Has Changed, But the Style is Old
If the source code shows the new version, but the site still looks wrong, you are facing a “Hard Cache” issue on the server or CDN. The browser is requesting the new file, but an intermediate layer (such as NGINX or Cloudflare) has aggressively cached that path and is ignoring the query string. To fix this, you need to update the caching rules of your server and CDN.
Step 3: Stop Caching HTML Too Long (Cache-Control Header)
Incorrectly configuring the Cache-Control headers can create persistent caching issues. This HTTP header instructs the user’s browser: “Save this file locally and do not check the server for updates for X days.”
It is recommended to set a 1-year expiration for static assets (such as images and fonts) for optimal performance.
However, applying those same rules to your dynamic HTML pages is disastrous. If you accidentally instruct browsers to cache your homepage HTML for 30 days, no amount of server-side purging will resolve the issue. The visitor’s browser will simply stop requesting the page from your server entirely, relying on its local copy until the timer expires.
RunCloud’s NGINX templates come preconfigured with safe, industry-standard Cache-Control policies. Our stack is tuned to aggressively cache static assets for maximum speed while ensuring dynamic HTML remains fresh and revalidates frequently. This built-in logic prevents “configuration drift” and safeguards you from accidentally locking your users onto an obsolete version of your site.
Special Considerations for WordPress Multisite
WordPress Multisite environments often share Redis instances, PHP workers, and cache directories across multiple sites. Flushing object cache or Redis globally may affect other sites on the network.
If you are running Multisite, prefer site-specific cache purging through WordPress or RunCloud tools rather than command-line flushes.
Always confirm whether Redis databases or FastCGI cache folders are isolated per site before manually clearing them.
Wrapping Up
Debugging a WordPress site that refuses to update is one of the most tedious parts of development, but it doesn’t have to be a mystery. As we’ve discussed, the “invisible wall” preventing your changes from showing up is usually a result of multiple caching layers (browser, server, object, and CDN) working a little too well.
By following the workflow we outlined, you can stop guessing and start resolving issues systematically.
However, the best way to handle caching is to use a platform that simplifies it.
Managing NGINX rules, Redis instances, and CDN purges separately is a recipe for frustration. RunCloud RunCache solves this by integrating server-side page caching, object caching, and edge caching into a single, intuitive dashboard. You get the raw speed of a custom-tuned server with the ease of use of a simple plugin.
FAQs on WordPress Changes Not Showing After Update
Why do changes show when I’m logged in but not when I’m logged out?
This occurs because WordPress typically bypasses caching for logged-in users, while logged-out visitors are served a static HTML copy stored in the server’s page cache. To resolve this, you need to purge the server-level cache (FastCGI/RunCache) via the RunCloud dashboard, which clears the stale HTML without affecting your browser settings.
What cache should I clear first: browser, plugin, server, or CDN?
Always start by clearing the server-level cache, as this is the most common source of “stuck” content for dynamic sites. RunCloud lets you safely clear server and Redis object caches from a single dashboard, ensuring fresh content is served before you need to troubleshoot downstream layers like the CDN or the local browser cache.
Why is CSS not updating even after clearing the cache?
If CSS remains stale, the asset URL likely hasn’t changed, so browsers and CDNs continue serving the file based on previous expiration headers. While you should implement versioning for your assets, you can also check your RunCloud NGINX configuration to ensure headers are set correctly and purge the specific file path from the server.
Should I purge Cloudflare by URL or purge everything?
You should purge by URL whenever possible to avoid “cache rebuild” storms that can overwhelm your PHP/MySQL resources with sudden traffic spikes. RunCache simplifies this process by unifying edge and server caching, offering auto-purging capabilities that target specific content changes so you don’t have to wipe the entire cache.
How do I confirm a page is cached (HIT vs MISS)?
Inspect the HTTP response headers in your browser’s developer tools (Network tab) and look for headers such as X-Cache, X-RunCache, or cf-cache-status that indicate a HIT.
Can Cache-Control cause WordPress pages to stay stuck on an old version?
Yes, if Cache-Control headers set a long Time-To-Live (TTL) without validation, browsers will refuse to request new versions until the timer expires. RunCloud lets you standardize these rules at the NGINX layer, preventing config drift and ensuring users across all devices receive the latest updates.
There is a pervasive myth in the web development community: “WordPress is for novices. Real developers build custom apps.”
If you’re a developer who loves the clean workflow of Git, the component architecture of React, or the speed of static sites, you might look at WordPress with disdain. You might picture bloated plugins, spaghetti PHP code, and ongoing security concerns.
But if you ignore WordPress, you are ignoring a tool that powers over 60% of all websites using a CMS.
That market dominance isn’t an accident, and it isn’t just because it’s “easy” for beginners. It’s because WordPress solved the hardest problem in web development: Content Management.
As technical experts, we need to stop looking at WordPress as a “website builder” and start seeing it for what it truly is: a highly accessible, open-source, API-driven Content Database.
Whether you are using a sophisticated Roots.io stack with Git integration or going fully Headless, WordPress gives you complete freedom to manipulate the frontend while empowering your non-technical team.
However, the allure of “simplifying” the stack often leads developers to swing the pendulum too far in the opposite direction. In an effort to escape database management and PHP, many technical teams migrate to pure Static Site Generators (SSGs), relying solely on Markdown files.
While this initially feels like a developer’s utopia, offering total control and zero maintenance, it often turns into an operational nightmare for the rest of the organization.
Who This Architecture Is For
This approach is not aimed at hobby sites or solo blogs. It is designed for teams where developers and content editors have different needs.
If you are working with:
A marketing or content team that needs editorial autonomy
Developers who prefer modern JavaScript frameworks
A product or SaaS site where performance and security matter
Headless WordPress becomes a practical architectural choice rather than an experiment.
Why You Shouldn’t Use Static Site Generators
Many teams migrate to Static Site Generators (SSGs) for faster page load times and simpler hosting requirements, as Markdown files power them. On the surface, the idea sounds utopian as it is “Just a bunch of HTML files! No database! Easy deployment!“
Using a static file-based solution would mean you now need a PR for every update to a blog post. Let’s look at the reality of that workflow in a mid-sized company:
A marketing manager spots a typo in a blog post.
They can’t fix it. They have to ask a developer. The developer must create a branch, fix the typo, commit, push, open a Pull Request (PR), wait for the CI/CD, and then merge.
Your highly paid engineers are spending time fixing typos instead of shipping product.
We cannot expect marketing teams to learn Git or write perfectly formatted Markdown. We need to empower them with a CMS while retaining our own developer freedom.
Classic vs. Headless WordPress
For advanced development teams, the biggest friction point with WordPress isn’t the dashboard; it’s the templating engine.
You might already have a sophisticated corporate identity, a component library built in React, or a legacy styling setup that your team loves. Trying to shoehorn that existing frontend architecture into the standard WordPress PHP template hierarchy (single.php, header.php, the Loop) can feel like forcing a square peg into a round hole.
You often end up fighting the CMS rather than leveraging it, translating modern frontend patterns into WordPress-specific PHP themes. This adds complexity, slows iteration, and ties your frontend decisions to the WordPress render cycle.
This is where the distinction between Classic and Headless WordPress changes the game.
The Classic WordPress
In the Classic WordPress model, the backend (admin interface/database) and the frontend (what the user sees) are tightly coupled. They live on the same server and share the same codebase. When a user visits your site, WordPress dynamically generates the HTML based on your active theme.
For many projects, this is fine (even preferred). But for a technical team that wants to iterate on the frontend independently of the content engine, this monolithic structure can be a bottleneck.
Developers often try to add their modern components within a custom PHP theme or build complex custom plugins to manage data, aiming to make the WordPress editor feel more like a modern frontend experience.
While this can offer temporary relief, it often leads to a more complex, heavier application. You are still ultimately constrained by the limitations of the WordPress render cycle and the PHP environment, and you’re forced to maintain a custom codebase that may be difficult for new developers to onboard to.
The Headless Revolution
Headless WordPress decouples this relationship entirely. Think of it as performing surgery: you keep the “Body” (the robust content management, user roles, and database) because WordPress does that better than almost anyone else. However, you sever the “Head” (the frontend display layer).
In this architecture, WordPress becomes a data source. It sits quietly in the background, waiting for instructions. You then use the WordPress REST API or WPGraphQL to fetch that content and inject it into a completely separate frontend application.
This shift from “Website Builder” to “Content API” unlocks three massive advantages for technical teams:
You are no longer bound by PHP. You can build your frontend in React, Vue, Svelte, Angular, Next.js, Gatsby, or even plain HTML/JS. If your team is already proficient in React, they can build the site using the tools they know and love, simply treating WordPress as a JSON endpoint. You stop hacking themes and start building applications.
In a classic setup, your content is trapped in the website’s HTML. In a headless setup, your content is portable data. You can publish a case study once in WordPress and have it instantly available via API to your marketing website, your native iOS/Android app, an internal intranet dashboard, and even a smartwatch interface simultaneously.
Because your frontend is physically separated from your backend (often hosted on entirely different servers or CDNs), your database is not directly exposed to user traffic. Even if your frontend site experiences a large traffic spike or an attack, your WordPress installation is far less exposed, since it is not directly serving public traffic and can be further protected behind the API layer.
If you want to combine the SEO benefits of static sites with the dynamic power of a CMS, pairing WordPress with a framework like Gatsby is a good choice.
Gatsby pulls your data from WordPress via GraphQL, generates static HTML at build time, and deploys it to the edge. This results in extremely fast page loads that are difficult for traditional PHP-rendered sites to match at scale. If you want to learn more about this architecture, then we recommend reading why Gatsby chose headless WordPress for its blog.
How To Set Up Headless WordPress with Gatsby
For this guide, we will use RunCloud to manage our infrastructure. RunCloud offers an excellent balance of server control and ease of use. While a production workflow usually involves local development pushed to a Git repository with CI/CD pipelines (Atomic Deployment), we will perform this setup directly on the server to demonstrate the architecture clearly.
Here is how you connect the dots between your WordPress backend and your Gatsby frontend.
Step 1: Set Up the WordPress Backend (The “Body”)
First, we need the source of truth for your content.
Create the App: Log in to your RunCloud dashboard and create a new Web Application. This will host your WordPress installation.
Install WordPress: Use the RunCloud “One-Click Install” feature (or your preferred installation method) to get WordPress running.
Important Note: For this WordPress Backend step, do not use your final, public-facing domain (e.g., www.example.com). Use a subdomain dedicated to the backend, such as backend.example.com or internal.example.com. Your final domain will be assigned to the Gatsby Frontend application in Step 2.
Configure Permalinks: This is a crucial step! Go to Settings > Permalinks in your WordPress dashboard. Set it to “Post name” or a custom structure. The default “Plain” setting (?p=123) can sometimes cause issues with GraphQL routing.
Install Essential Plugins: Go to Plugins > Add New and install the following two plugins:
WPGraphQL: This exposes your WordPress data via a GraphQL API.
WPGatsby: This optimizes communication between WordPress and Gatsby, handling tasks such as cache invalidation and delta updates.
Your marketing team will log in here to publish content. To them, it appears to be a standard WordPress site.
Step 2: Prepare the Frontend Environment
Now, we need a place for the Gatsby application to live.
Create a New Web App: Back in RunCloud, create a second Web Application.
Select Stack: Choose an Empty Web App stack (since Gatsby is a React-based framework running on Node).
Domain: Assign your public-facing domain to this application (e.g., www.example.com).
In a production environment, you would develop locally, push to Git, and use RunCloud’s Git deployment feature. For this tutorial, we will initialize the app directly on the server to give you an immediate overview of the file structure.
Step 3: Install Gatsby via SSH
Connect to your server via SSH using the system user attached to your Frontend Web Application. Before moving ahead, ensure the Gatsby CLI is installed globally on the server by running the following command:
npm install -g gatsby-cli
Navigate to the root directory of your new application (/home/username/webapps/appname). In this folder, you will need to delete the default index.html file by running the following command.
rm index.html
Once the directory is empty, run the following command to generate the site skeleton using a WordPress-specific starter:
gatsby new . https://github.com/gatsbyjs/gatsby-starter-wordpress-blog
This command pulls down a pre-configured Gatsby site optimized for fetching data from WordPress.
You have now initialized the core files for your Gatsby frontend in this folder. You can update the React components, styling, and general structure as you like.
Step 4: Connect Frontend to Backend
You need to tell Gatsby where your WordPress API lives. Open the configuration file using your preferred editor (nano or vim):
nano gatsby-config.js
Locate the configuration options for gatsby-source-wordpress and update the url setting to point to your backend’s GraphQL endpoint. After editing, it will look like this:
Save and exit the file by pressing Ctrl + O, Enter, and Ctrl + X.
For a deep dive into advanced configuration, schema customization, and troubleshooting, we highly recommend reading the official documentation: Gatsby Source WordPress Documentation
Step 5: Build and Deploy
Now, we will need to generate the static files that will be displayed on the internet.
Handle SSL (Optional): If your backend is on a staging server using a self-signed certificate, Gatsby might refuse to connect. You can bypass this temporarily by running:
export NODE_TLS_REJECT_UNAUTHORIZED=0
Build the Site: Run the build commands to fetch the data from WordPress and generate the HTML/CSS/JS files in your Gatsby environment:
gatsby clean gatsby build
Update Public Path: By default, RunCloud points the web server to the root of your application. However, Gatsby compiles your static site into a folder named “public”. Therefore, we will update the public path of the Gatsby web application in the RunCloud dashboard. Please note that we don’t need to modify this setting for the WordPress backend.
Go to your RunCloud Dashboard > Web Application > Settings.
Change the Public Path to /public.
Save settings by clicking the Update Stack button.
After updating the public path, your website will be immediately accessible on the internet.
With your Headless WordPress architecture now fully deployed, here are a few things to consider for ongoing maintenance and optimization:
Continuous Deployment for Content Changes
Currently, every time your marketing team publishes a new post or makes an edit in the WordPress dashboard (Step 1), you still need to manually run gatsby build on your server (Step 5) to see the changes on the live site. To automate this process, you need to implement Webhooks and CI/CD.
Configure Webhooks: The WPGatsby plugin you installed in Step 1 can be configured to automatically send a signal (a webhook) to an external service every time content is saved or published.
Trigger a Build: Set up your deployment pipeline (e.g., using RunCloud’s Git deployment feature or a dedicated service like Netlify/Vercel) to listen for this webhook. When the signal is received, the pipeline automatically triggers a new Gatsby build, fetching only the updated content (delta changes) and deploying the new static files.
Benefit: This creates a zero-touch content workflow, where the content team publishes content, and the live site updates automatically in minutes, without requiring developer intervention.
Scaling and Optimization
Since your frontend is static, hosting it on a global Content Delivery Network (CDN) will drastically reduce load times for international users. Services like Cloudflare or AWS CloudFront can be easily configured to sit in front of your Gatsby application.
Maintaining Security
The separation of your backend and frontend inherently improves security, but proactive measures are still essential for the WordPress installation:
Regular Updates: Ensure your WordPress core, themes (even those unused for templating), and all plugins (especially WPGraphQL and WPGatsby) are kept up to date. We strongly recommend using Patchstack for this step, as it secures your website from vulnerabilities by using RapidMitigate technology, which protects your website even if the plugin developers haven’t released an update.
Firewall Rules: Use the firewall features to restrict access to the WordPress dashboard (e.g., only allow specific IP addresses or VPN ranges) since it’s an internal-only application.
This decentralized approach gives you the ultimate control to tune and scale each component independently, ensuring both performance and editorial freedom.
WordPress is a Power-Up, Not a Compromise
For too long, developers have viewed WordPress as a “necessary evil”, something you tolerate because the client demanded it. It’s time to retire that mindset.
When you pair WordPress with a modern architecture, such as a Headless setup, it stops being a compromise and becomes a massive workflow accelerator. It solves the content problem instantly, allowing your team to focus on what actually moves the needle: building high-performance user interfaces, optimizing conversion funnels, and shipping code.
You get the stability of a CMS that powers over 60% of the web, combined with the bleeding-edge speed of a React frontend.
You Don’t Need to Be a Linux Expert
Perhaps the biggest hesitation remaining is the infrastructure. “If I go Headless, don’t I need to manage multiple servers? Do I need to be a Linux sysadmin to keep this secure?”
This is where RunCloud bridges the gap.
Powerful architecture shouldn’t require you to spend your time managing low-level server configuration. RunCloud does all the heavy lifting for you. We automate the provisioning, security patching, and server management so you can deploy a WordPress backend and a Node.js frontend in minutes, not days.
But unlike “Managed Hosting” that locks you in a black box, RunCloud respects your expertise.
We handle the tedious tasks: SSL installation, backups, and service monitoring occur automatically.
You retain control: You maintain full root access to your server. Want to tweak a custom NGINX config? Go ahead. Need to install a specific server-side library? You have the keys.
You get the convenience of a managed dashboard with the raw power of a VPS.
Ready to Build Your Headless Stack?
Don’t let infrastructure headaches stop you from building the best version of your website. Join developers and agencies using RunCloud to deploy faster, secure their infrastructure, and scale with confidence.
Is Headless WordPress too complex for a small development team?
While the initial setup requires more architecture than a standard install, it often simplifies long-term maintenance by separating the frontend code from the content database. This separation enables your developers to work with modern frameworks, such as React, without compromising the content editing experience for the marketing team.
Does using a Headless architecture hurt my SEO rankings?
On the contrary, a Headless setup often improves SEO by using Static Site Generation (SSG) via tools like Gatsby or Next.js. These frameworks generate pre-rendered HTML that loads instantly and achieves high Core Web Vitals scores, which are a major ranking factor for Google.
Do I need to be a Linux system administrator to use RunCloud?
No, RunCloud is designed to eliminate the need for command-line expertise by providing a visual dashboard for server management. We handle the heavy lifting (such as configuring NGINX, firewalls, and SSL certificates) so you can focus on your application, while still providing root access if you ever need it.
Why use RunCloud instead of traditional “Managed WordPress” hosting?
Traditional managed hosting often locks you into a “black box” environment where you cannot change server configurations or install custom software. RunCloud offers the best of both worlds: the automated convenience of managed hosting, combined with the flexibility and cost-effectiveness of owning your own VPS infrastructure.
Will my existing WordPress plugins be compatible with a Headless setup?
Backend plugins that manage structured data, such as Advanced Custom Fields (ACF), work well by exposing their data via the API. SEO plugins, such as Yoast, can still be used as data sources but require explicit integration in the frontend to render metadata correctly. However, frontend-specific plugins, such as visual page builders or sliders, will not work, as you are replacing the WordPress theme layer with your own custom frontend code.
Is WordPress secure enough to be used as an enterprise backend?
WordPress is highly secure when maintained correctly, and a Headless architecture makes it even more secure by decoupling the database from the user-facing site. Since the frontend consists of static files or a separate Node.js app, your actual WordPress database remains hidden from direct public traffic and potential attacks.
Why not just use a pure file-based CMS instead of WordPress?
File-based systems (using Markdown) often struggle to scale when multiple non-technical users need to edit content simultaneously. WordPress provides a robust, multi-user database with granular permissions and a user-friendly interface that file-based systems simply cannot match for team collaboration.
Does running two separate applications (Frontend and Backend) double my hosting costs?
Not necessarily, because the WordPress backend in a Headless setup requires fewer resources since it isn’t serving public traffic. Furthermore, using RunCloud allows you to host multiple web applications (both your WordPress backend and Node.js frontend) on a single server, keeping your infrastructure costs efficient.
What happens if my server goes down? Does RunCloud fix it?
RunCloud provides tools to monitor your server’s health and automatically restart services (such as NGINX or PHP) if they crash. While we manage the software layer and configuration to prevent downtime, you retain full control and ownership of your relationship with your cloud infrastructure provider (like AWS, UpCloud, or DigitalOcean).
A slow WordPress site isn’t just frustrating – it drives visitors away and hurts your SEO.
In most cases, the cause is simple: too many HTTP requests.
Every script, image, and font file your browser fetches adds another delay, which hurts your WordPress website performance and Core Web Vitals
This guide shows you how to cut those requests at the source – and make your site load noticeably faster. You’ll learn how to configure your WordPress site to:
Dequeue unnecessary assets properly
Combine images using CSS sprites
Disable WordPress emojis.
Let’s get started!
What are HTTP Requests on a WordPress Website?
Let’s try to understand this with the help of an example. You can think of your web browser as a personal shopper with a list of things it needs to build the webpage you want to see.
An HTTP request is a single trip your shopper (the browser) makes to a server to pick up one item on that list. For a WordPress site, this list is long and includes trips to different “stores” (servers):
Your Server: It needs to get the logo, background images, the main text content, and theme files (CSS for styling, JavaScript for interactivity).
Google’s Servers: It might need to fetch custom fonts (Google Fonts).
Facebook’s Servers: It might need to grab a tracking pixel or a “Like” button script.
Other Servers: It may need to get a video from YouTube or an icon from a font library.
Each one of these “trips” is an individual HTTP request. A modern website can easily make 50-100 of these requests just to load a single page, and a slow or disorganized shopping trip makes for a frustratingly slow website.
Benefits of Making Fewer HTTP Requests in WordPress
Reducing the number of “shopping trips” your browser has to make provides immediate and significant benefits.
Firstly, it dramatically improves page load speed and creates a much better experience for your visitors.
Secondly, this speed boost directly impacts your SEO and Core Web Vitals, as search engines like Google reward fast, responsive websites with better rankings.
Finally, fewer requests mean less work for your server. This allows it to handle more traffic without slowing down, which is important for growing your business.
The best way to see all these HTTP requests is with a waterfall analysis, which you can find in tools like GTmetrix or your browser’s developer tools (F12 > Network). A waterfall chart gives you a visual breakdown of every single file your browser requests to build the page. It looks like a cascading series of bars, showing:
What was requested: Every image, script, and stylesheet.
Where it came from: Your server, a CDN, or an external site.
How long it took: Long bars are performance bottlenecks.
By analyzing this chart, you can pinpoint exactly what is slowing your site down: too many files, large images, or slow external services.
How Reducing HTTP Requests Works on a WordPress Site
As we already discussed, every element on a WordPress site, each image, stylesheet (CSS file), script (JavaScript file), and font, requires the browser to make a separate request to a server to download it. And if a web browser has to perform more tasks, it would take longer.
If we reduce the number of requests, we can speed up the entire loading process:
Remove or Replace Heavy Plugins and Themes That Load Excessive Assets
The single biggest source of unnecessary HTTP requests in WordPress comes from poorly coded or feature-heavy plugins and themes. A complex theme or a “do-it-all” plugin might load dozens of its own CSS and JavaScript files on every single page, even if the feature isn’t being used.
Auditing and replacing these heavy assets with lightweight, modular alternatives is a high-impact first step toward a leaner, faster website.
Use a tool like GTmetrix or open the “Network” tab in your browser’s DevTools to run a waterfall analysis. Look for clusters of .css and .js files being loaded from specific plugin or theme directories (/wp-content/plugins/plugin-name/).
For each heavy plugin, ask: “Is this functionality critical?” and “Can it be achieved more simply?” For example, a heavy social sharing plugin might be replaceable with simple HTML links or a lighter plugin.
Research plugins and themes that are specifically marketed as “lightweight,” “performant,” or “modular.” Look for options that allow you to disable features (and their associated assets) that you are not using.
Deactivate the heavy plugin on a staging site, install the lighter alternative, and run the waterfall analysis again to measure the reduction in requests.
Load Assets Conditionally and Dequeue Unused CSS/JS Per Page
Many plugins load their assets globally. For example, the scripts for your contact form are also loading on your homepage and blog posts, where there is no form. Conditional loading is the practice of preventing assets from loading on pages where they are not needed.
This approach ensures that each page only loads the absolute minimum number of files required for it to function correctly. If you prefer a code-based approach, you can use WordPress functions wp_dequeue_style() and wp_dequeue_script() in your theme’s functions.php file. Wrap them in conditional tags to target specific pages.
Example: To disable a contact form script everywhere except the “Contact” page:
add_action( 'wp_enqueue_scripts', 'my_dequeue_scripts', 100 );
function my_dequeue_scripts() {
if ( ! is_page( 'contact' ) ) {
wp_dequeue_script( 'contact-form-7' ); // Use the script's handle
wp_dequeue_style( 'contact-form-7' ); // Use the style's handle
}
}
Minification removes unnecessary characters (like whitespace and comments) from code to reduce file size. And after minification, you can bundle multiple CSS or JavaScript files into a single file to reduce the number of HTTP requests.
However, this strategy is most effective for older HTTP/1.1 servers. Modern servers using HTTP/2 and HTTP/3 can handle many small requests in parallel very efficiently, so combining files can sometimes be counterproductive.
For HTTP/1.1: Use a caching plugin like WP Rocket or W3 Total Cache to enable minification and file combination for both CSS and JS.
For HTTP/2 and HTTP/3: You can enable minification, but be cautious with the combination setting. It’s often faster to load multiple small, minified files that are deferred or loaded asynchronously than one large, combined file that could block rendering. You should test your load times with the combination enabled and disabled to see what works best for your specific site.
Optimize Fonts (Self-Host, Subset, Preload, Use font-display: swap)
Web fonts, especially those loaded from external services, can introduce multiple HTTP requests and DNS lookups that slow down rendering. By taking full control of your fonts, you can eliminate these external requests and ensure they are delivered as efficiently as possible from your own optimized server.
Host Fonts Locally: Use a plugin like OMGF (Optimize My Google Fonts) to automatically find the Google Fonts your site uses, download them, and serve them directly from your own server. This eliminates the external request to fonts.googleapis.com.
Subset Your Fonts: Subsetting removes all the characters and weights you don’t use from a font file, and this drastically reduces its size. Many local font generation tools offer this as an option.
Use font-display: swap;: Add this CSS property to your @font-face declaration. It tells the browser to display a fallback system font immediately while the custom font is loading. This prevents a blank text flash (Flash of Invisible Text).
Preload Critical Fonts: Identify the one or two font files needed to render the “above-the-fold” content. Preload them by adding a <link> tag to your site’s <head> to tell the browser to download them with high priority.
Every third-party service you add, analytics, heatmaps, live chat widgets, ad networks, and social media feeds, adds external HTTP requests. These requests can significantly slow down your site because your server has no control over the speed and reliability of the third-party server. Minimizing or locally hosting these scripts where possible is key to reclaiming performance.
Use your waterfall chart to identify all requests going to domains that are not your own.
For each external service, decide if its value outweighs its performance cost. Can you remove it?
For services like Google Analytics, plugins like Perfmatters allow you to host the analytics.js script locally on your server. This gives you full caching control and eliminates an external DNS lookup. A server managed by RunCloud will serve this local file with incredible speed.
For non-critical scripts like chat widgets or ad scripts, use a script manager to delay their loading until a user interacts with the page (e.g., scrolls or clicks).
Optimize Images (Next-Gen Formats, Lazy Loading, SVG Sprites for Icons)
Images are often the heaviest assets on a page, and a site with many unoptimized images will generate a huge number of HTTP requests. Modern image optimization techniques focus on reducing file size, deferring loads, and combining multiple small image requests into one.
Convert your JPEGs and PNGs to modern formats like WebP or AVIF. These formats offer superior compression and smaller file sizes with no visible quality loss. We recommend reading this excellent article on Best WordPress Image Optimization Plugins by Patchstack to learn more about image compression.
Lazy loading prevents images and iframes that are “below the fold” from loading until the user scrolls them into view. This drastically reduces the number of initial HTTP requests. This is a native feature in WordPress 5.5+, but many WordPress plugins also offer more advanced control.
For simple graphics, logos, and icons, you should use Scalable Vector Graphics (SVGs). They are incredibly small in file size and scale perfectly without losing quality.
Use Resource Hints (preload, preconnect, dns-prefetch, fetchpriority) for Critical Files
Resource hints are instructions that you can place in your site’s HTML <head> to give the browser a “heads-up” about resources it will need soon. This allows the browser to start fetching critical files or establishing connections early, which can shave valuable milliseconds off your load time by optimizing the request-and-response cycle.
dns-prefetch: You can use this for third-party domains your site needs to connect to, like Google Fonts or Google Analytics. It tells the browser to perform the DNS lookup in the background.
preconnect: This goes a step further than dns-prefetch. It completes the DNS lookup, TCP handshake, and TLS negotiation. Use this for critical third-party domains from which you know the site will fetch resources.
preload: Use this for a specific, critical file on your own server (like a font file or CSS file) that is needed for the initial render but might be discovered late by the browser.
Enable a CDN and HTTP/3 with QUIC to Reduce Latency on Many Small Requests
A Content Delivery Network (CDN) reduces latency by storing copies of your assets on servers around the world and serving them from the location physically closest to the user. Enabling CDN can dramatically speed up your website.
HTTP/3 is the latest web protocol, built on QUIC, and designed to be faster and more reliable, especially on mobile or unstable networks. It excels at handling many small, parallel requests without the “head-of-line blocking” that could slow down HTTP/2.
Integrate a CDN: Sign up for a CDN service like Cloudflare, BunnyCDN, or KeyCDN. For a service like BunnyCDN, you’ll get a unique URL to which to point your assets. Alternatively, you can also use RunCloud’s built-in feature to enable Cloudflare Proxy with the flip of a switch.
Enable HTTP/3: This is a server-level configuration and might require you to modify server settings via CLI. However, with RunCloud, enabling HTTP/3 is as simple as flipping a switch in your web application’s settings. This ensures your site is using the most advanced protocol for handling requests efficiently.
Disable WordPress Emojis, Embeds, and Other Non-Essential Features That Trigger Requests
By default, WordPress loads a small JavaScript file (wp-emoji-release.min.js) on every single page to convert text emoticons into emojis. It also loads scripts for oEmbeds, which allow you to embed content from sites like YouTube easily. If you don’t use these features, they are just extra, unnecessary HTTP requests.
The easiest way to get rid of them is to use a plugin like Perfmatters or Asset CleanUp, which have simple toggles to disable emojis, embeds, and other WordPress core features like XML-RPC and jQuery Migrate.
Use Code Snippets: If you prefer not to use a plugin, you can add the following code to your theme’s functions.php file to disable these features manually:
Create SVG Sprite Sheets or Icon Sets to Consolidate Multiple Small Assets
If your site uses multiple small icons (e.g., for social media links, user interface elements), each one is often a separate HTTP request. An SVG sprite sheet is a technique where you combine all of your SVG icons into a single, large SVG file. You can then display any individual icon from that single file using a simple CSS reference, consolidating dozens of potential requests into just one.
Instructions:
Gather Your SVGs: Collect all the individual SVG icons you use on your site.
Generate a Sprite Sheet: Use an online tool like SVGOMG or a build tool like Webpack to combine your SVGs into a single sprite file. The tool will give you one .svg file and the corresponding HTML/CSS markup.
Load the Sprite: You can either include the SVG sprite inline in your theme’s header.php or footer.php file (best for performance) or load it via JavaScript.
Display an Icon: Use an SVG use element to reference the ID of the icon you want to display from the sprite.
Implement Critical CSS and Defer/Async Non-Critical JavaScript
By default, CSS and JavaScript files are “render-blocking”, which means that the browser has to download and parse them completely before it can display the page. Critical CSS is a technique where you extract the absolute minimum CSS needed to style the “above-the-fold” content and place it inline in the HTML <head>.
You then load the rest of the stylesheet asynchronously. Similarly, you should defer or async non-critical JavaScript so it doesn’t block the initial page paint.
Use a tool like the Critical Path CSS Generator or a service like criticalcss.com to generate the critical CSS for your key pages (homepage, blog post, etc.).
Implement in WordPress:
Plugin Method: Caching plugins like WP Rocket have a feature that automatically generates and applies critical CSS for you with a single click. This is the recommended and easiest method.
Manual Method: If doing it manually, you would inline the generated CSS in a <style> tag in your site’s <head>.
Load Full CSS Asynchronously: Load the main stylesheet using a non-blocking method.
Defer/Async JavaScript: Go through your enqueued scripts and add the defer or async attribute. The defer tag executes the script after the document has been parsed, while async executes it as soon as it’s downloaded. For most scripts, defer is the safer option. You can do this with plugins or programmatically using the script_loader_tag filter in WordPress.
Wrapping Up: Why You Should Reduce HTTP Requests for Your WordPress Websites
In this post, we’ve covered a wide array of powerful techniques to reduce the number of web requests for your website. While any single change provides a small benefit, their combined effect can turn a slow, bloated website into a streamlined, fast, and efficient website.
But why is this so critical? Reducing HTTP requests isn’t just about numbers. Some people even go as far as to create a website which is less than 14KB in size to reduce the number of web requests.
Finally, a leaner site puts less strain on your server, making it more stable and capable of handling more traffic without slowing down.
These optimizations only go so far without a fast, reliable server.
RunCloud takes care of the heavy lifting – managing caching, HTTP/3, and CDN configuration – so your site can load faster and handle more visitors effortlessly.
Use a caching or asset optimization plugin like WP Rocket or Perfmatters to minify and combine CSS and JavaScript files into fewer, smaller files.
What plugins help cut down external requests?
Plugins like Perfmatters and Asset CleanUp are excellent for selectively disabling scripts on pages where they aren’t needed, which stops requests to external services. Additionally, by managing your server with RunCloud, you ensure the remaining essential requests are handled with maximum efficiency by a finely-tuned stack.
Should I combine or defer JavaScript files?
On modern servers, you should prioritize deferring JavaScript over combining it, as this prevents scripts from blocking page rendering.
How do CDNs improve page speed?
A Content Delivery Network (CDN) stores copies of your assets on servers worldwide, delivering them to users from the closest geographical location to reduce latency. Integrating a CDN like Cloudflare is straightforward with RunCloud, which simplifies the server configuration needed to work in perfect sync for maximum global speed.
What tools show how many requests a site makes?
Web performance tools like GTmetrix, Pingdom, and the Network tab in Google Chrome’s DevTools provide a detailed waterfall chart of every HTTP request. Use these to measure the direct performance gains from both your on-site optimizations and the efficiency of a server managed by RunCloud.
How do I optimize icons with SVG sprites?
You can combine multiple SVG icons into a single “sprite” file, which is loaded just once and referenced with CSS. This drastically reduces individual HTTP requests.
Is HTTP/2 or HTTP/3 better for performance?
HTTP/3 is the newer, faster protocol, but HTTP/2 is still a massive improvement over its predecessor and has wider support. RunCloud takes the complexity out of server management, allowing you to easily switch from HTTP/2 to HTTP/3 with just a few clicks to ensure your site is using the best technology.
Unused WordPress plugins can slow your site down and weaken your security, even when they’re deactivated.
This guide explains why they cause problems and shows you how to safely remove them.
Why You Should Remove Unused Plugins
Leaving inactive or unused plugins on your WordPress installation is a significant liability. Here’s why you should clean them up:
Enhanced Security
Inactive plugins still leave their files on your server. If a vulnerability is found, attackers can target those files directly. Removing unused plugins closes those entry points.
Improved Performance
Many plugins add files and database entries that remain after deactivation. They increase backup sizes and sometimes still load assets. Removing them reduces bloat and can help your site load faster.
Simplified Maintenance
A shorter list of plugins makes your life easier. It simplifies troubleshooting when issues arise and reduces the time you spend on updates. With fewer plugins to manage, you can focus on the ones that are essential for your site’s functionality.
Reduced Bloat
Over time, unused plugins can contribute to database bloat. Even after deactivation, some plugins leave behind tables and rows in your database. This unnecessary data can slow down your database queries and negatively impact your overall site performance.
Why Deactivation Isn’t Enough
Many WordPress site owners believe that if a plugin is deactivated, it’s harmless. While it’s true that deactivating a plugin prevents it from actively running on your site, this is only a half-measure that creates a false sense of security. The reality is that the plugin’s files are still sitting on your server.
Think of it this way: even if the plugin isn’t “on,” its code is still present and accessible. Hackers and malicious bots are constantly scanning the web, not just for active vulnerabilities, but for the mere presence of specific plugin files known to have security flaws. If a known vulnerability exists in a deactivated plugin, its files can still be scanned and exploited. Removing the plugin avoids this risk entirely.
How to Identify and Remove Unused Plugins
Follow these simple steps to clean up your WordPress installation.
Step 1: Identify Unused Plugins
Go to Plugins in the WordPress dashboard and review each installed plugin. For each one, check whether you still use it and whether the functionality is truly needed.
What function does this plugin perform?
Is this functionality still necessary for my website?
Is there a better way to achieve this without a plugin?
When was the last time I used this plugin’s features?
If you’re unsure about a plugin, try deactivating it and checking your website to see if any issues arise. This can help you determine if it’s safe to remove.
Once you’ve identified a plugin that is no longer needed, click “Deactivate” under its name. This will disable the plugin, but its files will still be on your server.
Step 3: Delete the Plugin
After deactivating the plugin, a “Delete” option will appear. Click on it. WordPress will ask for confirmation before permanently removing the plugin’s files. Confirm the deletion.
By following these steps, you are actively enhancing your website’s security and performance. A clean WordPress installation is a crucial component of a well-maintained website, enabling you to use your hosting resources to their fullest potential.
As we’ve seen, keeping your WordPress site free of unused plugins is a powerful step towards a faster, more secure, and easier-to-manage website. By removing unnecessary plugins, you can eliminate security vulnerabilities and reduce performance-draining code.
Cleaning up unused plugins is easier when you can test changes safely and securely.
RunCloud provides a simple and reliable way to manage WordPress sites, featuring one-click staging, automated backups, and performance-focused server setups.
You can test plugin removals in staging, confirm everything works, and deploy changes with confidence.
Take the risk out of managing WordPress. Use RunCloud to create a staging site, test plugin changes safely, and run your site on a fast, secure server setup.
Frequently Asked Questions About Removing Unused Plugins
How does removing unused plugins help my website’s SEO?
Search engines like Google favor websites that are fast and secure. By removing unused plugins, you reduce code bloat and potential security vulnerabilities, which improves your site’s loading speed and overall health. This sends positive signals to search engines that can boost your rankings.
Is deactivating a plugin the same as deleting it?
No, they are not the same. Deactivating a plugin simply turns it off, but its files remain on your server, posing a potential security risk. Deleting the plugin completely removes its files, which is the recommended practice for better security and performance.
How often should I perform a plugin cleanup?
It’s a good practice to review your installed plugins every three to six months. This regular audit helps ensure that you are only keeping the plugins that are necessary, up to date, and beneficial for your site’s functionality.
Could I break my site by deleting a plugin?
Yes, if the plugin provides essential functionality. To avoid this, always deactivate the plugin first and thoroughly test your website’s key features to ensure everything still works as expected before proceeding with deletion.
What if I need a deleted plugin in the future?
If you think you might need a plugin again, you can simply reinstall it from the WordPress plugin repository. However, for plugins you are certain you won’t use, complete removal is the best way to keep your site lean and secure.
Enabling caching on a WooCommerce store is an important but delicate process that balances performance with functionality.
Unlike a static blog, an e-commerce site is highly dynamic, managing user-specific data like shopping carts, account information, and personalized content.
A misconfigured cache can lead to serious issues, such as showing one customer’s cart to another or displaying incorrect order information, ultimately destroying user trust and costing sales.
When we configure the cache, our goal is to aggressively cache static content and anonymous user page views while intelligently bypassing the cache for dynamic elements and logged-in users.
This guide will walk you through how to properly implement caching for your WooCommerce store. By following these principles, you can significantly reduce server load, decrease page load times, and provide a faster, more reliable shopping experience for your customers without compromising the dynamic nature of your e-commerce operations.
Let’s get started!
What is WooCommerce Caching?
Caching instructs your server to build a web page only once and then save a static, ready-to-go copy. Instead of repeating the resource-heavy process of running code and fetching data from the database for every visitor, the server can instantly deliver this pre-made version, dramatically accelerating your site’s performance.
The most important part of building a good cache is being smart about what to save. Modern CMSs such as WooCommerce intelligently create copies of static pages that are the same for everyone, like product pages or category listings, to make them load incredibly quickly. At the same time, it knows to exclude dynamic pages unique to each user, such as the shopping cart and checkout pages, ensuring that customers only see their items and personal information.
The primary benefit of caching your WooCommerce store is a massive boost in website speed. Faster-loading pages create a significantly better user experience, which keeps shoppers from getting frustrated and leaving your site. This leads directly to more sales and a lower cart abandonment rate.
In addition to improving conversions, the website speed is an important factor for search engine optimization (SEO). Google and other search engines favor fast websites, so a well-cached store will rank higher in search results, bringing you more free, organic traffic.
Finally, caching reduces the workload on your server and allows your store to handle many more visitors at once without slowing down or crashing, which is essential for surviving busy shopping seasons like Black Friday.
Step-by-Step Guide: How to Set Up WooCommerce Caching
Follow the steps below to develop an effective caching strategy for your WooCommerce site.
1. Choosing the Right Caching Solution
The first (and arguably the most important) decision is selecting the appropriate caching technology for your hosting environment. Your options fall into two broad categories: plugin-based caching and server-level caching.
Caching plugins such as WP Rocket or W3 Total Cache are user-friendly options that allow you to edit and manage your caching settings from the WordPress application. Although convenient, this adds processing overhead, as WordPress must still load to serve a cached page.
You should consider using server-level caching, a superior approach to achieve maximum performance. Modern caching plugins, such as LiteSpeed’s LSCache, operate at the web server level, before WordPress is even loaded. This allows them to serve cached pages with minimal latency and resource consumption, resulting in significantly faster response times.
However, if you are using RunCloud, you can consider using the RunCloud Hub, which provides a good balance between the two by offering both native NGINX FastCGI cache (RunCache) and Redis Page caching. For RunCloud users, RunCloud Hub is the most efficient approach as it is specifically optimized for the server stack.
Once you have chosen your caching solution, the next step is installation and initial configuration. If using a plugin like WP Rocket, installation is straightforward via the WordPress dashboard. After activation, most modern caching plugins automatically detect that WooCommerce is active and apply a default set of safe exclusion rules. These presets typically prevent the caching of critical pages like Cart, Checkout, and My Account, providing a solid baseline to prevent major functional issues.
If you are using RunCloud, you don’t need to leave your RunCloud dashboard, as you can enable RunCloud Hub within your RunCloud dashboard and your WordPress web application.
During the initial setup, you should avoid enabling every performance feature simultaneously. Start by enabling the core page caching feature for logged-out users. After confirming the site still functions correctly, you can incrementally enable other options like CSS or JavaScript minification, testing thoroughly after each change.
The single most important rule of WooCommerce caching is never to cache pages that display user-specific information publicly.
Caching these pages would result in one user’s private data being served to other visitors, a catastrophic failure for any online store.
The primary pages that must be excluded from any page caching mechanism are the Cart, Checkout, and My Account pages. By default, their URL slugs are /cart/, /checkout/, and /my-account/, respectively.
To prevent this scenario at a technical level, the server sends specific instructions to browsers and intermediate caches through HTTP headers. This is handled by using the Cache-Control: private header. This HTTP header specifies that the response is intended for a single user’s browser and must not be stored by any shared cache, such as a CDN or a server-level cache like RunCache. This is often accompanied by a no-store directive for maximum security.
Almost all caching plugins and server-level configurations provide a setting labeled “Never Cache URLs” or “Exclude URLs”. You must add the relative paths for these private pages in this section. It is best practice to use wildcards to ensure all sub-pages are also excluded from the cache. For example, adding /my-account/* will ensure that account-specific pages, such as order history and address management, are excluded from the cache.
4. Excluding WooCommerce Sessions and Cookies from Cache
In addition to excluding specific URLs, you must be aware of WooCommerce cookies. WooCommerce uses cookies to track user sessions and cart contents, even for guests who are not logged in.
For example, the woocommerce_cart_hash cookie tracks changes to the shopping cart, and the wp_woocommerce_session_ cookie contains a unique code corresponding to the customer’s session data in the database. When these cookies are present in a visitor’s browser, it signifies that the user has an active, personalized session.
To ensure your website works as expected, you must configure your caching system to bypass the cache entirely whenever these specific WooCommerce cookies are detected. This ensures that any user who has added an item to their cart or is logged in receives a fresh, non-cached page from the server. It also ensures that dynamic elements like the mini-cart and user-specific pricing function correctly.
Minification is removing unnecessary characters (like whitespace and comments) from CSS and JavaScript files and combining them to reduce the number of server requests.
The minification process can improve load times and cause unexpected errors and conflicts, particularly with the complex JavaScript used by WooCommerce and its many extensions. When enabling minification, proceed cautiously and test rigorously after each change is recommended.
We recommend enabling CSS minification first and thoroughly testing the site’s layout and design. Once satisfied, you can enable JavaScript minification and test all interactive elements, paying close attention to the add-to-cart functionality, image galleries on product pages, and checkout. If you encounter a broken feature, you can configure your caching plugin to exclude specific CSS or JavaScript files from minification.
6. Integrating CDN and Edge Caching with WooCommerce
A Content Delivery Network (CDN) is a set of computers that can distribute your static assets, such as images, CSS, and JavaScript, across a worldwide network of servers. This drastically reduces latency for international visitors by serving files from a location geographically closer to them.
Using a CDN to serve static assets is highly recommended for WooCommerce. Most caching plugins provide a dedicated section for rewriting asset URLs to point to the CDN. Modern caching solutions, such as Cloudflare or Bunny.net Accelerator, take this a step further by caching the full HTML of your pages at the CDN level.
The edge cache must be configured to respect the same exclusion rules as your on-site cache, bypassing the cache for dynamic URLs (cart, checkout) and any visitor with a WooCommerce session cookie.
This ensures the CDN edge doesn’t serve a stale, generic page to an active shopper. Proper integration ensures your origin server sends the correct Cache-Control headers, which a well-configured caching plugin will manage for you.
7. Setting Up Object Caching (Redis/Memcached) for WooCommerce
Caching web pages allows you to store and serve fully rendered HTML pages, but that’s not the only thing you can cache. Loading a web page launches several repetitive and complex database queries that take a long time to execute. An object cache, such as Redis or Memcached, can store the results of these database queries in the server’s fast-access RAM.
This Object caching functionality can provide a massive performance boost for a query-heavy application such as WooCommerce, which constantly checks product stock, sale prices, user permissions, and session data. This is especially useful for logged-in users and during backend operations where page caching is not active.
Enabling object caching can be tricky if you do it manually, but using RunCloud Hub allows you to configure it with a single click. Simply navigate to the RunCloud Hub page in your RunCloud dashboard and select Enable next to the Redis Object Cache setting.
Enabling this optimization significantly reduces the load on your MariaDB/MySQL database, which leads to faster dynamic page generation, a more responsive WordPress admin area, and a snappier experience for active shoppers navigating your store.
When you enable caching for your WooCommerce store, you inherently handle sensitive personal data and Personally Identifiable Information (PII). If you host multiple WordPress websites on the same server, this can create a security risk.
In the case of a breach, if one of the websites gets infected, the attacker can access the cached data of other sites.
To protect this data, it’s recommended that you enable Redis Access Control Lists (ACLs). This ensures that each website can only access its own cached data. It will also prevent a malicious plugin on one site from accessing the Redis data of your other sites.
However, correctly configuring and maintaining this security can be challenging. That’s why we’ve pre-configured it in RunCloud Hub. When you install our plugin, Redis ACLs are automatically set up for your website, providing robust security with no extra effort.
You can verify this setting by navigating to the “Redis Object Cache Constants” section in the RunCloud Hub settings menu. If you see the following screen, then it is configured correctly.
9. Testing and Troubleshooting Your Cache
Creating a caching system is one thing, but running it is another. A flawed cache configuration can go unnoticed while silently costing you sales. After you deploy your cache, you should use two different web browsers or a regular and an incognito window to test it.
Browse the site in the incognito window (representing a new, logged-out visitor) to ensure you are being served fast, cached pages. In the regular browser, log in as a test customer to verify that all dynamic functionality works correctly.
During the tests, you should perform a complete test transaction: add a product to the cart, view the cart page, proceed to checkout, and check the mini-cart widget on various pages to ensure it updates correctly.
Check that personalized content for logged-in users appears as it should. If you encounter an issue, the first step is to clear all caches, the plugin’s cache, any server-level cache, your CDN cache, and your browser cache, before re-testing.
If a problem persists, disable your most recently changed setting (e.g., JS minification) and test again, working backward to isolate the source of the conflict. You can also use your browser’s developer tools to inspect page response headers. This lets you see cache status codes in HTTP headers like X-Cache: HIT or X-RunCache-Status: BYPASS to confirm your rules are working as intended.
Final Thoughts: Achieving Peak WooCommerce Performance with RunCloud
In this guide, we have shown you that properly configuring cache for a WooCommerce store is a multi-layered process that requires a deep understanding of how static and dynamic content interact.
Although manual configuration offers granular control, it also introduces multiple potential failure points that can be time-consuming to troubleshoot and disastrous if implemented incorrectly.
This is precisely why we developed RunCloud Hub, our all-in-one optimization and management plugin.
Built to integrate seamlessly with the RunCloud platform and eliminate these complexities, RunCloud Hub handles the actions mentioned above automatically and provides WooCommerce-aware caching out of the box with no manual rules required.
Want WooCommerce caching without the headaches? Try RunCloud Hub, which is built for store owners.
One of the most impactful optimizations for a busy WooCommerce store is Redis Object Caching, which dramatically speeds up backend operations and dynamic requests for logged-in users. This process can be tedious and complex, requiring the deployment of a Redis instance, installing a connector plugin, and manually configuring the connection.
However, RunCloud Hub transforms this complex task into a single click. It automatically detects your RunCloud-managed Redis server and enables you to do object caching.
By combining the raw power of RunCloud’s server-level caching with the intelligent, WooCommerce-aware optimizations of RunCloud Hub, you can achieve fast performance without needing to be a caching expert.
This allows you to focus on what truly matters: growing your business, managing your products, and serving your customers.
Ready to boost your store’s speed, stability, and conversions?
RunCloud Hub is one of the best caching plugins for WooCommerce. It automatically detects and excludes cart and checkout pages to prevent issues.
Does WooCommerce work with Redis?
Yes, WooCommerce works extremely well with Redis, primarily using it as a persistent object cache to efficiently handle database queries. This dramatically speeds up the WordPress admin area, user-specific content, and complex store operations, reducing server load. Enabling Redis caching with a single click on a managed server platform like RunCloud Hub is extremely easy.
How can I use Memcached with WooCommerce?
To use Memcached with WooCommerce, you must first ensure it is installed and running on your server, then use RunCloud Hub to integrate it as an object cache. Enabling cache stores repetitive database query results in memory, accelerating your site’s backend and dynamic functions.
How do I exclude the cart and checkout from the cache?
Leading caching plugins like WP Rocket and FlyingPress automatically exclude the default /cart/, /checkout/, and /my-account/ pages from the cache to ensure they remain dynamic. If you need to do this manually, find the “Do Not Cache URLs” or “Exclude Pages” section in your plugin’s settings and add the slugs for these critical pages. This is essential for a functioning e-commerce store.
Can I use object caching in WooCommerce?
Object caching is highly recommended for WooCommerce as it significantly reduces the number of database queries required for each page load. By storing query results in a fast-access system like Redis or Memcached, everything from product filtering to order processing in the backend is sped up.
Why is my product search not updating?
If your product search results are not updating with new products or price changes, the cause is almost always a stale page cache. Your caching system serves an old, static HTML version of the search results page instead of generating a new one. Clearing your site-wide cache or excluding the search results page will resolve this.
Does caching affect WooCommerce search results?
Yes, aggressive page caching can negatively affect WooCommerce search results by serving outdated or irrelevant content to users. To avoid this, you should exclude your search results page from the page cache so that it is always generated dynamically. Implementing an object cache can still speed up the search function by optimizing the underlying database queries.
What is the difference between a caching plugin and server-level caching?
A caching plugin runs within your WordPress installation, while server-level caching operates before WordPress loads, making it significantly faster and more efficient. It intercepts requests at the server level, delivering a cached page without engaging PHP or your database. RunCloud Hub provides this superior server-level caching functionality, which you can enable with one click for a performance boost that plugins alone cannot match.
How do I choose the best hosting for a high-traffic WordPress site?
For high-traffic sites, you need a scalable cloud server (from providers like Vultr, DigitalOcean, or AWS) paired with an expert server management panel. This combination provides raw power and fine-tuned control over your server environment. Using RunCloud Hub on your server allows you to easily manage resources and deploy critical performance features like single-click caching, ensuring your site remains fast and responsive under heavy load.