Redis object cache instellen in WordPress

Je host raadt Redis aan. Je hebt de Redis Object Cache plugin geïnstalleerd, maar het dashboard zegt nog steeds 'Drop-in: Invalid' of 'Not connected'. In deze walkthrough lees je wat die drop-in eigenlijk is, welke wp-config.php constants ertoe doen, de valkuil bij Docker Compose en hoe je controleert of de cache ook echt iets doet.

Doel. Aan het einde van dit artikel staat er in je WordPress-admin onder Instellingen > Redis "Status: Connected" met een groen bolletje, en is de object-cache.php drop-in geïnstalleerd in wp-content/. Vanaf dat moment leest elke WordPress-request herhaalde databasequeries uit Redis in plaats van uit de database zelf.

Wat object caching is en waarom Redis wint van de default

WordPress heeft al een object cache ingebouwd, maar die is niet-persistent: elke gecachete query, optie en berekende waarde gaat in een PHP-array die aan het eind van de request weer weg is. De volgende request begint dus gewoon bij nul. Een Redis object cache vervangt die wegwerparray door een verbinding met een echte Redis-server, zodat de gecachete waardes tussen requests én tussen PHP-workers blijven staan. Het mechanisme staat beschreven in de WP_Object_Cache class-reference op developer.wordpress.org.

Die vervanging gebeurt via een bestand dat een drop-in heet. Zodra WordPress boot, checkt het of wp-content/object-cache.php bestaat. Als dat zo is, laadt WordPress dat bestand in plaats van de ingebouwde class en gaat elke aanroep van wp_cache_get(), wp_cache_set(), wp_cache_add() en de rest naar Redis. Zonder die drop-in doet de Redis Object Cache plugin in wp-content/plugins/redis-cache/ feitelijk helemaal niets aan caching: hij laat alleen een statusscherm in de admin zien. Dit is de grootste valkuil in Redis-setups, en precies de reden dat het plugin-dashboard een grote "Enable Object Cache"-knop heeft in plaats van zichzelf stilletjes aan te zetten.

Redis object caching zit op een andere laag dan page caching. Een page cache (WP Super Cache, WP Rocket, LiteSpeed LSCache, nginx fastcgi_cache) bewaart de complete gerenderde HTML en slaat PHP helemaal over bij een hit. Een Redis object cache draait pas nadat PHP is gestart: hij slaat de databasequeries over die anders tijdens het verwerken van de request zouden draaien. De twee vullen elkaar aan, ze zijn geen alternatieven voor elkaar. Daarom loopt het conceptartikel over cachelagen door hoe ze stapelen. Redis schittert juist op plekken waar een page cache niets doet: ingelogde bezoekers, WooCommerce-cart en checkout, /wp-admin/ en alles met per-gebruiker-output.

Een hardnekkige mythe is dat Redis alleen nuttig is voor "grote" sites. Zo werkt de techniek niet. Het voordeel van object caching schaalt met het aantal herhaalde databasequeries per request, en elke WordPress-site met Yoast SEO, WooCommerce, een contactformulier-plugin of een paar membership-plugins doet er al genoeg. Het "alleen voor grote sites"-verhaal komt meestal voort uit het feit dat managed hosts Redis bundelen in hogere pakketten, en dat is een prijsbeslissing, geen technische.

Prerequisites

