Transients vs object cache: wanneer gebruik je wat

WordPress transients of object cache? Ontdek de verschillen, voordelen en valkuilen zodat je weet wanneer je welke caching-strategie kiest.

22 april 20267 min leestijdDoor We Develop Communication

Als je serieus aan WordPress performance werkt, kom je vroeg of laat bij twee begrippen uit: transients en object cache. Beide beloven snellere pagina's en minder druk op de database, maar ze lossen het probleem op een andere manier op. En juist die verwarring zorgt ervoor dat developers vaak de verkeerde tool kiezen, of erger, allebei halfslachtig inzetten.

In dit vergelijk leg ik uit wanneer je transients gebruikt, wanneer je beter voor een persistente object cache kiest, en hoe je ze samen inzet zonder dat je site omvalt zodra Redis even niet bereikbaar is.

Wat zijn transients in WordPress?

Transients zijn een eenvoudige caching-API in WordPress, bedoeld voor het tijdelijk opslaan van data met een verloopdatum. Denk aan het resultaat van een externe API-call, een zware WP_Query of een berekende statistiek.

De API bestaat uit drie functies:

  • set_transient( $key, $value, $expiration )
  • get_transient( $key )
  • delete_transient( $key )

Standaard worden transients opgeslagen in de wp_options-tabel. Zonder verdere configuratie is een transient dus gewoon een rij in je database, inclusief de bijbehorende query bij elke pageload.

Voorbeeld

$posts = get_transient( 'recent_featured_posts' );

if ( false === $posts ) {
    $posts = new WP_Query( [
        'posts_per_page' => 5,
        'meta_key'       => 'featured',
        'meta_value'     => '1',
    ] );

    set_transient( 'recent_featured_posts', $posts, HOUR_IN_SECONDS );
}

Simpel, leesbaar en ingebouwd. Dat is de kracht van transients.

Wat is object cache?

Object cache is een mechanisme waarmee WordPress objecten (queries, options, metadata) in het geheugen bewaart, zodat ze binnen één request, of met een persistente backend ook tussen requests, niet opnieuw hoeven te worden opgehaald.

Out of the box draait WordPress met een niet-persistente object cache: alles wordt alleen binnen dezelfde PHP-request hergebruikt. Pas als je een backend zoals Redis of Memcached koppelt, wordt het echt krachtig.

We gingen daar eerder dieper op in in Object caching met Redis in WordPress. Lees die post zeker als je Redis nog niet draait, de basis daarvan is een voorwaarde voor de rest van dit artikel.

Het cruciale verband: transients zitten bovenop object cache

Hier ontstaat bij veel developers verwarring. Transients en object cache zijn geen concurrenten. Ze opereren op verschillende niveaus:

  • Transients = een API (hoe je cache aanspreekt in code)
  • Object cache = een backend (waar die data fysiek wordt opgeslagen)

Als er een persistente object cache actief is, slaat WordPress transients automatisch daarin op in plaats van in wp_options. Je code blijft identiek, maar de opslag verschuift van database naar geheugen.

Je ziet dit gedrag in wp-includes/option.php, waar set_transient() controleert of wp_using_ext_object_cache() true retourneert en dan wp_cache_set() gebruikt in plaats van een databaseschrijfactie.

Wanneer kies je transients?

Transients zijn ideaal wanneer je:

  • Data wilt cachen met een duidelijke expiratie (bijvoorbeeld 1 uur, 24 uur, een week).
  • Leesbare code wilt die ook werkt op hostingomgevingen zonder object cache.
  • Langlevende data hebt die een cache-flush moet overleven (bij database-opslag).
  • Werkt aan plugins of themes die op willekeurige hostingomgevingen moeten werken.

Wees alert op autoloaded transients

Zonder object cache belanden transients in wp_options. Zonder expiratie worden ze soms zelfs autoload = yes, waardoor ze bij élke pageload meeladen. Dat is precies het probleem dat we behandelden in Autoloaded options: stille performance killer.

Vuistregel: geef transients altijd een expiratie, tenzij je heel bewust een permanente waarde wilt.

Wanneer kies je direct voor object cache?

De object cache API (wp_cache_get, wp_cache_set, wp_cache_delete) gebruik je als je:

  • Heel vaak per request dezelfde data nodig hebt (binnen één pageload).
  • Korte levensduur prima vindt, data mag verdwijnen zodra de cache geflusht wordt.
  • Cache groups wilt gebruiken om data logisch te ordenen.
  • Maximale snelheid wilt, zonder database-overhead als fallback.

Voorbeeld met cache groups

$user_stats = wp_cache_get( $user_id, 'user_stats' );

if ( false === $user_stats ) {
    $user_stats = calculate_user_stats( $user_id );
    wp_cache_set( $user_id, $user_stats, 'user_stats', 5 * MINUTE_IN_SECONDS );
}

Cache groups maken het eenvoudig om een hele categorie weg te gooien met wp_cache_flush_group( 'user_stats' ) (in WordPress 6.1+). Die granulariteit heb je met transients niet.

Directe vergelijking

