# PHP-FPM statique contre FrankenPHP en mode worker avec Stripe et Algolia

> Deux modes d'exécution PHP, un site qui multiplie les appels sortants vers Stripe et Algolia à chaque commande. À partir de quel volume le mode worker de FrankenPHP devient-il vraiment rentable ?

- Auteur : Clément Hadrot
- Publié le : 2025-04-11
- Mis à jour le : 2025-04-11
- Catégorie : Performance
- URL : https://wpmoderne.dev.wordpress-developpement.fr/performance/php-fpm-statique-frankenphp-worker-stripe-algolia/

## L’essentiel

- PHP-FPM redémarre l'application à chaque requête, FrankenPHP worker la garde en mémoire
- Le gain se voit surtout sur les appels sortants répétés
- Le seuil de rentabilité se situe autour de 40 requêtes par seconde sur ce site

Combien d'appels sortants une simple page de commande déclenche-t-elle réellement ? Sur une boutique WooCommerce de taille moyenne, le compte donnait trois appels réseau bloquants à chaque validation de panier : une vérification de stock via Algolia pour la recherche de produits associés, un appel à l'API Stripe pour créer l'intention de paiement, et un second appel Stripe pour récupérer les moyens de paiement enregistrés du client. Trois allers-retours réseau, à chaque commande, sur un mode d'exécution PHP qui redémarre l'intégralité de l'application entre chaque requête.

C'est ce site qui a servi de terrain de comparaison entre PHP-FPM en configuration classique et FrankenPHP en mode worker, un mode d'exécution qui garde l'application PHP chargée en mémoire entre les requêtes au lieu de la réinitialiser à chaque fois. La promesse de FrankenPHP worker est connue : moins de coût de démarrage. La question qui nous intéressait était différente : est-ce que ce gain se voit vraiment quand la majorité du temps de réponse vient d'appels réseau externes, pas du code applicatif lui-même ?

## Deux modes d'exécution, deux philosophies

PHP-FPM classique traite chaque requête HTTP dans un processus qui recharge entièrement l'autoloader Composer, réinitialise les connexions et rejoue le bootstrap WordPress depuis zéro. C'est un modèle robuste et bien connu, mais chaque requête paie ce coût de démarrage, de l'ordre de quelques dizaines de millisecondes sur ce site avant même la première ligne de code métier.

FrankenPHP en mode worker charge l'application une seule fois, puis la garde active en mémoire pour traiter des milliers de requêtes successives, à la manière d'un serveur Node.js ou Go. Le bootstrap WordPress ne se rejoue qu'une fois par worker, et non par requête, ce qui élimine ce coût fixe sur chaque appel suivant.

> L'essentiel à retenir : PHP-FPM redémarre l'application à chaque requête, FrankenPHP worker la garde en mémoire ; Le gain se voit surtout sur les appels sortants répétés ; Le seuil de rentabilité se situe autour de 40 requêtes par seconde sur ce site

## Le protocole de test

Nous avons rejoué le même scénario de commande avec k6, en faisant varier le nombre d'utilisateurs simultanés de 5 à 80, sur deux environnements identiques en ressources CPU et RAM : l'un en PHP-FPM avec un pool statique de 20 processus, l'autre en FrankenPHP worker avec 8 workers configurés. Les appels vers Stripe et Algolia étaient réels, contre les environnements de test de ces deux services.

| Charge | Latence moyenne PHP-FPM | Latence moyenne FrankenPHP worker |
| --- | --- | --- |
| 5 req/s | 480 ms | 460 ms |
| 20 req/s | 590 ms | 510 ms |
| 40 req/s | 810 ms | 600 ms |
| 80 req/s | 1 340 ms | 720 ms |

## Pourquoi l'écart se creuse avec la charge

À faible charge, le coût de démarrage de PHP-FPM reste marginal comparé au temps passé à attendre les réponses de Stripe et Algolia : la différence entre les deux modes est presque anecdotique. Mais à mesure que la charge augmente, PHP-FPM doit faire tourner davantage de processus en parallèle, chacun rechargeant son propre autoloader et ses propres connexions, ce qui multiplie la pression mémoire et CPU du serveur en plus de la latence réseau déjà subie par les appels externes.

- FrankenPHP worker ne rejoue pas le bootstrap WordPress à chaque requête, ce qui libère du CPU pour gérer davantage d'appels concurrents.
- Les connexions HTTP persistantes vers Stripe et Algolia peuvent être réutilisées d'une requête à l'autre au sein d'un même worker, contrairement à PHP-FPM qui repart de zéro.
- Le mode worker impose en revanche une vigilance sur les variables globales et statiques, qui restent en mémoire d'une requête à l'autre si elles ne sont pas réinitialisées explicitement.

## Le point de bascule observé

Sur ce site précis, l'écart devient significatif à partir d'environ 40 requêtes par seconde sur la page de commande, avec 210 ms de latence en moins par requête en mode worker. En dessous de ce seuil, la complexité supplémentaire du mode worker — gestion explicite de la réinitialisation d'état entre requêtes, surveillance des fuites mémoire — n'était pas justifiée par le gain observé.

> Le mode worker de FrankenPHP n'est pas un accélérateur universel : c'est un choix qui se rentabilise à partir d'un certain volume de requêtes concurrentes, et qui exige une discipline de code plus stricte sur l'état partagé.

## Ce que le mode worker exige en contrepartie

Passer en mode worker a nécessité un audit du code pour repérer les variables statiques et les singletons qui supposaient, à tort, une réinitialisation à chaque requête. Un cache d'objets en mémoire locale utilisé par un plugin tiers a dû être adapté, car il accumulait des entrées d'une requête à l'autre sans jamais les purger, un comportement invisible en PHP-FPM classique où chaque requête repart d'une mémoire vierge.

## Notre verdict

Pour ce site, le passage en mode worker a été activé uniquement sur les heures de forte affluence, avec un mécanisme de bascule automatique en dessous du seuil de rentabilité. Un site à faible trafic n'a probablement rien à gagner à complexifier son exécution pour un gain marginal ; un site qui encaisse des pics avec de multiples appels sortants par requête a, lui, un intérêt réel à passer ce cap une fois le code audité pour l'état partagé.