Voordat je begint, heb je drie dingen op orde. Doe ze in deze volgorde: als er één mist, weigert de "Enable Object Cache"-knop straks gewoon af te maken.

  • Een Redis-server die je vanaf WordPress kunt bereiken. Op een single-server setup draait Redis op 127.0.0.1:6379 naast PHP-FPM. Bij een managed host krijg je een hostname (vaak iets als redis.internal) en een port. In een Docker Compose-setup voeg je een redis service toe aan docker-compose.yml en verwijs je ernaar via de service name vanuit de WordPress-container. Bij de meeste managed hosts bevestigt het controlepaneel of de documentatie van je host of Redis beschikbaar is en welke hostname je moet gebruiken. Als je SSH-toegang hebt: check dat de server draait met redis-cli -h <host> -p <port> ping; je moet PONG terugkrijgen.
  • Een PHP Redis-client. Of de PhpRedis PECL-extensie (een gecompileerde C-extensie, sneller), of Predis (pure PHP, meegeleverd met de plugin, iets langzamer maar zonder serverwijzigingen). Of PhpRedis geïnstalleerd is check je vanuit wp-admin onder Hulpmiddelen > Sitegezondheid > Info > Server, waar de rij "PHP-extensies" alle geladen extensies opsomt. Als je SSH-toegang hebt: draai php -m | grep -i redis. Staat er redis, dan zit je goed. Als PhpRedis niet in de lijst staat, pakt de plugin automatisch Predis en kun je later upgraden.
  • WordPress 4.6 of nieuwer, PHP 7.2 of nieuwer. Redis Object Cache 2.7.0 vraagt minimaal deze versies. De meeste moderne WordPress-sites voldoen hier al aan; is dat bij jou niet zo, upgrade dan eerst.
  • Schrijftoegang tot wp-config.php en wp-content/. De drop-in wordt naar wp-content/object-cache.php gekopieerd en de connectie-constants gaan in wp-config.php. Als DISALLOW_FILE_MODS aanstaat, kan de admin-knop de drop-in niet wegschrijven en moet je WP-CLI gebruiken (dat staat verderop).

Op een WordPress multisite netwerk activeer je de plugin via Network Activate, niet per site. Dat is een harde eis sinds pluginversie 2.0.0 en staat op de Redis Object Cache plugin-pagina.

Stap 1: de Redis Object Cache plugin installeren en activeren

Twee routes, beide prima, beide gewoon ondersteund in 2.7.0.

Via het dashboard. Log in op WordPress, ga naar Plugins > Nieuwe toevoegen, zoek op "Redis Object Cache" van Till Krüss en klik op Nu installeren en daarna op Activeren. Je ziet nu onder Instellingen > Redis een nieuw menu-item.

Via WP-CLI. Vanuit de WordPress-root:

wp plugin install redis-cache --activate

Verwachte output:

Installing Redis Object Cache (2.7.0)
Downloading installation package...
Unpacking the package...
Installing the plugin...
Plugin installed successfully.
Activating 'redis-cache'...
Plugin 'redis-cache' activated.
Success: Installed 1 of 1 plugins.

Klik nog nergens op een "enable"-knop. Zet eerst de wp-config.php-constants erin, anders heeft de drop-in straks geen plek om mee te verbinden.

Stap 2: de connectie-constants in wp-config.php zetten

Open wp-config.php via de bestandsbeheerder van je hostingpaneel (of download het bestand via SFTP) en zet het volgende blok boven de regel die zegt /* Dat is alles, stop met bewerken! Veel plezier met publiceren. */. Alles wat je onder die regel zet, wordt in sommige bootstrap-paden genegeerd. Dezelfde regel uit het wp-config.php referentieartikel geldt ook hier: nieuwe defines gaan boven de marker.

// Redis Object Cache connectie
define( 'WP_REDIS_HOST', '127.0.0.1' );
define( 'WP_REDIS_PORT', 6379 );
define( 'WP_REDIS_TIMEOUT', 1 );
define( 'WP_REDIS_READ_TIMEOUT', 1 );

// Unieke prefix zodat deze site niet botst met andere sites op dezelfde Redis
define( 'WP_REDIS_PREFIX', 'jouwsite-prod' );

// Optioneel: database-nummer (0-15) voor logische scheiding op een gedeelde Redis
define( 'WP_REDIS_DATABASE', 0 );

De juiste hostwaarde hangt af van waar Redis draait. Op een single server met Redis op localhost klopt 127.0.0.1. Bij een managed host gebruik je de hostname die je van ze krijgt. In Docker Compose: zie het aparte kopje verderop (het antwoord is redis, niet 127.0.0.1).

De WP_REDIS_PREFIX-valkuil

