# WordPress Redis object cache: when it helps and how to set it up

> What a WordPress Redis object cache does, how it differs from page cache, when it actually speeds a site up, and how to set it up safely on a VPS or in ZoPanel.

Source: https://zopanel.net/blog/wordpress-redis-object-cache  
Updated: 2026-10-21

## Key takeaways

- WordPress's built-in object cache lives for one request only; Redis keeps it between requests.
- Page cache serves anonymous visitors, while a Redis object cache helps wp-admin, WooCommerce and logged-in users.
- Set maxmemory and maxmemory-policy allkeys-lru, because by default Redis refuses writes when full instead of evicting.
- On a shared server every site needs its own key prefix and its own Redis credentials.

A **WordPress Redis object cache** stores database query results, options and transients in Redis, so later requests read them from RAM instead of asking MariaDB again. It helps most on pages that can't use a page cache: wp-admin, WooCommerce cart and checkout, membership areas and anything a logged-in user sees. On a brochure site that already has page cache turned on, the gain is usually small.

This article explains how the object cache works, how it differs from page cache, when it's worth it, how to set it up by hand on Ubuntu 24.04 or Debian 12, how to switch it on in ZoPanel, and the configuration mistakes we see most often.

## What is the WordPress object cache?

WordPress ships with an object cache layer (`WP_Object_Cache`). Whenever it needs an option, a post or user metadata, it asks the object cache first; on a miss it queries the database and stores the result.

