Releases: hostney/hostney-cache
Release list
v1.3.0
The first release that does more than cache. Two new tools, and a page that
looks like the rest of Hostney.
New: Reduce background work
WordPress does a certain amount of work on every page view, and a certain amount
every few seconds in the background, whether or not your site uses the features
behind it. This turns off the parts you do not need.
- Background activity. An open admin tab checks in with the server every 15
seconds by default. You can slow that to every two minutes, or limit it to the
places it actually does something. - Emoji script, embeds, front-end Dashicons and the extra head
tags (RSD, Windows Live Writer, shortlink, generator) can each be removed
from the front end.
Every option is off by default and applies only to the site you set it on.
The post editor always keeps its background activity, whatever you choose.
That is what drives autosave and the warning when someone else is editing the
same post, and neither is worth trading for a request every two minutes.
Two of these need a look at your site afterwards, and the page says so where you
turn them on: some themes use Dashicons, and removing the embed discovery links
stops other sites embedding yours. Embedding YouTube and the rest into your own
posts is unaffected.
New: Database cleanup
WordPress keeps a great deal it never removes — every revision of every post,
drafts nobody finished, comments you binned months ago, expired temporary data.
None of it is served to visitors, and all of it is backed up and restored with
your site.
The page shows you how many rows of each kind can go before anything is
removed. "Remove 12,904 revisions" is a decision you can make; "Optimise
database" is not.
- At least one revision per post is always kept. Revisions are the only undo
an edit from last week has, so there is no setting that removes them all. - Removal happens in batches, so a site with a very large backlog takes a few
presses rather than going unresponsive while it works. - Optionally weekly or monthly, using the same limits.
A page that looks like Hostney
The plugin page has been rebuilt to match the control panel — the same colours,
buttons, inputs and dialogs — and organised into four tabs:
| Tab | What is on it |
|---|---|
| Overview | Cache status, purge, and flush and pre-fetch |
| Object cache | Engine status, drop-in, and what each site on the account is holding |
| Optimisation | Reduce background work, database cleanup |
| Activity | The purge log |
Confirmations are now proper dialogs instead of browser pop-ups. That is not
only about appearance: a browser prompt cannot show a list, so "this also clears
shop.example.com" had to be squeezed into a line of text — and browsers suppress
repeated prompts, meaning the warning before clearing every site on an account
could sometimes not appear at all.
Removing the object cache drop-in now asks first, and says what stops working.
It previously happened on a single click with no warning.
Upgrading
Nothing to do, and nothing changes on your site unless you turn it on. Every new
option is off by default, and the two existing caches carry on exactly as before.
v1.2.4
Fixed: purging did nothing when you were signed in on a preview address
Hostney serves a site on whichever address you reach it by — its own domain, the
www form, or the temporary .hostney.app preview address. WordPress is told
the site address once per request, so it reports back whichever one you happen
to be using.
The plugin took that at face value and sent its cache purge to the address you
were browsing rather than to the site. Preview addresses do not use the page
cache, so there was nothing there to purge: the request failed, and the live
domain's cache was never cleared.
The only symptom is edits not appearing. Nothing is written to any error log,
and the site itself looks perfectly healthy — which is what made this worth
fixing over a version of its own.
Purges are now always addressed to the site's own domain, whichever address you
are signed in on. The URLs sent with them are rewritten to match, because the
purge endpoint rejects any URL that does not belong to the domain asking.
Who this affected: anyone administering a live site over its preview
address, which is common after a migration — the preview URL is usually the one
still in your bookmarks. If you only ever use the site's own domain, purging
already worked and nothing changes for you.
Two things the same change fixes
- Pre-fetch warms the live cache. "Flush and pre-fetch" was warming whichever
address you were on. On a preview address that meant carefully filling a cache
nobody reads from. - The plugin page describes the live site. Page caching, the purge endpoint
check and the "Detected website" row now all refer to the site's own domain,
so what the page reports and what its buttons act on can no longer disagree.
Requirements
This relies on a small platform helper that Hostney installs on your site
automatically. There is nothing to configure and nothing to wait for.
Until that helper arrives, the plugin behaves exactly as it did in 1.2.3 —
correct on the site's own domain, unchanged everywhere else.
v1.2.3
Fixed: two sites on one account could share each other's cached data
This is the important one, and it could take a site down.
Every Hostney account gets one Redis or Memcached instance, shared by every
domain on it. Each site is meant to keep its entries under its own key prefix.
That prefix was derived from the WordPress database table prefix and nothing
else — so two installations on the same account both using the default wp_
produced the same prefix and shared every key.
The failure looks like nothing at all: a blank white page, HTTP 200, and not one
line in any error log. The second site reads the first site's cached
alloptions, so template and stylesheet name a theme it does not have, the
template loader finds no file to include, and WordPress returns an empty
response. Nothing failed from PHP's point of view, so nothing was written to a
log. Deactivating the plugin removes the drop-in, options come from the database
again, and the site comes back — which makes the plugin look like the cause
rather than the collision.
Cache keys are now namespaced by database name, install path and table prefix.
WP_CACHE_KEY_SALT is honoured ahead of all of it, for installations that
deliberately want to share a cache.
Present in every release from 1.2.0 through 1.2.2.
Upgrading empties the object cache on affected sites. Entries written under
the colliding prefix cannot be trusted and must not be read back, so they are
abandoned rather than reused. Sites rebuild over the next few requests; there is
nothing to do.
Flushing is now scoped to a single site
Flushing emptied the whole instance, so every other site on the account lost its
cache at the same time — no warning, and nothing to tell those owners why their
site suddenly got slower. Installing or removing the drop-in did the same thing.
- Flush this site is the new default and clears only this site's entries.
- Flush all sites on this account is still there, behind a confirmation that
names the other sites it is about to affect. - Installing the drop-in, removing it, and deactivating the plugin are all
scoped the same way. - Deactivating now also clears this site's entries and removes its registry
record, so nothing is left stranded in the shared instance.
New: Account keyspace
A panel showing how many cache entries each site on the account is holding, and
how many belong to no site at all — usually left behind by a domain that was
removed.
The key prefix is a one-way hash, so a site can work out its own and never a
neighbour's. Sites now record themselves in a small account-level registry,
which is what makes both the breakdown and the "this will also clear" warning
possible at all.
The breakdown reads every key in the instance, so it runs only when you ask for
it and never on page load.
Page caching and the purge endpoint are checked separately
The plugin page rendered both the "Page caching" and "Purge endpoint" rows from a
single test of the purge endpoint. Any address that caches without a purge
location, or does not cache at all, was reported as "Page caching: not detected"
— untrue, and the row people act on.
Each row now has its own check, and there are three outcomes rather than two:
- cached and purgeable — fine
- cached but not purgeable — genuinely broken, and now says so specifically
- neither — an address that does not cache, such as a preview URL. Reported as
normal rather than as a fault, and "Purge all cache" is no longer offered
where it cannot work.
Redis and Memcached
Per-site flushing and the keyspace breakdown need Redis. Memcached has no way to
look up keys by prefix, so it offers only the account-wide flush and says so on
the page.
Key isolation — the fix at the top of this list — works on both engines.
v1.2.2
Flush and pre-fetch
Purging a cache is instant. Refilling it is not — and until it refills, the next
visitor to every page pays for the render. On a site with a few hundred pages
that is a slow half hour for whoever happens to arrive first, right after you
changed a theme or ran a bulk edit.
Flush and pre-fetch clears the page cache and then requests every public URL
once, so the cache is full again before anyone asks for it. It is on the plugin
page with a progress bar, and in the admin bar menu from anywhere on the site.
It is slow on purpose
A hosting account has a small, fixed number of PHP workers. Warming is by
definition a stream of uncached requests, so every one of them occupies a
worker for a full page render. Fire several at once and the warmer takes the
site down for real visitors while claiming to make it faster.
So: one request at a time, a pause between them, a 500-URL cap, and the work
runs in the background on WP-Cron rather than holding a browser tab open. A few
hundred pages takes tens of minutes. That is the correct speed, not a limitation
to be tuned away.
Batches are time-boxed rather than a fixed URL count. spawn_cron() will not
spawn again inside WP_CRON_LOCK_TIMEOUT, so a tick happens roughly once a
minute however often it is asked — a fixed five-URL batch would have warmed five
URLs a minute, and a 500-page site would have taken a day and a half.
It warms your origin, not a CDN edge
Requests go to 127.0.0.1 with a Host header rather than to the public
hostname. Three reasons, and each one matters on a different kind of site:
- On Hostney, PHP-FPM shares the host network namespace, so
127.0.0.1really
is the nginx holding this site's page cache. - A site behind a CDN would otherwise warm an edge node — possibly without ever
reaching the origin whose cache was just emptied. - The request arrives from a private address, so the bot-protection layer passes
it before any scoring or challenge logic runs. A challenge page written into
the page cache would then be served to every subsequent visitor.
URLs with a query string are skipped: they bypass the page cache on the default
configuration, so warming one renders a page and stores nothing.
It tells you when there is nothing to warm
If a whole run comes back with no page-cache header on any response, the result
says page caching looks switched off for the site — rather than reporting N
pages warmed into a cache that does not exist. That failure is otherwise only
discovered later, by the site still being slow.
Admin bar
The single "Hostney: Purge cache" item is now a menu: Purge cache, Flush
and pre-fetch, and Cache settings. The parent links to the settings page
rather than being inert, and while a pre-fetch is running its label carries the
progress — so "is it still going?" is answerable without opening the page.
Filters
| Filter | Default | Purpose |
|---|---|---|
hostney_cache_warm_max_urls |
500 |
How many URLs a run may queue |
hostney_cache_warm_urls |
— | The collected URL list, before it is trimmed |
hostney_cache_warm_delay_ms |
200 |
Pause between requests |
hostney_cache_warm_batch_seconds |
20 |
How long one cron tick may spend warming |
Upgrading
Nothing to do. No settings, no migration, and the object cache drop-in is
untouched by this release.
Deactivating the plugin now also clears any queued warm-up, so a run cannot
outlive the plugin and reappear on the next activation.
v1.2.1
WordPress plugin for automatic cache management on Hostney hosting.
Object caching now works with Redis as well as Memcached, and the site works out which one it is on by itself.
This release also contains v1.1.0 and v1.2.0, neither of which was published here. Upgrading from v1.0.0 gets you all three.
What's new
Redis object caching
The object cache drop-in speaks to Redis or Memcached. Which one it uses is decided per request, by probing for each engine's socket and connecting to whichever answers.
That is the whole mechanism, and it is why switching engines in the Hostney control panel needs no action on the site: the panel stops one engine and starts the other, and the next PHP request finds the new socket and connects to it. Nothing to reconfigure, no file to edit, no constant to set.
The drop-in now looks after itself
Three things that all used to need a human:
- Activating the plugin installs the drop-in, if nothing else already owns the
object-cache.phpslot. Deactivating has always removed it, so until now the plugin could take the file away but never put it back - the only thing that created one was a button on the admin page. - Updating the plugin updates the drop-in. A plugin update does not normally touch
wp-content/, so a site upgraded from v1.1.0 kept a Memcached-only drop-in. It carried on working on Memcached and would have quietly stopped caching if the account switched to Redis. The drop-in is now stamped with the plugin version and rewritten when it is stale. - The admin page tells you when the drop-in is out of date, instead of reporting it as current.
A drop-in belonging to another plugin is never touched, with or without these changes.
A cache that cannot take the site down
If neither engine answers, the drop-in falls back to a non-persistent in-memory array for that request. The site keeps serving; it just stops caching between requests until the socket is back.
A socket that accepts a connection is not a server that answers, so the drop-in checks for a real response rather than trusting the connect, and it uses a short timeout throughout - both engines are on the same machine, so a slow one is a broken one.
Fixed: wp_cache_supports( 'flush_group' ) now reports false
It reported true while only clearing the in-process array. That told WordPress a group flush had invalidated persistent entries when it had not, so anything relying on wp_cache_flush_group() could read stale data back out of the object cache. Reporting false makes WordPress fall back to a path that actually works.
Features
- Automatic nginx cache purge on content changes - posts, pages, custom post types, taxonomies, comments
- Smart URL collection - purges permalink, homepage, RSS feed, sitemap, and related archives
- Deduplication and batching - multiple changes in a single request are collected and deduplicated
- Batch overflow protection - falls back to full cache clear when more than 15 URLs are queued
- Gutenberg debounce - handles concurrent save requests without duplicate purges
- Redis or Memcached object cache management, detected at runtime
- Admin page with status overview, manual purge button, and activity log
- Admin bar and post editor purge buttons
Requirements
- WordPress 5.0+ (tested to 6.9)
- PHP 7.4+
- Hostney hosting (nginx caching with OpenResty/Lua)
- For object caching: the
redisormemcachedPHP extension, whichever engine the account runs. Both ship in the Hostney PHP images.
Upgrading
No action needed. Sites hosted on Hostney get the update automatically, and the drop-in is installed or refreshed on its own.
If the admin page reports the drop-in as out of date after an update, wp-content/ is not writable - fix the permissions, or use the Update drop-in button once the directory is writable again.
v1.2.0
Object caching now works with Redis as well as Memcached, and the site figures out which one it is on by itself.
This release also contains v1.1.0, which added Memcached object caching and was never published here. Upgrading from v1.0.0 gets you both.
What's new
Redis object caching
The object cache drop-in speaks to Redis or Memcached. Which one it uses is decided per request, by probing for each engine's socket and connecting to whichever answers.
That is the whole mechanism, and it is why switching engines in the Hostney control panel needs no action on the site: the panel stops one engine and starts the other, and the next PHP request finds the new socket and connects to it. Nothing to reconfigure, no file to edit, no constant to set.
A cache that cannot take the site down
If neither engine answers, the drop-in falls back to a non-persistent in-memory array for that request. The site keeps serving; it just stops caching between requests until the socket is back.
A socket that accepts a connection is not a server that answers, so the drop-in checks for a real response rather than trusting the connect, and it uses a short timeout throughout - both engines are on the same machine, so a slow one is a broken one.
Fixed: wp_cache_supports( 'flush_group' ) now reports false
It reported true while only clearing the in-process array. That told WordPress a group flush had invalidated persistent entries when it had not, so anything relying on wp_cache_flush_group() could read stale data back out of the object cache. Reporting false makes WordPress fall back to a path that actually works.
Internal
Drop-in management moved out of the Memcached class. It is one file serving either engine, rather than one engine's class owning the single object-cache.php slot that both need.
Features
- Automatic nginx cache purge on content changes - posts, pages, custom post types, taxonomies, comments
- Smart URL collection - purges permalink, homepage, RSS feed, sitemap, and related archives
- Deduplication and batching - multiple changes in a single request are collected and deduplicated
- Batch overflow protection - falls back to full cache clear when more than 15 URLs are queued
- Gutenberg debounce - handles concurrent save requests without duplicate purges
- Redis or Memcached object cache management, detected at runtime
- Admin page with status overview, manual purge button, and activity log
- Admin bar and post editor purge buttons
Requirements
- WordPress 5.0+ (tested to 6.9)
- PHP 7.4+
- Hostney hosting (nginx caching with OpenResty/Lua)
- For object caching: the
redisormemcachedPHP extension, whichever engine the account runs. Both ship in the Hostney PHP images.
Upgrading
Sites hosted on Hostney are updated automatically - no action needed.
Anywhere else, replace the plugin folder as usual. The drop-in is rewritten on activation and keeps the same marker, so an existing wp-content/object-cache.php from an earlier version is recognised and replaced rather than left in place.
v1.0.0
Hostney Cache v1.0.0
WordPress plugin for automatic cache management on Hostney hosting.
Features
- Automatic nginx cache purge on content changes - posts, pages, custom post types, taxonomies, comments
- Smart URL collection - purges permalink, homepage, RSS feed, sitemap, and related archives
- Deduplication and batching - multiple changes in a single request are collected and deduplicated
- Batch overflow protection - falls back to full cache clear when more than 15 URLs are queued
- Gutenberg debounce - handles concurrent save requests without duplicate purges
- Memcached object cache management
- Admin page with status overview, manual purge button, and activity log
- Admin bar and post editor purge buttons
Requirements
- WordPress 5.0+
- PHP 7.4+
- Hostney hosting (nginx caching with OpenResty/Lua)