Un client avait pris l’habitude de purger tout le cache de page après chaque mise à jour de thème « pour être sûr que tout est à jour ». Problème : la purge totale renvoyait chaque visiteur suivant vers une génération PHP complète, non mise en cache, ce qui provoquait ponctuellement des pics de charge CPU proches de la saturation sur les pages les plus consultées, exactement au moment où plusieurs visiteurs arrivaient en même temps sur une page fraîchement vidée.
La solution n’est pas d’éviter la purge, souvent nécessaire, mais de la faire suivre immédiatement d’un préchauffage (warmup) maîtrisé : générer soi-même les pages les plus importantes avant que les vrais visiteurs ne le fassent, sans pour autant infliger au serveur une rafale de requêtes simultanées qui recréerait le problème initial.
Problème : purger vide, mais ne remplit pas
Un cache de page purgé revient à un état neutre : la prochaine requête sur chaque URL déclenchera une génération complète par PHP, potentiellement coûteuse si la page contient des requêtes SQL lourdes ou des appels à des API externes. Sur un site à fort trafic, plusieurs visiteurs peuvent arriver simultanément sur la même page tout juste purgée, ce qui peut, selon les configurations de cache, déclencher plusieurs générations parallèles de la même page avant que le cache ne soit reposé (un phénomène parfois appelé « cache stampede »).
Construire la liste des pages à réchauffer

Le sitemap XML généré nativement par WordPress depuis la version 5.5 (accessible sur /wp-sitemap.xml) constitue une base fiable et déjà structurée pour construire la liste des URL à réchauffer, sans avoir à interroger la base de données soi-même. Un script bash simple suffit à extraire les URL :
#!/bin/bash
curl -s https://exemple.fr/wp-sitemap-posts-post-1.xml \
| grep -oP '(?<=<loc>).*?(?=</loc>)' > urls-a-rechauffer.txt
wc -l urls-a-rechauffer.txt
Pour un site avec des pages plus importantes que d’autres (accueil, catégories principales, pages produits phares), il est préférable de construire une liste priorisée manuelle plutôt que de réchauffer l’intégralité du sitemap dans l’ordre alphabétique, souvent sans rapport avec le trafic réel de chaque page.
Réchauffer sans surcharger : limiter le débit
Le script de warmup doit imposer une limite de débit, sous peine de reproduire artificiellement le pic de charge qu’on cherche justement à éviter. Sur l’hébergement testé (quatre cœurs PHP-FPM dédiés au warmup), 12 requêtes par seconde s’est révélé être un débit soutenable sans impact perceptible sur les visiteurs réels pendant l’opération.
#!/bin/bash
DEBIT=12
while read -r url; do
curl -s -o /dev/null -w "%{http_code} %{time_total}s %{url}\n" "$url"
sleep "$(echo "scale=3; 1/$DEBIT" | bc)"
done < urls-a-rechauffer.txt
Cette version simple traite les URL séquentiellement avec une pause calculée. Une variante plus robuste utilise xargs -P pour paralléliser un nombre limité de requêtes simultanées (par exemple quatre), tout en gardant un débit global maîtrisé, ce qui réduit le temps total de warmup sur un grand sitemap sans dépasser la capacité du serveur.
Automatiser après chaque purge
Le warmup a été branché directement après la commande de purge dans le script de déploiement, via WP-CLI pour la purge du cache d’objets et un appel au script de warmup pour la purge du cache de page :
wp cache flush
wp cli cache flush
bash /opt/scripts/warmup.sh >> /var/log/warmup.log 2>&1 &
Le warmup est lancé en tâche de fond (& final) pour ne pas bloquer le reste du script de déploiement, avec un journal dédié permettant de vérifier a posteriori qu’aucune URL n’est revenue en erreur.
Variantes selon le contexte
- Pour un site multilingue, prioriser d’abord la langue majoritaire du trafic avant de réchauffer les langues secondaires.
- Pour un site WooCommerce, exclure volontairement les pages panier et compte du warmup, ces pages n’étant de toute façon pas destinées à rester en cache.
- Pour un très gros catalogue, réchauffer d’abord les 200 pages les plus consultées selon les statistiques d’analytics, puis élargir progressivement plutôt que de viser l’exhaustivité dès la première passe.
En résumé
Une purge de cache sans warmup transfère simplement le coût de génération vers les premiers visiteurs qui passent après coup, au pire moment possible. Un script de préchauffage simple, basé sur le sitemap natif de WordPress et un débit volontairement limité, referme cette fenêtre de vulnérabilité sans demander d’outillage compliqué. C’est un des rares cas où quelques lignes de bash suffisent à éliminer un vrai risque de production.