Nginx page caching is one of the most effective ways to speed up a WordPress site. When it works correctly, cached pages are served directly by Nginx from memory or disk without invoking PHP-FPM or touching the database. A cached response that takes 15 milliseconds replaces a dynamic response that takes 300-800 milliseconds. For a site handling concurrent traffic, the difference is not incremental – it is the difference between a server that handles load comfortably and one that runs out of PHP workers and returns 503 errors. If your site is currently slow and you are not yet sure caching is the answer, why is my WordPress site so slow? A diagnostic guide walks through how to confirm that TTFB is actually the bottleneck before installing a caching layer.
The problem is keeping that cache consistent. Every time a post is published, updated, or a comment is approved, the relevant cached pages need to be purged so visitors get fresh content. Stale cache means visitors see outdated content – or, more subtly, browsers and CDNs receiving 304 Not Modified responses against the cached old version, never noticing the update happened. Overly aggressive purging defeats the purpose of caching. Getting the balance right requires the caching layer and the application to communicate.
On a standard VPS, setting this up is a multi-step process. You configure Nginx cache zones, write a purge location block, choose or write a WordPress plugin that knows how to call it, handle Gutenberg’s duplicate save requests, and decide what to do about object caching on top of that. None of it is particularly difficult, but it all has to be wired together correctly and maintained as WordPress and Nginx are updated.
On Hostney, this is handled at the platform level by the Hostney Cache plugin, which is installed and kept up to date for you. There is nothing to configure. For the full picture of every cache layer a WordPress site can have (browser, DNS, CDN, server, WordPress page cache, object cache, OPcache) and how to purge each one, see how to clear the WordPress cache: every layer explained – the Hostney plugin handles Layers 4-6 automatically, and the rest of that guide covers what’s left.
Why server-level caching matters#
Before getting into how the plugin works, it is worth understanding why server-level page caching is fundamentally different from plugin-based caching.
WordPress caching plugins like W3 Total Cache or WP Rocket generate static HTML files and serve them through PHP or through .htaccess rewrite rules. This is faster than generating the page dynamically, but PHP still loads on every request to determine whether a cached file exists and whether it should be served. The WordPress bootstrap still runs, at least partially.
Nginx page caching operates at the web server level, before PHP is involved at all. When a cached page exists, Nginx serves it directly – the request never reaches PHP-FPM, never loads WordPress, never touches the database. PHP workers remain available for requests that genuinely need dynamic processing: admin pages, WooCommerce cart and checkout, logged-in user sessions, and AJAX requests.
This is why server-level caching has an outsized impact on capacity. Each request that hits the cache is one fewer request consuming a PHP-FPM worker. On a hosting plan with a fixed number of workers, the cache hit rate directly determines how much concurrent traffic the site can handle before workers are exhausted.
On Hostney, Nginx page caching is built into the server configuration for every account. Cached pages are served with the
X-Cache-Status
response header, which shows HIT for cached responses and MISS for responses that were generated dynamically. You can check it in your browser’s developer tools or with a curl request. That header name is also the one WordPress Site Health looks for, so a Hostney site reports its page cache correctly under Tools > Site Health.
What gets purged and when#
The plugin registers hooks for the events that matter:
- Post publish, update, and unpublish (if you are removing content permanently, consider also configuring 410 Gone responses so the deleted URL gets deindexed faster)
- Post trashing, restoring, and permanent deletion
- Taxonomy term edits, creation, and deletion (including category renames that affect menus linking to category archives)
- Comment approval and status changes
When any of these events fires, the plugin does not immediately call the purge endpoint. Instead it queues the affected URLs and executes the purge at the end of the request, after the response has already been sent. Saving a post does not block on the cache purge, so no latency is added to the editor.
Purge scope#
The scope of each purge is calculated based on what changed. Publishing a post purges the post permalink, the homepage (whichever page is currently set as the homepage in Settings > Reading), the RSS feed, the sitemap, and the category, tag and author archives associated with the post.
Archive pages are purged by path prefix rather than exact URL, which covers paginated archive pages without needing to enumerate them. If you publish a post in a category with five pages of archives, all five are invalidated by a single prefix purge.
Two cases deliberately escalate to a full clear. Deleting a taxonomy term clears everything, because there is no reliable way to enumerate what linked to a term that no longer exists. And if more than 15 URLs and prefixes accumulate in a single request, the plugin clears the whole cache rather than making dozens of individual calls. That threshold handles bulk operations like imports and batch updates, where targeted purging would cost more than starting fresh.
Gutenberg deduplication#
Gutenberg sends multiple concurrent REST API requests when saving a post. Without handling this, a single save would trigger the same purge several times in parallel. The plugin prevents this with a short lock per post, so duplicate purge calls within a five-second window are collapsed. One save, one purge, regardless of how many requests the editor makes behind the scenes.
Purging one page by hand#
Every public post type gets a “Purge cache for this page” button in the editor sidebar. This is the one to reach for after changing something the hooks cannot see, such as a theme setting that only affects one template.
How the purge endpoint works#
The purge request is sent to a local endpoint,
/.well-known/hostney-cache-purge
, with the
Host
header set to your domain. Calling it locally is intentional: the endpoint only accepts requests from inside the server, so a request arriving from the public internet is refused before any code runs. The domain is then taken from what Nginx itself saw, not from anything WordPress supplies, which is what stops a compromised site from purging a different site’s cache.
The request supports three operations: an exact URL purge, a prefix purge for archives and paginated content, and a full clear for the domain. The plugin builds the payload from what changed and what WordPress knows about the post’s related URLs and terms.
Because each Hostney account runs in its own container with isolated resources, a page cache purge affects only your own cache.
Flush and pre-fetch#
Purging is instant, but it leaves the next visitor to each page waiting while it renders again. On a large site, clearing the cache at midday means every page is slow for whoever arrives first.
“Flush and pre-fetch” clears the page cache and then requests every public URL once, so the cache is full again before visitors arrive. It runs in the background with a progress bar on the plugin page, and the admin bar shows progress while a run is in flight. You can close the tab and it keeps going.
Two design decisions are worth knowing because they affect what you should expect:
It warms one page at a time, deliberately. Every warming request is a full uncached render, so doing them in parallel would slow the site down for real visitors while claiming to speed it up. A large site takes a while, and that is the correct trade.
URLs with a query string are skipped. Those bypass the page cache on the default configuration, so warming one would render a page and store nothing.
If an entire run completes without ever seeing a page cache header, the result says page caching looks switched off rather than reporting pages as warmed. That distinction matters: the failure it catches is a site that is quietly uncached while a plugin sits there happily purging nothing.
Object caching#
Page caching handles the external response, which is what visitors see. Object caching handles the internal database queries that WordPress runs to build that response.
WordPress runs dozens of queries per page load, many of them fetching the same data repeatedly: site options, active plugins, theme settings, rewrite rules, user roles. Without a persistent object cache, WordPress re-fetches all of it on every request. With one, the results are held in memory. Reducing database load matters most on sites with bloated wp_options tables and accumulated transients.
The impact is largest on pages that cannot be fully page-cached. WooCommerce cart and checkout pages, logged-in dashboards and admin pages all bypass the page cache because they contain user-specific content. They still benefit from object caching, because the underlying queries for configuration, product data, tax rates and shipping zones are the same for everyone.
How it works on Hostney#
Your account runs one object cache service, either Redis or Memcached, and the plugin detects which one you have and manages the
object-cache.php
drop-in for it. There is nothing to configure and no connection details to enter.
One detail is worth understanding, because it changes what the flush buttons do. The object cache is per account, not per site. If you run several sites under one hosting account, they share it. Entries are namespaced per site so the sites cannot read each other’s data, but the underlying service is shared, which is why the plugin gives you two separate buttons: “Flush this site” clears only the current site’s entries, and “Flush all sites on this account” clears everything. Reach for the second one only when you mean it, because it empties the cache for your other sites too.
On Redis, the plugin can also scan the account keyspace and show you which sites currently hold entries, which is the quickest way to see whether a site you thought was using the object cache actually is.
Before installing the drop-in, the plugin checks whether an
object-cache.php
already exists and whether Hostney Cache wrote it. If another plugin such as W3 Total Cache or Redis Object Cache installed its own, the plugin will not overwrite it unless you explicitly choose to replace it. That makes it safe on sites migrated from other hosts. On deactivation it removes only its own drop-in and leaves anyone else’s alone.
Reducing background work and cleaning the database#
Recent versions added two optional sections that have nothing to do with purging and quite a lot to do with why sites get slow over time.
Reduce background work trims activity that runs on every page load whether or not anything needs it: the admin heartbeat outside the editor, and front-end assets loaded for logged-in users who are not using the toolbar. The post editor always keeps its heartbeat, because that is what drives autosave and post locking.
Database cleanup removes what accumulates and never leaves on its own: post revisions above a floor you set, auto-drafts, trashed posts and comments, spam comments, expired transients and orphaned metadata. You can run it on demand or on a schedule, and each category shows its current count before you touch anything.
Both sections default to off. The platform installs and updates this plugin for you, so a default that changed how your site behaves would amount to a Hostney release quietly altering sites nobody asked to change. If you want these, you turn them on.
Where to find it#
The plugin is installed automatically on Hostney hosting accounts and kept current for you. There is no download step and nothing to activate.
You will find it as a top-level Hostney Cache item in the WordPress admin sidebar, organised into tabs for status, object cache, optimisation and activity. The status view shows the detected domain, whether page caching and the purge endpoint are working, and the state of your object cache. The activity log lists recent purge operations with what triggered them and whether they succeeded.
There is also an admin bar menu, on both the front end and in wp-admin, with Purge cache, Flush and pre-fetch, and a link into the settings. It is the fastest route after a bulk change the automatic hooks would not see, such as editing the database directly or changing a theme setting that affects every page.
The plugin is open source and the code is on GitHub if you want to read the purge logic before trusting it.
No other caching plugin needed#
Most WordPress sites install a caching plugin for two reasons: page caching and object caching. On Hostney both are handled at the platform level. For a head-to-head walkthrough of the major caching plugins and when each is the right pick, see best WordPress caching plugins: an honest comparison.
This means you can run WordPress on Hostney with no third-party caching plugin at all. That removes a common source of conflicts and stale-cache problems, and it is one fewer plugin to keep patched, which matters given how plugin vulnerabilities tend to arrive.
If you migrate to Hostney with a caching plugin still active, you do not need to do anything about it: the migration deactivates known page-cache plugins as part of the move. This is not tidiness. A cache plugin left active rewrites its own drop-in files on the next request, and a foreign object cache drop-in occupies the one slot the Hostney drop-in needs, so the account ends up paying for an object cache nothing is using.
The remaining gap is asset minification and concatenation of CSS and JavaScript. Compression is already handled at the server level, and lazy loading has been in WordPress core since 5.5, so minification is the narrower thing it sounds like. If you rely on WP Rocket specifically for it, use a dedicated minification plugin, or test whether your site is fine without it. With page caching at the web server layer, it usually is.
What this replaces#
The self-managed version of all this is not hard to build once. It is hard to keep working, because every piece of it has to survive Nginx upgrades, PHP upgrades and whatever WordPress changes about how saves fire. That maintenance is the part nobody budgets for, and it is the part the platform absorbs here.
Caching is one layer of a faster site rather than the whole of it, and the rest is covered in how to speed up WordPress. If you want to understand what your hit rate is actually telling you, what is a cache miss and how does it affect performance is the one to read next, and should I use a CDN for my website covers whether adding one on top is worth it. The hosting plans list what each tier includes.