Deze constant is het belangrijkste item uit dat blok zodra je Redis deelt met andere WordPress-sites, en het is ook de constant waar tutorials het vaakst de mist mee ingaan. In pluginversie 2.0.0 is de eigen prefix-constant hernoemd van WP_CACHE_KEY_SALT naar WP_REDIS_PREFIX, om verwarring met een gelijknamige WordPress core constant te voorkomen. Dat staat in de changelog van de plugin. Elke tutorial die nog define('WP_CACHE_KEY_SALT', ...) laat zien, gebruikt de v1.x-syntax. De oude naam wordt voor terugwaartse compatibiliteit nog gelezen, maar WP_REDIS_PREFIX is de huidige, officiële naam en de enige die je in nieuwe configs moet schrijven.

Waarom die prefix zo belangrijk is: Redis is één grote key-value store. Twee WordPress-sites die allebei wp_cache_set('post_123', $data) roepen tegen dezelfde Redis-instance, schrijven naar dezelfde key en lezen elkaars data. Met WP_REDIS_PREFIX ingesteld op een unieke string per site (jouwsite-prod, jouwsite-staging, klant-a enzovoort) krijgt elke key een eigen namespace en kunnen die sites elkaars cache niet meer corrumperen. Zet 'm dus voordat je de drop-in aanzet. Wijzig je de prefix later, dan gooi je de bestaande cache weg.

Draai je een wachtwoord-beveiligde Redis, dan gooi je de credentials er ook bij:

define( 'WP_REDIS_PASSWORD', 'jouw-redis-wachtwoord' );
// Redis 6+ ACL-user, als dat van toepassing is
define( 'WP_REDIS_USERNAME', 'wordpress' );

Sla het bestand op.

Stap 3: de object cache drop-in aanzetten

Twee gelijkwaardige routes. Beide kopiëren redis-cache/includes/object-cache.php naar wp-content/object-cache.php.

Via het dashboard. Ga naar Instellingen > Redis. Je ziet een statuspaneel met velden voor Status, Client, Drop-in, Filesystem, Global Prefix en Host/Port. Bovenaan staat een grote Enable Object Cache-knop. Druk erop. De pagina herlaadt en Status staat daarna op "Connected" met een groen bolletje. Drop-in zegt "Valid".

Via WP-CLI. Vanuit de WordPress-root:

wp redis enable

Verwachte output:

Object cache enabled.
Success: Updated drop-in file.

Beide routes doen precies hetzelfde. Het WP-CLI-commando is handig voor automation, Composer-workflows, containers zonder admintoegang en sites waar DISALLOW_FILE_MODS aan staat (waardoor de admin-knop geen bestanden kan schrijven). In de INSTALL.md van de plugin staan beide methodes als gelijkwaardig, niet als alternatief voor een verplichte WP-CLI-stap. Het idee dat "pluginversie 2.0 WP-CLI verplicht heeft gemaakt voor de drop-in" klopt niet: WP-CLI-ondersteuning bestaat al sinds pluginversie 1.3.4, en de admin-knop werkt gewoon nog in 2.7.0.

Stap 4: de verbinding verifiëren

Je weet dat het gelukt is als Instellingen > Redis toont:

  • Status: Connected (groen)
  • Drop-in: Valid
  • Client: PhpRedis of Predis (wat je hebt)
  • Prefix: de waarde die je in WP_REDIS_PREFIX hebt gezet

Toont het Status-veld iets anders dan "Connected", spring dan door naar het troubleshooting-kopje.

Als je SSH-toegang hebt: je kunt de verbinding ook vanaf de commandline checken met WP-CLI:

wp redis status

Verwachte output bij een werkende setup:

Status: Connected
Client: PhpRedis (v5.3.7)
Drop-in: Valid
Disabled: No
Ping: 1
Errors: 0

Als Ping leeg is of Errors niet nul, dan staat de drop-in er wel maar kan hij Redis niet echt bereiken.

Om te bevestigen dat Redis ook echt data binnenkrijgt, draai je dit tegen de Redis-server zelf:

redis-cli -h 127.0.0.1 -p 6379
> KEYS jouwsite-prod:*
> INFO stats

KEYS laat elke key zien die onder je prefix is weggeschreven (draai dit liever niet in productie op een grote database; SCAN is veiliger). INFO stats toont keyspace_hits en keyspace_misses. Naarmate er verkeer door de site komt, moet de hit count gestaag oplopen; dat is de meetbare impact. Op een gemiddelde WordPress-voorkant schrijft de eerste ongecachete request tussen de 40 en 200 keys weg, en de tweede request leest de meeste daarvan weer uit Redis.

