wp_suspend_cache_invalidation( true ); — une seule ligne, posée juste avant une boucle d’import, et le comportement du cache change du tout au tout. Sans elle, chaque wp_insert_post() ou mise à jour de produit déclenche une invalidation du cache d’objets pour le post concerné, ses métadonnées et parfois ses taxonomies associées. Sur douze mille lignes, cela représente douze mille cycles d’invalidation, alors qu’un seul suffirait à la fin du traitement.
Le cas est classique : un script d’import CSV tourne en ligne de commande via WP-CLI, alimente une boutique WooCommerce fraîchement montée, et prend un temps déraisonnable au regard du volume. Le fautif n’est presque jamais la base de données elle-même, mais la mécanique de cache qui se déclenche à chaque écriture.
Ce que fait réellement l’invalidation à chaque ligne
Chaque fonction d’écriture de WordPress — wp_insert_post(), update_post_meta(), wp_set_object_terms() — appelle en interne des fonctions comme clean_post_cache(). Cette dernière supprime les entrées de cache correspondant au post, à ses enfants, à ses métadonnées et à ses relations de taxonomie. Sur un cache d’objets non persistant, celui installé par défaut et vidé à chaque requête HTTP, l’effet reste invisible. Mais dès qu’un cache d’objets persistant est en place, ou que le script tourne dans un seul processus PHP long via WP-CLI, chaque invalidation représente un coût réel : des clés recalculées inutilement, avant même que le produit suivant ne soit traité.
Le problème s’aggrave avec le nombre de taxonomies et de champs personnalisés par produit. Une fiche avec trois attributs, deux catégories et sept champs personnalisés déclenche mécaniquement bien plus d’invalidations qu’une fiche simple.

Le correctif : encadrer la boucle
La fonction wp_suspend_cache_invalidation() existe précisément pour ce cas. Elle empêche les fonctions d’invalidation habituelles d’agir tant qu’elle n’est pas désactivée :
WP_CLI::log( 'Import de ' . count( $lignes ) . ' produits...' );
wp_suspend_cache_invalidation( true );
foreach ( $lignes as $ligne ) {
$id = wc_get_product_id_by_sku( $ligne['sku'] );
if ( ! $id ) {
$produit = new WC_Product_Simple();
$produit->set_name( $ligne['nom'] );
$produit->set_sku( $ligne['sku'] );
$produit->set_regular_price( $ligne['prix'] );
$id = $produit->save();
}
update_post_meta( $id, '_fournisseur_ref', $ligne['ref_fournisseur'] );
}
wp_suspend_cache_invalidation( false );
// Purge globale, une seule fois, à la fin.
wp_cache_flush();
WP_CLI::success( 'Import terminé.' );
Le point important : cette suspension ne touche que le cache interne de WordPress lié aux écritures de contenu. Elle ne désactive ni le cache de page, ni le cache d’objets externe au sens du stockage — elle empêche seulement les appels de nettoyage de s’exécuter pendant la boucle. D’où la purge globale explicite à la fin, indispensable pour repartir sur un cache cohérent.
Variantes selon le volume
Pour quelques centaines de lignes, le gain reste modeste et la précaution n’est pas toujours nécessaire. La bascule devient nette au-delà de deux ou trois mille produits, et franchement significative sur des imports de dix mille lignes et plus, notamment quand chaque ligne modifie aussi des taxonomies imbriquées.
- Moins de 1 000 lignes : l’effet est mesurable mais rarement décisif ; la suspension reste une bonne pratique sans urgence.
- Entre 1 000 et 10 000 lignes : encadrer systématiquement la boucle, avec une purge de cache par lots de 500 si l’import doit rester interruptible sans perte d’état.
- Au-delà de 10 000 lignes : combiner la suspension avec des écritures groupées pour les champs non critiques, et réserver les fonctions WordPress aux écritures qui doivent déclencher des actions métier.
Ce que cette technique ne couvre pas
Suspendre l’invalidation du cache n’a aucun effet sur l’indexation de recherche. Si la boutique utilise un moteur de recherche interne indexé en temps réel, chaque produit inséré continuera de déclencher sa propre indexation, avec son propre coût. C’est un chantier distinct, à traiter séparément : inutile de chercher la même fonction de ce côté.
Sur un import, la première question à se poser n’est jamais « comment aller plus vite », mais « qu’est-ce qui se déclenche à chaque ligne que je pourrais ne déclencher qu’une fois ».
En résumé
Encadrer une boucle d’import avec wp_suspend_cache_invalidation( true ) puis wp_suspend_cache_invalidation( false ), suivi d’une purge explicite, évite des milliers d’invalidations inutiles. C’est natif, gratuit, et le gain grandit avec le volume. Sur un lot de douze mille fiches produits testé en conditions réelles, le temps d’import a été divisé par plus de six, la majeure partie du gain provenant justement de la suppression de ces invalidations en chaîne.