The catch is that the default cache is **non-persistent**. As the [WordPress developer reference](https://developer.wordpress.org/reference/classes/wp_object_cache/) puts it, the data lives in memory only for the duration of the request. The next request starts from scratch and runs the same queries again.

A persistent object cache replaces that layer with a drop-in, `wp-content/object-cache.php`, that talks to Redis (or Memcached). Data survives between requests and is shared by every PHP worker. One side effect people miss: with a persistent object cache, plugin transients are stored in Redis instead of the `wp_options` table, so that table stops bloating with expired transients.

Since WordPress 6.1, **Site Health** may recommend a persistent object cache when the site is large enough to benefit from one.

## Page cache vs object cache

| | Page cache | Redis object cache |
|---|---|---|
| What it stores | The finished HTML page | Query results, options, transients |
| Does PHP run? | No, the web server answers | Yes, but with fewer database queries |
| Who benefits | Anonymous visitors | Every request, including wp-admin and logged-in users |
| Cart and checkout | Must be bypassed | Works |
| Speed-up | Very large on cacheable pages | Moderate, depending on how query-heavy the site is |

They complement each other. The sensible order is page cache first, because it's the biggest win (our [4 GB VPS capacity tests](/blog/how-many-wordpress-sites-4gb-vps) saw capacity rise 2.5 to 4 times with it), then Redis for the traffic page cache can't serve.

## When should you use a WordPress Redis object cache?

It's worth it for:

- **WooCommerce stores**: cart, checkout, customer accounts and order admin all bypass page cache.
- **Membership, course and forum sites** with many logged-in users.
- **Slow wp-admin** caused by query-heavy plugins or several editors working at once.
- **Transient-heavy plugins**, such as SEO suites, analytics or plugins calling external APIs.

It adds little when:

- The site is a brochure or a low-traffic blog with page cache on: almost no page view runs PHP anyway.
- The server is short of RAM: Redis needs its own memory, and a cache that keeps evicting has a poor hit rate.
- Queries are slow because of missing indexes or a badly written plugin: the cache hides the symptom, but every miss is still slow.

A quick test: install Query Monitor on a staging copy, open a few wp-admin screens and the cart page, and look at the query count and database time. If each page runs hundreds of repeated queries, Redis will make a visible difference.

## Setting up a Redis object cache by hand on Ubuntu or Debian

These steps suit a VPS running one or a few of your own sites with PHP-FPM already installed.

### Step 1: install Redis and the PHP extension

```bash
sudo apt update
sudo apt install redis-server php-redis
```

Ubuntu 24.04 ships PHP 8.3 and Debian 12 ships PHP 8.2. If your PHP comes from another repository, install the extension package for that version, for example `php8.3-redis`.

### Step 2: cap memory and pick an eviction policy

Open `/etc/redis/redis.conf` and set:

```conf
bind 127.0.0.1 -::1
maxmemory 256mb
maxmemory-policy allkeys-lru
requirepass CHANGE_TO_A_LONG_RANDOM_PASSWORD
```

`maxmemory-policy` is the line that matters. By default Redis uses `noeviction`: when it's full it **refuses writes** rather than dropping old keys. The [Redis eviction documentation](https://redis.io/docs/latest/develop/reference/eviction/) recommends `allkeys-lru` as a good default for caches, since it drops the least recently used keys. 128–256 MB is usually plenty for a handful of WordPress sites; watch it and adjust.

Because this is a cache, you can turn off on-disk snapshots with `save ""` to save I/O. Losing the cache on restart is fine.

Never expose port 6379 to the internet. Keep `bind` on localhost and don't add a firewall rule for it.

```bash
sudo systemctl restart redis-server
sudo systemctl restart php8.3-fpm     # Debian 12: php8.2-fpm
```

### Step 3: configure wp-config.php

Add these lines to `wp-config.php`, **above** the "That's all, stop editing" line:

```php
define( 'WP_REDIS_HOST', '127.0.0.1' );
define( 'WP_REDIS_PORT', 6379 );
define( 'WP_REDIS_PASSWORD', 'CHANGE_TO_A_LONG_RANDOM_PASSWORD' );
define( 'WP_REDIS_PREFIX', 'shop1:' );
define( 'WP_REDIS_MAXTTL', 86400 );
```

`WP_REDIS_PREFIX` must be unique when several sites share one Redis, or one site will read another's cache. `WP_REDIS_MAXTTL` caps how long (in seconds) a key can live, so nothing stays cached forever.

### Step 4: install the plugin and enable the drop-in

The most widely used plugin is [Redis Object Cache](https://wordpress.org/plugins/redis-cache/) by Till Krüss. With WP-CLI, run as the user that owns the site:

```bash
wp plugin install redis-cache --activate
wp redis enable      # copies the object-cache.php drop-in into wp-content
wp redis status      # shows connection status and diagnostics
```

### Step 5: check that the cache is working

```bash
export REDISCLI_AUTH='CHANGE_TO_A_LONG_RANDOM_PASSWORD'
redis-cli INFO stats | grep -E 'keyspace_(hits|misses)|evicted_keys'
redis-cli INFO memory | grep used_memory_human
```

Hit rate = `keyspace_hits / (keyspace_hits + keyspace_misses)`. Once the site has been running for a while it should be high. If `evicted_keys` climbs quickly, Redis is short of memory: raise `maxmemory` or lower `WP_REDIS_MAXTTL`.

## One Redis, many customers: the security problem

On a shared hosting server, one Redis for every site is a real risk. Without controls, customer A's site can read, write or delete customer B's cache, including session data if a plugin keeps it there. One `FLUSHALL` wipes everyone's cache.

Ways to separate sites, from weakest to strongest:

1. **Different prefixes only.** Prevents accidental collisions, not deliberate snooping.
2. **Different database numbers (0–15).** Still one shared password, and only 16 databases.
3. **Redis ACLs (Redis 6 and later).** One user per site with its own password, limited to keys with its own prefix and barred from admin commands. The Redis Object Cache plugin supports ACLs by passing `WP_REDIS_PASSWORD` as `['user', 'password']`.
4. **A separate Redis process per account.** The strongest isolation, at a cost in RAM.

If you sell hosting, level 3 is the minimum.

## Turning on the Redis object cache in ZoPanel

ZoPanel handles the isolation above for you. The steps:

1. **The administrator installs Redis once**, from the **Database servers** card on the **Databases** page or from **Components**. Every database engine costs memory, so install it when customers actually need it.
2. **Open the website → PHP & config tab → Redis object cache** and switch it on. ZoPanel creates a private Redis database for the site and configures the Redis Object Cache plugin.
3. **Turn on Page cache** on the same tab if it isn't on yet, so anonymous visitors are served straight from nginx.

Each Redis database in ZoPanel has its own key namespace and its own password. Keys must start with the namespace prefix (for example `alice_cache:`); other keys and administrative commands are denied, so one customer can't read or flush another's cache. Details are in the [Databases documentation](/docs/databases).

To clear the cache, open the **WordPress** tab and click **Flush caches** in the **Maintenance** card: it runs `wp cache flush` and deletes all transients. See the [WordPress Toolkit](/docs/wordpress) and [Performance and capacity](/docs/performance) docs for how page cache, Redis and sleeping PHP work together.

One note: Redis data is not exported or backed up. That's the nature of a cache, but it means you should never let a plugin keep its only copy of anything important (orders, settings) in Redis.

## Common Redis object cache mistakes

1. **No `maxmemory`.** Redis grows until the server runs short of memory, or with `noeviction` it starts failing writes.
2. **Two sites with the same prefix.** One site shows the other's title, menus or settings, a baffling symptom if you don't think of the cache.
3. **Editing the database directly without flushing.** Change a URL or option in SQL and the site keeps reading the old value from Redis. Run `wp cache flush` after direct database work, or use `wp search-replace`, which goes through WordPress.
4. **Removing Redis without disabling the drop-in.** Run `wp redis disable` before removing Redis or moving the site to a server without it.
5. **Exposing Redis to the internet.** An unauthenticated Redis on a public port is a routine target for automated scanners.
6. **Expecting Redis to replace page cache.** For anonymous visitors, page cache is still far faster.

## The takeaway

A Redis object cache isn't a turbo button for every WordPress site. It pays off where page cache can't reach: wp-admin, WooCommerce and membership sites. Turn on page cache first, measure your queries, then add Redis with a memory cap, `allkeys-lru` and a unique prefix per site. On a multi-customer server, per-account key and password isolation is not optional.

In ZoPanel, both page cache and the Redis object cache are a single switch on the **PHP & config** tab, and both are available on the Free plan (3 hosting accounts, 10 websites, 10 databases). See [pricing](/pricing) when you need more sites.

## Frequently asked questions

### Does a Redis object cache make WordPress faster?

Yes, on pages that run PHP and many database queries: wp-admin, WooCommerce and members' pages. For anonymous visitors on a site with page cache, PHP barely runs, so Redis changes very little.

### Redis or Memcached for WordPress?

Both work as a persistent object cache. Redis is more common in the WordPress ecosystem, has ACLs to separate sites and has the widely used Redis Object Cache plugin, so it is usually the easier choice.

### How much RAM does Redis need for a WordPress site?

It depends on the number of posts, plugins and transients. A typical site often uses only tens of megabytes; set a modest `maxmemory`, watch `used_memory` and `evicted_keys`, and raise it if keys are being evicted constantly.

### Do I need both page cache and a Redis object cache?

For shops and sites with logged-in users, yes. Page cache serves casual visitors without running PHP, while Redis cuts queries for the requests that must run PHP, such as cart, checkout and wp-admin.

### How do I turn off the Redis object cache safely?

Run `wp redis disable` to remove the `object-cache.php` drop-in, then deactivate the plugin or remove Redis. In ZoPanel, switch off **Redis object cache** on the website's **PHP & config** tab.
