Repository navigation
Redis object cache
SafeHouse includes a persistent object cache for Redis. WordPress keeps database results in its object cache; without a persistent cache that cache is lost after every request. With this one, the results stay in Redis between requests, so pages need fewer database queries. Every value SafeHouse writes to Redis is signed, so other sites on a shared Redis server cannot plant data in your cache.
The object cache is not a module. It has no switch on the settings page, and you install and remove it only with WP-CLI.
| Module ID | None: it is not a module and has no SHOUSE_MODULES key |
| Default | Not installed |
| Available | With the PhpRedis extension in the web server's PHP and in the PHP that runs WP-CLI, and Redis 6.0 or newer |
| WP-CLI |
wp shouse object-cache (always, also in safe mode) |
| Since | 0.1.0 |
wp shouse object-cache enable writes wp-content/object-cache.php, the drop-in WordPress loads for a persistent object cache. The file is a short loader. It loads the cache code from the SafeHouse plugin folder, so SafeHouse updates also update the cache. Only this command writes the file.
The loader starts the Redis cache unless one of these holds. Then WordPress uses its own cache:
- SafeHouse safe mode is on (
SHOUSE_SAFE_MODE, or the filewp-content/shouse-safe-mode); -
SHOUSE_OBJECT_CACHEis defined asfalse; -
WP_REDIS_DISABLEDis defined astrue; - the SafeHouse plugin files cannot be read;
- Redis cannot be reached (see Redis outages).
Every key starts with a prefix that keeps this site's data apart from other sites on the same Redis server. SafeHouse takes:
-
WP_REDIS_PREFIX, if it is set and not empty; - otherwise
WP_CACHE_KEY_SALT, if it is set and not empty; - otherwise the first 12 hexadecimal characters of a SHA-1 hash of the database name, the table prefix and the WordPress path, followed by
:.
It then appends wph: with no separator. For example:
| Setting | Prefix in Redis |
|---|---|
| None of the constants |
3f2a9c1b7d4e:wph: (12 characters that depend on the site) |
WP_REDIS_PREFIX is mysite
|
mysitewph: |
WP_REDIS_PREFIX is mysite:
|
mysite:wph: |
A full key is the prefix, then 1 (or g for the groups WordPress marks as global), the cache group and the key, separated by colons: mysite:wph:1:options:alloptions. An empty group is stored as default. Groups that WordPress or a plugin marks as non-persistent stay in memory for one request and never reach Redis. wp shouse object-cache status shows the prefix in use.
Before it stores a value, SafeHouse serializes it and puts an HMAC-SHA256 signature in front. The signature covers the Redis key and the value. Its secret is derived from AUTH_KEY, SECURE_AUTH_KEY, NONCE_KEY, the database password (DB_PASSWORD) and the prefix.
When it reads a value, SafeHouse checks the signature first. A value with a wrong signature counts as not in the cache and is never unserialized. That covers a value written by another site or by anyone else with access to Redis, and a value of this site copied to another key. PHP's unserialize() is not safe on data from an untrusted source, so the check comes first.
Changing AUTH_KEY, SECURE_AUTH_KEY, NONCE_KEY or the database password, or changing the prefix, therefore empties the cache in practice: every stored value fails the check. The site keeps working and refills the cache as it goes. The old values stay in Redis until they expire or you flush the cache.
A flush deletes only keys under this site's prefix. SafeHouse finds them with SCAN and deletes them with UNLINK; it never sends FLUSHDB or FLUSHALL. This applies to every flush: wp shouse object-cache flush, wp cache flush, and the flushes WordPress and plugins request. Flushing one cache group deletes only that group's keys.
Each request first connects to Redis. Over tcp or tls it waits at most WP_REDIS_TIMEOUT (1 second by default). If the connection fails, SafeHouse defines no object cache and WordPress uses its own for that request. The site keeps working, more slowly. Site Health and wp shouse object-cache status show the reason.
While Redis is out, changes reach only the database, and Redis may still hold older copies when it comes back (for example if it saves its data to disk). So every request that runs without Redis leaves a marker, the option shouse_object_cache_stale. The first request that reaches Redis again deletes all of this site's keys and then the marker, before it reads anything. Checking for the marker costs one database lookup by primary key per request.
The same marker is left when the cache is off because of safe mode, SHOUSE_OBJECT_CACHE, WP_REDIS_DISABLED, or a WP-CLI command running on a PHP without PhpRedis. So changes made while the cache was off always show once it is back on.
If Redis fails in the middle of a request, the rest of that request runs on the in-memory copy only.
The object cache has no settings in wp-admin. It reads these constants from wp-config.php. The WP_REDIS_* names are the ones the Redis Object Cache plugin uses.
| Constant | Default | What it does |
|---|---|---|
WP_REDIS_SCHEME |
tcp |
tcp, tls or unix. Any other value counts as tcp. |
WP_REDIS_HOST |
127.0.0.1 |
Redis host for tcp and tls. |
WP_REDIS_PORT |
6379 |
Redis port for tcp and tls. |
WP_REDIS_PATH |
/var/run/redis/redis.sock |
Socket path, used only with unix. |
WP_REDIS_TIMEOUT |
1 |
Connect timeout in seconds. Not used with unix. |
WP_REDIS_READ_TIMEOUT |
1 |
Read timeout in seconds. Not used with unix. |
WP_REDIS_PASSWORD |
None | A password, or [ 'USER', 'PASSWORD' ] for a Redis user. An empty value sends no AUTH. |
WP_REDIS_DATABASE |
0 |
Redis database number. |
WP_REDIS_PREFIX |
None | Key prefix (see Keys and the prefix). |
WP_CACHE_KEY_SALT |
None | Key prefix when WP_REDIS_PREFIX is not set. |
WP_REDIS_DISABLED |
Not set |
true turns the cache off and keeps the drop-in. |
SHOUSE_OBJECT_CACHE |
Not set |
false turns the cache off and keeps the drop-in. true has no effect. |
SafeHouse reads no other WP_REDIS_* constant. Constants such as WP_REDIS_MAXTTL, WP_REDIS_IGNORED_GROUPS, WP_REDIS_GLOBAL_GROUPS, WP_REDIS_SERIALIZER, WP_REDIS_COMPRESSION, WP_REDIS_CLIENT, WP_REDIS_SERVERS, WP_REDIS_CLUSTER, WP_REDIS_SENTINEL, WP_REDIS_SHARDS and WP_REDIS_SELECTIVE_FLUSH have no effect.
For example, for Redis on another host with a password and its own prefix:
define( 'WP_REDIS_HOST', '10.0.0.12' );
define( 'WP_REDIS_PASSWORD', 'REDIS_PASSWORD' );
define( 'WP_REDIS_PREFIX', 'example:' );You need:
- the PhpRedis extension in the PHP that serves the site and in the PHP that runs WP-CLI (they are often different);
- Redis 6.0 or newer, which answers the
INFOcommand; - write access to
wp-contentfor the user that runs WP-CLI; - no other
object-cache.phpdrop-in.
Run:
wp shouse object-cache enableThe command works through these steps and stops at the first error:
- It checks for PhpRedis:
Error: The PhpRedis extension is not installed for the PHP that runs WP-CLI. The web server's PHP needs it as well. - It checks for another drop-in:
Error: Another plugin's object-cache.php drop-in is installed. Remove it (or deactivate that plugin) first. - It deletes this site's existing keys from Redis, so the cache starts empty:
Error: Redis is not usable: REASON, for exampleCould not connect to Redis.or anAUTHerror. - It checks the Redis version:
Error: Redis 6.0 or newer is required (this server: VERSION).If Redis does not answerINFO, the version shows asunknown. - It writes
wp-content/object-cache.php:Error: Could not write PATH, orError: Unexpected plugin folder name: NAMEwhen the SafeHouse folder name has characters other than letters, digits,.,_and-.
On success it writes object_cache "SafeHouse object cache enabled from WP-CLI" to the activity log and prints:
Success: Object cache enabled. Change alerts will report the new object-cache.php drop-in; that is expected.
Change alerts watch drop-ins, so they report this one. Running enable again over SafeHouse's own drop-in reinstalls it.
Show the drop-in, the connection and this site's keys:
wp shouse object-cache statusThe command prints a table with these rows:
| Item | Value |
|---|---|
drop-in |
ours (SafeHouse's), other (another plugin's) or none
|
phpredis |
The PhpRedis version, or missing
|
redis |
connected, or not connected followed by the reason |
prefix |
The key prefix, including wph:
|
keys |
How many keys this site has in Redis (? when Redis stops answering) |
hits/misses (this command) |
Cache hits and misses while the command ran |
The last three rows appear only when the SafeHouse cache runs in the WP-CLI process. Add --format=csv or --format=json for other output.
Tools → Site Health has a test while SafeHouse's drop-in is installed:
| Result | Status | Text |
|---|---|---|
| "The SafeHouse object cache is connected to Redis" | Good | "Database results are kept in Redis between requests. Every cached value is signed, so other sites on a shared Redis cannot plant data." |
| "The SafeHouse object cache cannot reach Redis" | Critical | "WordPress is using its own cache for now, so the site works but is slower. Reason: REASON" |
REASON is the connection error, such as "The PhpRedis extension is not installed." or "Could not connect to Redis.", or the error message from Redis. When the cache is off because of safe mode, SHOUSE_OBJECT_CACHE or WP_REDIS_DISABLED, the drop-in is still installed, so Site Health shows the critical result with the reason ?.
The Integrations tab shows the same state in the Redis object cache row: "connected" or "Redis not reachable", followed by "SafeHouse object cache".
Delete this site's keys from Redis:
wp shouse object-cache flushThe command prints Success: Object cache flushed. It needs the cache to run in the WP-CLI process; otherwise it stops with Error: The SafeHouse object cache is not running in this process. It prints the success line even when Redis fails during the flush. Check with wp shouse object-cache status if in doubt.
Remove the drop-in and this site's keys:
wp shouse object-cache disableThe command removes wp-content/object-cache.php, deletes this site's keys from Redis, and stops the WP-CLI process from writing to Redis again. It writes object_cache "SafeHouse object cache disabled from WP-CLI" to the activity log and prints Success: Object cache disabled and its keys removed from Redis.
If Redis could not be reached, the drop-in is still removed and the command prints:
Warning: Drop-in removed, but old keys could not be cleared: REASON. Run `wp shouse object-cache enable` later only after Redis is back.
If SafeHouse's drop-in is not installed, it prints Warning: The SafeHouse object cache is not installed. and changes nothing.
To turn the cache off for a while without removing the drop-in, add this to wp-config.php, or define WP_REDIS_DISABLED as true:
define( 'SHOUSE_OBJECT_CACHE', false );When you remove the line again, the first request that reaches Redis deletes the site's old keys, as after an outage.
SafeHouse reads the same connection constants as the Redis Object Cache plugin, but its keys carry wph: after the prefix. Neither cache ever reads the other's data.
To switch from the Redis Object Cache plugin:
- Remove that plugin's
object-cache.phpdrop-in, or deactivate the plugin. SafeHouse refuses to install over another drop-in. - Run
wp shouse object-cache enable.
SafeHouse does not delete the other plugin's keys from Redis.
To switch back:
- Run
wp shouse object-cache disable. - Install the other plugin's drop-in as its documentation describes.
When SafeHouse's drop-in is not installed, the Redis object cache row of the Integrations tab shows the Redis Object Cache plugin, if it is installed, and one of "Object cache connected to Redis.", "Object cache drop-in installed, but Redis is not reachable." or "Another persistent object cache is in use."
A loader installed before the rename to SafeHouse points at the old plugin folder, so WordPress uses its own cache. wp shouse object-cache status and Site Health then give the reason "The object-cache.php loader dates from before the rename to SafeHouse. Run wp shouse object-cache enable to install the current one." Run the command once. See Upgrade from WPHouse.
- File
wp-content/object-cache.php, written only bywp shouse object-cache enable. - Redis keys under this site's prefix, as described above.
- Option
shouse_object_cache_stale(not autoloaded) while a request ran without Redis. It is deleted once Redis has been cleared. - Activity log entries
object_cachewhen the cache is enabled or disabled from WP-CLI.
Deactivating SafeHouse removes the drop-in and deletes this site's keys from Redis. Uninstalling deletes a SafeHouse drop-in that is still there and leaves another plugin's drop-in alone. It does not contact Redis.
- Only one Redis server: no cluster, Sentinel, replication or sharding.
- No settings for a maximum lifetime, ignored groups, compression or another serializer.
- Two sites with the same
WP_REDIS_PREFIXon the same Redis cannot read each other's values, because the signatures differ, but they overwrite each other's keys, and a flush on one deletes the other's keys. Give each site its own prefix. -
wp shouse object-cache flushreports success even when Redis failed during the flush. -
enabledeletes this site's existing keys before it checks the Redis version, so even a failedenablecan have emptied them. - If Redis fails in the middle of a request, that request leaves no marker. A change made after the failure reaches only the database, so Redis can keep an older copy until it expires or you flush the cache.
- An increment or decrement reads the value and writes it back in two steps, so two requests doing it at the same moment can lose one change. Values never go below 0.
- WP-CLI on a PHP without PhpRedis runs on WordPress's own cache, and every such command empties the site's Redis keys at the next web request.
These pages describe SafeHouse 0.2.0 and were last reviewed on 2026-10-07. · Repository · Releases · Changelog · Report a problem with these pages
Search every page and heading in the Pages box.
Start here
Modules
- All modules
- Security: Hardening · Login limits · Bot protection · Install lockdown
- Alerts: Change alerts · Plugin health · Vulnerability alerts
- Performance: LiteSpeed page cache · Cloudflare cache · Redis object cache
- WooCommerce: Omnibus price history
- Site tools: SMTP mail · Header and footer scripts · Duplicate posts and pages · Maintenance mode · Tweaks
Guides
- Behind Cloudflare or a proxy
- Running with Wordfence
- Configure in wp-config
- Deploy with git or CI
- Replacing other plugins
- Upgrade from WPHouse
Reference
Trust
Help