Ce qu’on voit : un site de comparateur de prix, sans cache d’objet persistant Redis ni Memcached configuré, voit son temps de réponse se dégrader progressivement sur plusieurs mois, sans qu’aucune modification de code n’ait été déployée entre-temps. Un contrôle de la table wp_options révèle plus de 210 000 lignes, contre quelques centaines attendues sur une installation WordPress standard avec une dizaine d’extensions actives.
Pourquoi c’est un problème
Sans backend de cache d’objet persistant configuré, l’API de transients de WordPress stocke ses données directement dans la table wp_options, chaque transient occupant deux lignes : une pour la valeur elle-même, préfixée _transient_, une pour son délai d’expiration, préfixée _transient_timeout_. C’est un comportement de repli documenté et parfaitement normal en soi.
Le problème apparaît quand une extension construit ses clés de transient de façon dynamique, par exemple en y incluant un identifiant de session ou une combinaison de paramètres de recherche propres à chaque visiteur. Sur ce comparateur de prix, l’extension de recherche à facettes générait une clé de transient différente pour chaque combinaison de filtres sélectionnés par chaque visiteur, avec une expiration réglée à sept jours, jugée trop longue par rapport au volume de combinaisons possibles.
La conséquence directe : la table wp_options grossissait de plusieurs centaines de lignes par jour, sans jamais réellement se vider, puisque l’expiration à sept jours laissait largement le temps à de nouvelles combinaisons de s’accumuler avant que les anciennes ne soient éligibles à suppression.
Pourquoi une table wp_options gonflée ralentit tout
La table wp_options joue un rôle particulier dans WordPress : les options marquées autoload à yes sont chargées en une seule requête à chaque exécution de PHP, dès l’initialisation de WordPress, avant même le traitement de la requête en cours. Si une partie significative des transients ajoutés hérite de cet autoload, chaque page chargée doit désormais transporter en mémoire des dizaines de milliers de lignes inutiles à la requête en cours.

Quoi faire : diagnostiquer avant de nettoyer
La première étape a consisté à quantifier précisément le problème avec une requête SQL directe, plutôt que de nettoyer à l’aveugle :
SELECT COUNT(*), autoload FROM wp_options WHERE option_name LIKE '_transient_%' GROUP BY autoload;
Le résultat a confirmé qu’une part importante de ces transients portait bien l’autoload à yes, expliquant la dégradation progressive du temps de réponse constatée sur l’ensemble du site, pas seulement sur les pages de recherche à facettes.
Quoi faire : nettoyer sans casser la fonctionnalité
WP-CLI fournit une commande dédiée à la suppression des transients expirés, à exécuter en premier lieu :
wp transient delete --expired
Cette commande n’a supprimé qu’une fraction du problème, la majorité des transients n’étant pas encore expirés selon leur délai de sept jours. Un script complémentaire, ciblant spécifiquement le préfixe de clé propre à l’extension de recherche à facettes, a permis de supprimer les entrées les plus anciennes sans toucher aux autres transients légitimes du site :
wp db query "DELETE FROM wp_options WHERE option_name LIKE '_transient_facette_%' AND option_id NOT IN (SELECT option_id FROM (SELECT option_id FROM wp_options WHERE option_name LIKE '_transient_facette_%' ORDER BY option_id DESC LIMIT 500) t)"
Quoi faire : corriger la cause plutôt que le symptôme
Le nettoyage ponctuel ne résolvait pas le problème de fond, qui allait recommencer à s’accumuler dès le lendemain. La correction durable a consisté à réduire la durée d’expiration de sept jours à deux heures, jugée largement suffisante pour l’usage réel de cache de résultats de recherche, et à retirer explicitement l’autoload de ces transients via un filtre disponible depuis WordPress 5.4, pre_wp_unique_id_from_values n’étant pas concerné ici, mais un simple contrôle du préfixe utilisé lors de l’enregistrement des options concernées.
- Toujours donner une expiration courte et réaliste à un transient dont la clé varie selon le visiteur.
- Vérifier régulièrement la taille de
wp_optionset la répartition de l’autoload sur un site sans cache d’objet persistant. - Envisager un cache d’objet persistant type Redis dès qu’un site génère un volume important de transients à courte durée de vie.
Pour aller plus loin
Ce cas ne traite pas la question de l’autoload en général, déjà documentée séparément pour d’autres types d’options : il se concentre spécifiquement sur le cas où l’API de transients elle-même, pourtant conçue pour améliorer la performance, finit par l’aggraver faute d’une conception de clés adaptée au volume réel de combinaisons possibles.