La Transients API est l’une de ces fonctionnalités que tout développeur WordPress croit connaître après avoir lu deux lignes de documentation, et qu’il redécouvre complètement le jour où un client active un cache d’objets Redis en production. Le comportement change alors du tout au tout, sans qu’une seule ligne de code de l’extension n’ait bougé.
Voici ce qu’il faut vraiment comprendre avant d’utiliser set_transient dans une extension destinée à tourner sur des hébergements variés.
Le principe : une donnée temporaire avec expiration
Un transient se manipule avec trois fonctions symétriques à l’API des options : set_transient(), get_transient() et delete_transient(). La différence avec update_option() tient dans un quatrième argument, la durée de vie en secondes.
function kaolin_recuperer_taux_change() {
$taux = get_transient( 'kaolin_taux_eur_usd' );
if ( false === $taux ) {
$reponse = wp_remote_get( 'https://api.exemple-taux.test/eur-usd' );
if ( is_wp_error( $reponse ) ) {
return false;
}
$taux = (float) wp_remote_retrieve_body( $reponse );
set_transient( 'kaolin_taux_eur_usd', $taux, HOUR_IN_SECONDS );
}
return $taux;
}
Le point que beaucoup ratent : get_transient() peut retourner false pour deux raisons différentes, un transient expiré ou une valeur qui vaut réellement false. Si votre donnée peut légitimement être booléenne, préférez encapsuler la valeur dans un tableau plutôt que de tester directement le retour brut.
Sans cache d’objets persistant : deux lignes dans wp_options
Sur la grande majorité des hébergements mutualisés, sans Redis ni Memcached configuré, chaque transient se traduit concrètement par deux lignes dans la table wp_options : une pour la valeur (_transient_kaolin_taux_eur_usd), une pour l’horodatage d’expiration (_transient_timeout_kaolin_taux_eur_usd).

C’est important à savoir pour deux raisons. D’abord, ces options sont chargées avec autoload désactivé par défaut sur les transients récents, ce qui évite qu’elles alourdissent chaque chargement de page comme le ferait une option classique. Ensuite, l’expiration n’est pas gérée par une tâche automatique : WordPress vérifie la date d’expiration au moment de la lecture, via get_transient(). Un transient jamais relu après son expiration reste donc physiquement présent en base, potentiellement pendant des mois.
- Sans cache persistant, un transient expiré mais jamais relu pollue durablement
wp_options - La commande
wp transient delete --expiredde WP-CLI permet un nettoyage périodique - Un transient à durée de vie très courte sur un site à fort trafic peut générer un nombre élevé d’écritures en base
Avec un cache d’objets persistant : tout change
Dès qu’un plugin de cache d’objets persistant est actif (Redis Object Cache, Memcached Object Cache, ou une solution propriétaire d’hébergeur), la Transients API bascule entièrement sur le cache d’objets. Les fonctions set_transient, get_transient et delete_transient ne touchent alors plus du tout wp_options : elles délèguent à wp_cache_set et consorts.
La conséquence la plus surprenante pour qui découvre ce comportement : un transient stocké de cette façon peut disparaître à tout moment, sans respecter la durée demandée, si le cache décide d’évincer cette clé faute de mémoire disponible. Ce n’est pas un bug, c’est le contrat même d’un cache d’objets. Une extension qui suppose qu’un transient survivra forcément jusqu’à son expiration programmée prend un risque.
Ne stockez jamais dans un transient une donnée que votre extension ne sait pas reconstruire à la volée si elle disparaît prématurément. C’est un cache, pas un espace de stockage garanti.
Choisir la bonne durée de vie
Le choix de la durée dépend directement de la fraîcheur nécessaire et du coût de régénération de la donnée. Pour l’appel de taux de change du projet évoqué plus haut, une heure suffisait largement. Pour un résultat de requête coûteuse peu sensible à la fraîcheur, une journée entière (DAY_IN_SECONDS) est souvent raisonnable.
MINUTE_IN_SECONDS,HOUR_IN_SECONDS,DAY_IN_SECONDSetWEEK_IN_SECONDSsont des constantes natives, à préférer à des valeurs en dur- Une durée de zéro équivaut à ne jamais expirer par le mécanisme de la Transients API elle-même
- Un transient sans expiration explicite reste soumis à l’éviction du cache d’objets, s’il est actif
Invalider un transient au bon moment
L’expiration passive ne suffit pas toujours : si la donnée source change (un article est modifié, un tarif est mis à jour dans un CPT), mieux vaut supprimer explicitement le transient concerné plutôt qu’attendre son expiration naturelle.
add_action( 'save_post_tarif', function ( $post_id ) {
delete_transient( 'kaolin_taux_eur_usd' );
} );
Cette invalidation ciblée, déclenchée sur le hook approprié, évite d’afficher une donnée obsolète pendant toute la durée de vie restante du transient, ce qui serait particulièrement gênant pour une information aussi sensible qu’un taux de change.
En résumé
La Transients API n’est pas un simple raccourci vers wp_options : c’est une abstraction qui s’adapte automatiquement à l’infrastructure de cache disponible, du mutualisé le plus basique au cluster Redis le plus sophistiqué. Écrire une extension qui la respecte, c’est accepter qu’un transient puisse disparaître avant l’heure, et toujours prévoir la régénération de la donnée en conséquence.