Kenmerk Transients Object cache
API set_transient, get_transient wp_cache_set, wp_cache_get
Standaard opslag wp_options-tabel In-memory (request-scoped)
Met persistente backend Geheugen (via object cache) Redis, Memcached
Expiratie Verplicht in argument Optioneel
Cache groups Nee Ja
Overleeft cache-flush Ja (bij DB-opslag) Nee
Werkt zonder extra infra Ja Alleen request-scoped
Ideaal voor Externe API's, views, rapportages Zware queries, repetitieve lookups

Veelgemaakte fouten

1. Transients "gratis" achten

Elke transient in de database is een UPDATE of INSERT in wp_options. Op drukke sites kan dat juist de bottleneck worden die je probeerde op te lossen. Check regelmatig je wp_options-tabel, of lees onze database optimalisatie voor WordPress voor een dieper verhaal.

2. Vergeten een fallback in te bouwen

Als Redis even weg is, moet je code niet crashen. Dit patroon is veilig:

$data = wp_cache_get( 'heavy_report', 'reports' );

if ( false === $data ) {
    $data = build_heavy_report();

    if ( ! empty( $data ) ) {
        wp_cache_set( 'heavy_report', $data, 'reports', HOUR_IN_SECONDS );
    }
}

Die ! empty()-check voorkomt dat je een mislukte berekening cachet.

3. Caches niet invalideren bij mutaties

Cache die niet meebeweegt met je data is erger dan geen cache. Hook in op save_post, updated_user_meta of je eigen actions en roep delete_transient() of wp_cache_delete() aan. Zie ook Hoe werkt WP_Query onder de motorkap? voor de query-cache invalidation logica.

4. Te veel in een losse key proppen

Als je honderden items in één array cached en je wijzigt er één, moet je alles invalideren. Splits grote datasets op in logische keys per groep.

Welke kies je in de praktijk?

Hieronder een beslisrichtlijn die in de meeste projecten werkt:

  1. Is er een persistente object cache (Redis/Memcached) beschikbaar? → Ja: gebruik transients voor de meeste use cases, je krijgt gratis de snelheid van Redis. → Nee: gebruik transients spaarzaam en met expiratie, of schakel eerst een object cache backend in.

  2. Heb je cache groups of zeer korte TTL's nodig? → Gebruik direct de object cache API.

  3. Moet de data een cache-flush overleven? → Transients met database-opslag, of een eigen custom options-strategie.

  4. Werk je aan een plugin voor publieke distributie? → Transients, want je kunt geen Redis veronderstellen bij eindgebruikers.

Meten of het helpt

Caching invoeren zonder meten is gokken. Installeer Query Monitor en kijk of het aantal queries daadwerkelijk daalt na je cache-implementatie. Check ook de officiële Transients API-documentatie voor edge cases en de Object Cache API-docs voor signatures.

Voor een breder beeld van je bottlenecks verwijs ik naar WordPress performance bottlenecks herkennen en meten. Meten eerst, cachen daarna.

Conclusie: geen of-of, maar samenspel

Transients en object cache zijn geen keuze tussen twee rivalen. Ze vormen een stack: transients is de leesbare, portable API die developers gebruiken, en object cache (met Redis of Memcached) is de snelle backend die eronder ligt.

Op een serieuze productiesite zou je een persistente object cache moeten hebben draaien, en je transients-aanroepen erbovenop. Plugins en themes gebruiken transients omdat ze overal werken, en op hosting mét Redis krijg je automatisch de snelheidswinst cadeau.

Kies bewust, geef elke cache een expiratie, bouw fallbacks in, en invalideer waar nodig. Dan worden beide technieken een versneller in plaats van een verborgen bottleneck.

Veelgestelde vragen

Wat is het grootste verschil tussen transients en object cache?

Transients worden standaard in de database opgeslagen en blijven bestaan tot hun expiratie. Object cache leeft in het geheugen (bijvoorbeeld Redis) en is vluchtig, maar veel sneller.

Worden transients automatisch sneller met een object cache?

Ja. Als er een persistente object cache actief is, slaat WordPress transients daarin op in plaats van in de database. Dat maakt ze direct een stuk sneller, zonder dat je je code hoeft aan te passen.

Wanneer kies je bewust voor transients in de database?

Als je data ook zonder draaiende Redis beschikbaar moet zijn, bijvoorbeeld bij een eenvoudige hosting zonder object cache backend, of voor langlevende data die een cache-flush moet overleven.

Kan ik transients en object cache tegelijk gebruiken?

Ja, en dat is eigenlijk de standaardsituatie. Transients is een API; object cache is een backend. Samen krijg je leesbare code én maximale snelheid.

Hoe voorkom ik dat mijn site omvalt als de object cache weg is?

Zorg voor een fallback in je code: controleer of data geldig terugkomt en haal het anders opnieuw op uit de bron. Leun nooit blind op een cache-hit, en cache nooit lege of foutieve waarden.

Veelgestelde vragen

Klaar om digitaal te groeien?

Wij helpen Nederlandse bedrijven met webtechnologie en SEO-strategieën die écht werken. Neem vrijblijvend contact op.