Cent cinquante mille produits. C’est la taille du catalogue d’un site d’agence spécialisé dans le mobilier professionnel, avec un nombre de références qui rendait toute tentative d’indexation complète en une seule requête vouée à l’échec : timeout serveur systématique au-delà de dix minutes d’exécution, quelle que soit la configuration PHP côté hébergement.
L’extension officielle Algolia pour WooCommerce propose une indexation complète en un clic, pensée pour des catalogues de quelques milliers de références. Au-delà d’un certain volume, cette approche synchrone sature la mémoire PHP allouée et dépasse la limite de temps d’exécution, avant même d’avoir traité un dixième du catalogue.
Découper en lots via Action Scheduler
La première décision d’architecture a été d’abandonner l’indexation en un bloc au profit d’un découpage en lots de 500 produits, chacun traité par une tâche Action Scheduler distincte, plutôt que par une seule tâche cron longue. Ce choix permet à chaque tâche de rester sous la limite de temps d’exécution PHP, tout en laissant WordPress répartir la charge sur plusieurs exécutions successives, avec un traitement en arrière-plan qui ne bloque jamais une requête utilisateur.
function planifier_indexation_algolia( $offset = 0, $taille_lot = 500 ) {
as_schedule_single_action(
time() + 10,
'indexer_lot_algolia',
array( 'offset' => $offset, 'taille' => $taille_lot ),
'algolia-index'
);
}
add_action( 'indexer_lot_algolia', function( $offset, $taille ) {
$produits = wc_get_products( array( 'limit' => $taille, 'offset' => $offset, 'status' => 'publish' ) );
if ( empty( $produits ) ) {
return; // Fin de l'indexation complète.
}
algolia_indexer->index_batch( $produits );
planifier_indexation_algolia( $offset + $taille, $taille );
} );
Synchronisation incrémentale plutôt que complète

Une fois l’indexation initiale terminée, réindexer l’intégralité des 150 000 produits à chaque modification de catalogue aurait été absurde. La synchronisation courante repose sur un déclenchement ciblé, accroché à woocommerce_update_product et woocommerce_update_product_stock, qui met en file d’attente uniquement le produit modifié, avec un délai de regroupement de trente secondes pour absorber les mises à jour en rafale (import massif, changement de prix en lot) sans multiplier les appels API vers Algolia.
Ce regroupement s’appuie sur une meta transitoire, _algolia_sync_pending, posée à la première modification détectée et retirée une fois le lot traité, évitant qu’un même produit modifié dix fois en une minute ne déclenche dix appels API distincts.
Confirmer la fin de traitement avant d’enchaîner
Le point qui a le plus retardé la mise au point : sans confirmation de traitement effectif côté Algolia, la file d’attente locale pouvait considérer un lot comme traité alors que l’API Algolia l’avait mis en file d’attente de son côté sans encore l’avoir indexé, provoquant des incohérences temporaires entre l’affichage front (résultats de recherche) et l’état réel du catalogue.
La solution a consisté à s’appuyer sur l’identifiant de tâche (taskID) renvoyé par chaque appel d’indexation Algolia, puis à interroger l’endpoint de statut de tâche avant de considérer un lot comme définitivement traité et de déclencher le lot suivant :
- Envoi du lot de 500 produits à Algolia, récupération du
taskID. - Vérification du statut via l’endpoint de suivi de tâche, avec une tentative répétée espacée de quelques secondes.
- Passage au lot suivant seulement après confirmation du statut « publié » côté Algolia.
- Journalisation de chaque lot avec son
taskID, pour permettre un diagnostic a posteriori en cas d’écart constaté.
Conseil maison : sur un très gros catalogue, ne considérez jamais un envoi API réussi comme une indexation terminée. Un appel qui répond « accepté » n’est pas la même chose qu’un appel dont le résultat est effectivement disponible côté moteur de recherche.
En résumé
Indexer 150 000 produits WooCommerce dans Algolia sans timeout suppose d’abandonner l’indexation synchrone en bloc au profit d’un découpage en lots pilotés par Action Scheduler, complété par une synchronisation incrémentale ciblée sur les seuls produits modifiés. La configuration du widget de recherche front, avec ses filtres et son tri par pertinence, reste un chantier séparé de cette architecture d’indexation.