Stap 5: de impact meten

Redis object cache roept zijn eigen succes niet van de daken. De impact zie je op twee plekken:

  • Time to first byte op admin-pagina's en ingelogde front-endpagina's. Meet het verschil door /wp-admin/ te bezoeken als ingelogde gebruiker, met Chrome DevTools > Network, en vergelijk het Waiting (TTFB)-getal van het hoofddocument. Op een WooCommerce-site met 15 actieve plugins zie ik de admin-TTFB routineus zakken van rond de 900 ms naar 250 ms zodra Redis het overneemt. De precieze getallen hangen volledig af van hoe query-zwaar je plugins zijn. Daarom loopt het artikel over hoge TTFB door het onderliggende kostenmodel.
  • Aantal databasequeries per request. De Query Monitor plugin zet het aantal queries per request in de admin bar. Op een ingelogde admin-pagina zakt dat getal vaak van 400-600 queries bij een koude cache naar ruim onder de 100 bij een warme cache, omdat transients en options die anders naar wp_options zouden gaan nu vanuit Redis opgelost worden. Het artikel over een trage database legt uit waarom juist wp_options zo vaak de bottleneck is, en object caching is daar de directe fix voor.

Verwacht geen verbetering op anonieme front-end-TTFB als je al een goed ingestelde page cache hebt. Cache hits draaien nooit PHP, dus Redis krijgt die requests helemaal niet te zien. De winst zit in de requests die de page cache bewust overslaan: admin, ingelogd, cart, checkout, REST API, AJAX.

Docker Compose setup

WordPress en Redis als losse containers draaien in Docker Compose is de plek waar Redis-setups het vaakst stil mislukken, en de reden is bijna altijd dezelfde: 127.0.0.1 betekent niet wat je denkt dat het betekent binnen een container. Elke container heeft zijn eigen loopback-interface, dus 127.0.0.1 vanuit de WordPress-container wijst naar de WordPress-container zelf, waar Redis helemaal niet draait. De fix is om de service name van Redis als hostname te gebruiken.

Een minimale werkende docker-compose.yml:

services:
  wordpress:
    image: wordpress:php8.3-fpm
    depends_on:
      - redis
      - db
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: change-me
    volumes:
      - wp-content:/var/www/html/wp-content

  redis:
    image: redis:7.2-alpine
    command: ["redis-server", "--maxmemory", "256mb", "--maxmemory-policy", "allkeys-lru"]
    expose:
      - "6379"

  db:
    image: mariadb:11
    environment:
      MARIADB_ROOT_PASSWORD: change-me
      MARIADB_DATABASE: wordpress
      MARIADB_USER: wordpress
      MARIADB_PASSWORD: change-me

volumes:
  wp-content:

En het bijpassende wp-config.php-blok:

define( 'WP_REDIS_HOST', 'redis' );   // de service name uit Compose, niet 127.0.0.1
define( 'WP_REDIS_PORT', 6379 );
define( 'WP_REDIS_PREFIX', 'jouwsite-prod' );

De flags --maxmemory en --maxmemory-policy allkeys-lru op de Redis-commandline zijn het waard om te kennen. Zonder memory cap groeit Redis door totdat de container door de OOM-killer om zeep wordt geholpen. Met allkeys-lru gooit Redis de minst recent gebruikte keys eruit zodra hij tegen de limiet aanloopt, en dat is precies wat je wilt voor een cache (bij een primaire data store zou je noeviction willen). De Redis-documentatie over eviction policies beschrijft de hele set als je iets anders nodig hebt.

Na docker compose up -d spring je de WordPress-container in en draai je wp redis enable && wp redis status om de drop-in te installeren en de verbinding te bevestigen.

Troubleshooting van verbindingsfouten

Drie foutmeldingen dekken bijna elk probleem.

