L’export CSV s’arrête systématiquement autour de la ligne 8 000, sans message d’erreur, sans page blanche, juste une réponse qui se coupe en plein milieu du fichier téléchargé. Le navigateur n’affiche aucune erreur particulière puisque, de son point de vue, la connexion a simplement été fermée par le serveur avant la fin de la réponse.
Sur ce site, l’export des commandes WooCommerce passait par une requête classique déclenchée depuis l’administration, avec génération du CSV directement dans le corps de la réponse HTTP. Le symptôme n’apparaissait qu’au-delà d’un certain volume de commandes, ce qui orientait naturellement vers une limite de temps ou de mémoire côté PHP.
Symptôme : une coupure nette, sans trace côté PHP
Premier réflexe : vérifier max_execution_time dans php.ini, réglé ici à 300 secondes, largement suffisant pour un export qui prenait moins de 90 secondes en conditions normales. Aucune ligne d’erreur dans le journal PHP, aucun message de type Fatal error: Maximum execution time exceeded, ce qui excluait cette piste évidente.
Diagnostic : le pool PHP-FPM avait son propre délai
La configuration du pool PHP-FPM contenait une directive request_terminate_timeout réglée à 60 secondes, héritée d’une configuration par défaut copiée d’un autre projet. Cette directive agit indépendamment de max_execution_time : elle force PHP-FPM à envoyer un signal d’arrêt au processus PHP dès que ce délai est dépassé, sans jamais lever d’exception PHP interceptable, et donc sans laisser de trace dans les journaux applicatifs habituels.
Le journal d’erreur de PHP-FPM lui-même, distinct du journal PHP classique, contenait bien la mention correspondante une fois qu’on est allé la chercher : un message indiquant que la requête avait dépassé le délai configuré et avait été terminée de force. C’est ce journal, souvent ignoré au profit du seul journal PHP, qui donnait la vraie explication.

Correctif : sortir l’export du cycle requête-réponse
Plutôt que d’augmenter request_terminate_timeout, ce qui aurait déplacé le problème vers un volume de commandes encore plus grand, la solution retenue déplace l’export vers un traitement en arrière-plan :
- La demande d’export déclenche une tâche planifiée via Action Scheduler plutôt qu’un traitement synchrone.
- Le fichier CSV est généré morceau par morceau dans le système de fichiers, avec un état d’avancement stocké dans une option dédiée.
- L’interface d’administration interroge périodiquement cet état par une requête légère, jusqu’à proposer le lien de téléchargement une fois le fichier complet.
Pourquoi ce découpage règle durablement le problème
Une tâche Action Scheduler s’exécute dans un contexte qui peut être relancé et repris, contrairement à une requête HTTP soumise à la fois au délai PHP et au délai du pool PHP-FPM. Le volume de commandes exportables devient alors limité uniquement par l’espace disque disponible, pas par une contrainte de temps de réponse.
Prévention pour éviter la prochaine surprise
La bonne pratique retenue depuis : documenter systématiquement, pour chaque environnement, les trois délais qui peuvent couper un traitement long — max_execution_time côté PHP, request_terminate_timeout côté pool PHP-FPM, et le délai du serveur web en amont. Les trois valeurs doivent être connues avant de concevoir un traitement long, plutôt que découvertes après coup à la lecture d’un journal qu’on ne consulte pas d’habitude.
Un piège annexe rencontré pendant la correction
En cherchant à contourner temporairement le problème avant la refonte complète, une première tentative a consisté à augmenter request_terminate_timeout à 300 secondes pour l’aligner sur max_execution_time. Cette rustine a fonctionné pour l’export testé, mais elle a aussi permis à d’autres requêtes défaillantes, notamment une boucle mal maîtrisée dans un widget tiers, de continuer à occuper un worker PHP-FPM bien plus longtemps qu’avant, réduisant le nombre de workers disponibles pour traiter les autres visiteurs pendant ce délai. Cet effet de bord a confirmé qu’augmenter uniformément un délai de sécurité déplace le risque plutôt que de le supprimer.
En résumé
Un export qui s’arrête sans erreur visible côté navigateur pointe presque toujours vers une limite côté serveur qui n’a pas d’équivalent côté PHP applicatif. Vérifier le journal propre à PHP-FPM, distinct du journal PHP standard, permet de gagner un temps de diagnostic précieux plutôt que de chercher une explication du côté du code applicatif seul.