12 000 pages republiées en une seule opération : c’est le volume atteint lors d’une réorganisation éditoriale sur un site de presse à très fort trafic, construit avec Elementor, quand une nouvelle taxonomie de rubriques a nécessité de réattribuer en masse les catégories d’un historique de plus de 400 000 pages. Chaque page réattribuée devait déclencher une purge de son cache, celui de sa page de rubrique, et celui de la page d’accueil si elle y figurait parmi les contenus mis en avant.
La stratégie de purge en place jusque-là fonctionnait bien pour un rythme de publication normal (une centaine d’articles par jour), mais s’est révélée totalement inadaptée face à une opération de cette ampleur : la purge globale du cache, déclenchée automatiquement à chaque publication, a saturé le serveur en quelques minutes lors du lancement de la réorganisation.
Le problème de la purge globale à cette échelle
Le plugin de cache en place déclenchait, par défaut, une purge complète du cache de page à chaque publication ou modification de contenu, un comportement raisonnable à faible volume mais catastrophique à 12 000 opérations rapprochées : chaque purge globale force une régénération intégrale du cache au prochain visiteur, sur l’ensemble des 400 000 pages du site, pas seulement sur celles réellement modifiées.
Construire une file de purge sélective
La solution retenue introduit une file d’attente dédiée à la purge, alimentée par un hook sur la sauvegarde d’un article, et traitée par lots via WP-Cron plutôt que déclenchée immédiatement à chaque modification.

add_action('save_post', function ($post_id) {
if (wp_is_post_revision($post_id)) {
return;
}
global $wpdb;
$wpdb->insert($wpdb->prefix . 'file_purge_cache', [
'post_id' => $post_id,
'statut' => 'en_attente',
'date_ajout' => current_time('mysql'),
]);
});
add_action('traiter_file_purge', function () {
global $wpdb;
$lignes = $wpdb->get_results(
"SELECT * FROM {$wpdb->prefix}file_purge_cache WHERE statut = 'en_attente' LIMIT 200"
);
$urls_a_purger = [];
foreach ($lignes as $ligne) {
$urls_a_purger[] = get_permalink($ligne->post_id);
foreach (get_the_category($ligne->post_id) as $categorie) {
$urls_a_purger[] = get_category_link($categorie->term_id);
}
}
purger_urls_cloudflare(array_unique($urls_a_purger));
$ids = wp_list_pluck($lignes, 'id');
$wpdb->query(
"UPDATE {$wpdb->prefix}file_purge_cache SET statut = 'traite' WHERE id IN (" . implode(',', $ids) . ")"
);
});
if (!wp_next_scheduled('traiter_file_purge')) {
wp_schedule_event(time(), 'toutes_les_trois_minutes', 'traiter_file_purge');
}
Un traitement par lots de 200 URL
La taille de lot de 200 URL par exécution a été déterminée empiriquement, après plusieurs essais sur l’environnement de recette : au-delà, l’appel à l’API de purge Cloudflare dépassait régulièrement le délai d’exécution alloué à la tâche planifiée.
Piloter la file via WP-CLI pendant l’opération
Pour l’opération de réattribution des 12 000 pages elle-même, une commande WP-CLI personnalisée a permis de suivre en temps réel la profondeur de la file d’attente, sans attendre le rythme normal des tâches planifiées.
wp eval 'global $wpdb; echo $wpdb->get_var(
"SELECT COUNT(*) FROM {$wpdb->prefix}file_purge_cache WHERE statut = '\''en_attente'\''"
);'
Les chiffres après refonte de la stratégie
| Indicateur | Purge globale (avant) | File sélective (après) |
|---|---|---|
| Temps de propagation moyen d’une modification | 18 minutes | 4,5 minutes |
| Charge serveur pendant l’opération de masse | Saturation observée | Stable, sous 40 % |
Cette stratégie de purge ne traite pas la question du CDN d’images du site, géré séparément par une configuration dédiée, ni celle de la monétisation publicitaire, dont les scripts suivent leur propre logique de rafraîchissement indépendante du cache de page.
Une purge de cache qui fonctionne à cent publications par jour peut devenir le goulot d’étranglement principal d’un site le jour où le volume est multiplié par cent : la robustesse d’une architecture se juge à son comportement sous charge inhabituelle, pas sous charge normale.
En résumé
Passer d’une purge globale systématique à une file de purge sélective traitée par lots a permis d’absorber une opération de réattribution de 12 000 pages sans dégradation du service, tout en réduisant de façon générale le temps de propagation moyen d’une modification. Le gain se paie par une complexité d’architecture supplémentaire, justifiée uniquement à ce volume de contenu.