Status: Not connected of Drop-in: Invalid. Of de drop-in is niet geïnstalleerd (de "Enable Object Cache"-stap is overgeslagen), of hij is wel geïnstalleerd maar kan de Redis-server niet bereiken. Begin met wp redis status en kijk naar het Errors-veld. Staat daar Connection refused, dan luistert Redis niet op de host en port die je hebt ingesteld. Staat er Authentication failed, dan klopt je WP_REDIS_PASSWORD niet of ontbreekt hij. Staat er Name or service not known, dan resolvet de hostname niet; in Docker Compose betekent dat meestal dat je 127.0.0.1 hebt geschreven in plaats van de service name.

Redis server went away of wegvallende verbindingen. De standaardwaardes voor WP_REDIS_TIMEOUT en WP_REDIS_READ_TIMEOUT zijn krap (1 seconde). Op een trage netwerkverbinding of tijdens een Redis-herstart breekt de verbinding daardoor weg. Zet beide op 2 of 3 seconden en voeg WP_REDIS_RETRY_INTERVAL toe op 100 (milliseconden) om tijdelijke dips te overleven:

define( 'WP_REDIS_TIMEOUT', 2 );
define( 'WP_REDIS_READ_TIMEOUT', 2 );
define( 'WP_REDIS_RETRY_INTERVAL', 100 );

De drop-in werkt, maar de hit rate blijft op nul. Meest voorkomende oorzaak: een andere caching-plugin (W3 Total Cache of LiteSpeed Cache met eigen object cache aan) schrijft zijn eigen object-cache.php over de Redis-drop-in heen. Pluginversie 2.4.2 en later vangt dit actief af, maar een verkeerd geconfigureerde W3TC kan er nog steeds om vechten. Check de inhoud van wp-content/object-cache.php: staat er W3 Total Cache of LiteSpeed in de comments, zet dan de object cache van de concurrerende plugin uit en draai wp redis enable opnieuw.

Krijg je het daarna nog steeds niet werkend, verzamel dan: (a) de output van wp redis status, (b) het volledige Redis-blok uit wp-config.php met het wachtwoord weggehaald, (c) de output van redis-cli -h <jouw-host> -p <jouw-port> ping gedraaid vanaf dezelfde server als WordPress, (d) de pluginversie via wp plugin list | grep redis-cache, (e) de PHP-extensies via php -m | grep -i redis, en (f) de huidige inhoud van wp-content/object-cache.php (de eerste 30 regels zijn genoeg om te zien welke implementatie geïnstalleerd staat). Met die set kan elke hosting-supportengineer je binnen een paar minuten vertellen waar het breekt.

Wanneer Memcached logischer is dan Redis

Redis en Memcached zijn allebei persistente object caches die hetzelfde gat vullen: de in-memory WP_Object_Cache vervangen door iets dat tussen requests blijft staan. Allebei hebben ze een WordPress-drop-in. Allebei werken ze. Het eerlijke verschil is kleiner dan het lijkt:

  • Redis ondersteunt persistence naar disk, replicatie, pub/sub en rijkere datatypes. Voor een WordPress object cache gebruik je die extra's meestal niet, maar persistence-naar-disk is handig op een VPS waar je Redis af en toe herstart en de cache niet elke keer opnieuw wilt opwarmen.
  • Memcached is simpeler en net iets sneller op de ruwe key-value-operaties die WordPress eigenlijk doet. Biedt je host Memcached en geen Redis, dan is dat een prima keuze, geen compromis. De community-onderhouden Memcached Object Cache drop-in vult dezelfde rol als Redis Object Cache.

Mijn standaardadvies in 2026 is Redis, simpelweg omdat elke managed WordPress-host het ondersteunt en de meeste hosting-tutorials ervan uitgaan. Maar erf je een server waar Memcached al draait en goed is ingesteld, dan is er geen enkele reden om hem eruit te trekken voor Redis. De winst zit in het feit dat er überhaupt een persistente object cache draait. Welke van de twee het wordt, is veel minder belangrijk dan de vraag of de drop-in er staat en of de hit rate oploopt.

Klaar met terugkerende traagheid?

Traagheid komt vaak terug na snelle fixes. Professioneel onderhoud houdt updates, caching en limieten consequent op orde.

Laat je WordPress site onderhouden

Doorzoek deze site

Begin met typen om te zoeken, of blader door de kennisbank en blog.