FrankenPHP est un serveur d'application PHP moderne, écrit en Go et basé sur Caddy, qui applique au PHP une idée longtemps réservée à d'autres plateformes : garder l'application en mémoire entre les requêtes. En septembre 2026, le projet est à sa version stable 1.12.7, publiée le 7 août 2026, et il n'est plus une curiosité de démonstration : c'est un outil documenté pour la production, avec un support natif du worker mode dans Symfony depuis la version 7.4.
Ce guide pose un cadre pragmatique : ce que le worker mode change réellement, comment l'intégrer à une application Symfony, où sont les gains mesurables et quelles sont les limites. Il complète notre panorama de l'écosystème PHP en 2026 en entrant dans le détail d'un outil précis, du choix architectural au déploiement.

Qu'est-ce que FrankenPHP et pourquoi ça change la donne
Le modèle historique de PHP, popularisé par mod_php puis PHP-FPM, reconstruit tout à chaque requête : le framework est booté, la configuration chargée, les services instanciés, les fichiers de traduction lus, le conteneur compilé. Pour une application Symfony complète, ce bootstrap représente une part sensible du temps de réponse, surtout sur des endpoints rapides comme une API ou une page en grande partie cachée.
FrankenPHP propose deux modes. Le mode classique reste proche du fonctionnement habituel : un bootstrap par requête, sans surprise. Le worker mode inverse la logique : le worker démarre l'application une fois, la garde en mémoire et lui transmet les requêtes successivement. C'est ce second mode qui justifie l'intérêt en 2026, car c'est lui qui attaque le coût du bootstrap.
Trois caractéristiques distinguent FrankenPHP des serveurs PHP traditionnels. D'abord, il embarque son propre serveur web : pas de Nginx devant, pas de PHP-FPM à administrer, un seul binaire à déployer. Ensuite, il parle les protocoles récents : HTTP/2, HTTP/3 et Early Hints, sans configuration supplémentaire. Enfin, il est distribué sous forme d'image Docker officielle, ce qui simplifie l'adoption sur les infrastructures conteneurisées standard.
Le worker mode, l'innovation centrale
Le principe du worker mode tient en une phrase : initialiser l'application une fois, servir des milliers de requêtes. Concrètement, le worker démarre, construit le conteneur de services, charge la configuration et les classes nécessaires, puis entre dans une boucle où chaque requête HTTP reçoit un contexte frais mais réutilise le socle déjà construit.
La configuration se fait par une variable d'environnement FRANKENPHP_CONFIG ou une option de ligne de commande qui désigne le script worker, typiquement un fichier qui appelle la boucle de traitement du serveur. Le nombre de workers règle la concurrence : chaque worker traite une requête à la fois, donc deux workers servent deux requêtes simultanément, comme deux processus PHP-FPM.
Ce modèle rapproche PHP des runtimes à longue durée de vie, avec un bénéfice immédiat pour tout ce qui était payé à chaque requête : construction du conteneur, chargement des fichiers de configuration, initialisation des connexions. La contrepartie est un changement de contrat mental. En mode worker, tout état qui survit d'une requête à l'autre peut fuiter : variable statique, propriété modifiée sur un service singleton, connexion dont l'état a changé. Les applications Symfony écrites selon les bonnes pratiques, avec des services sans état mutable, sont déjà compatibles dans leur grande majorité.
- Bootstrap unique : le conteneur, la configuration et les services chauds sont réutilisés d'une requête à l'autre.
- Concurrence par workers : chaque worker traite une requête à la fois, le parallélisme se règle en nombre de workers.
- Contrat de propreté : aucun état global persistant entre requêtes, sous peine de fuites difficiles à diagnostiquer.
FrankenPHP avec Symfony en 2026
L'intégration Symfony est officielle et s'est considérablement simplifiée. Depuis Symfony 7.4, le worker mode de FrankenPHP est supporté nativement : le framework gère la réinitialisation du contexte entre les requêtes et le cycle de vie du kernel. Pour les applications sur des branches plus anciennes, le runtime dédié runtime/frankenphp-symfony fournit la même intégration via le composant Runtime, qui découpe proprement le démarrage, le run et la terminaison.
Le choix de version compte donc doublement. D'un côté, Symfony 7.4 est la branche LTS : corrections de bugs jusqu'au 30 novembre 2028 et correctifs de sécurité jusqu'au 30 novembre 2029, ce qui en fait la cible rationnelle pour un socle qui dure. De l'autre, les branches 8.0 et 8.1 ont des cycles courts : la 8.0 est arrivée en fin de vie en juillet 2026 et la 8.1 est prévue jusqu'en janvier 2027 seulement. Un projet qui veut le worker mode natif sans dépendance supplémentaire a un argument de plus pour viser 7.4.
Côté PHP, la cohérence s'impose aussi : une application qui monte en version pour le worker mode devrait viser PHP 8.3 au minimum, car PHP 8.2 ne reçoit plus que des correctifs de sécurité jusqu'à la fin de l'année 2026. Notre guide de montée de version PHP en production détaille la méthode pour enchaîner ces migrations sans rupture.
Le parallèle avec le traitement asynchrone mérite d'être souligné : si vous utilisez déjà des consommateurs Messenger en processus longue durée, vous appliquez déjà la discipline que demande le worker mode. Les mêmes règles — services réentrants, pas d'état global, gestion propre de la mémoire — s'y appliquent, et l'expérience acquise sur les workers Messenger se transfère directement.

Performances : ce qu'on peut mesurer honnêtement
Soyons précis, car c'est ici que circulent les chiffres les moins solides du sujet. Le gain théorique du worker mode est le coût du bootstrap économisé : conteneur, configuration, initialisation des services. Sur une application Symfony réelle, ce coût se compte en millisecondes, parfois davantage si le projet charge beaucoup de bundles ou de traductions. Le gain perçu dépend donc du profil des endpoints : un endpoint qui consomme 250 millisecondes de métier ne verra pas sa latence divisée par deux parce que 15 millisecondes de bootstrap disparaissent.
Il n'existe pas, à ce jour, de benchmark public unique, standardisé et récent qui comparerait de façon fiable FrankenPHP en worker mode à PHP-FPM sur une charge représentative : les résultats publiés dépendent de l'application, du jeu de données, du réseau et de la méthode. Toute affirmation chiffrée universelle doit donc être traitée avec méfiance. Ce qui est mesurable, en revanche, c'est votre application : un outil de profilage ou un simple temps de réponse en percentile sur vos endpoints réels, avant et après, donne un chiffre qui vous appartient.
La méthode que nous recommandons tient en quatre étapes. Mesurez d'abord le bootstrap : le temps de réponse d'un endpoint minimal qui ne fait qu'instancier le kernel. Profiliez ensuite vos endpoints les plus fréquents pour connaître la part du bootstrap dans le total. Activez le worker mode en recette et comparez les percentiles sur un trafic similaire. Ne décidez que sur ces chiffres, et conservez le mode classique comme plan B documenté.
Early Hints et HTTP/3, les atouts protocolaires
Au-delà du worker mode, FrankenPHP apporte des capacités protocolaires que la pile LAMP traditionnelle peine à offrir sans assemblage. Le support d'HTTP/3 (QUIC) est intégré, ainsi que celui des Early Hints, le statut 103 qui permet au serveur d'envoyer des indications de préchargement avant la réponse complète : précharger la feuille de style, la police ou les sous-ressources critiques pendant que le backend construit la page.
FrankenPHP se présente comme le seul SAPI PHP avec support des Early Hints, et l'intérêt est concret pour le rendu côté serveur : un document HTML généré en 300 millisecondes peut commencer à indiquer ses ressources critiques dès les premières millisecondes, améliorant le Largest Contentful Paint sur les connexions lentes. Le TLS est automatisé via Let's Encrypt, ce qui supprime une classe entière de tâches d'exploitation.
Ces atouts ne dépendent pas du worker mode : on peut servir en mode classique et bénéficier d'HTTP/3, des Early Hints et du TLS automatique. C'est d'ailleurs la voie la plus prudente pour un premier déploiement, le worker mode venant en seconde étape une fois la supervision en place.
FrankenPHP face à PHP-FPM et RoadRunner
Le choix se joue sur trois acteurs principaux. PHP-FPM reste la valeur par défaut du marché : éprouvé, omniprésent, parfaitement intégré aux panels d'hébergement. RoadRunner, serveur Go de Spiral, propose lui aussi des workers persistants et une intégration Symfony via le runtime dédié. FrankenPHP se distingue par son serveur web intégré, ses protocoles récents et son approche Docker-first.
| Critère | FrankenPHP | PHP-FPM | RoadRunner |
|---|---|---|---|
| Modèle d'exécution | Classique ou worker mode | Bootstrap à chaque requête | Workers persistants |
| Serveur web intégré | Oui, basé sur Caddy | Non (Nginx/Apache requis) | Oui |
| HTTP/3 et Early Hints | Oui, natif | Via Nginx, config manuelle | HTTP/3 selon version |
| Intégration Symfony | Native depuis 7.4, sinon runtime dédié | Universelle | Runtime dédié |
| Courbe d'adoption | Image Docker, un binaire | Maximale, partout documentée | Simple côté Go, runtime PHP à ajouter |
| Position en 2026 | Mature, documentation production | Référence historique | Mature, écosystème Spiral |
La colonne décisive n'est pas technique mais organisationnelle : qui exploitera le serveur au quotidien ? Une équipe qui maîtrise déjà Nginx et PHP-FPM, avec des runbooks établis, peut légitimement garder cette stack et traiter FrankenPHP comme une option sur les nouveaux projets. Une équipe qui démarre un projet neuf sur conteneurs bénéficie d'une stack à un seul composant, du TLS automatique et d'un chemin clair vers le worker mode.

Mise en production et points de vigilance
Le déploiement suit les standards du conteneur : image officielle, variable FRANKENPHP_CONFIG pour activer le worker, healthcheck HTTP, logs structurés. Notre guide d'hébergement et de déploiement Symfony détaille l'articulation avec les environnements, et les mêmes principes s'appliquent : recette identique à la production, migrations découplées du démarrage, secrets hors des images.
- Supervision : métriques de latence par percentile, nombre de workers actifs, consommation mémoire des workers, taux de redémarrage.
- Recyclage : prévoir un redémarrage périodique des workers pour garder la mémoire sous contrôle, comme on le fait déjà pour les consommateurs de files.
- Montées de version : le serveur et le SAPI PHP sont couplés dans l'image, donc tester l'upgrade complet en recette, pas seulement l'application.
- Mode classique d'abord : servir en mode classique au premier déploiement, activer le worker ensuite, en gardant le retour arrière documenté.
La vigilance spécifique porte sur la mémoire. Un worker qui traite des milliers de requêtes sans redémarrage accumule les allocations si le code laisse fuiter des références — phénomène invisible en PHP-FPM où chaque requête démarre un processus neuf. Les outils de profilage mémoire de PHP restent utilisables, mais la métrique d'exploitation à regarder en priorité est l'empreinte mémoire du worker au fil des heures.
Quand adopter FrankenPHP, et quand s'en passer
Adoptez-le si le scénario vous ressemble : nouveau projet Symfony sur conteneurs, équipe à l'aise avec Docker, endpoints sensibles au temps de réponse, ou volonté de simplifier la chaîne Nginx plus PHP-FPM plus certificats en un seul composant. Le worker mode est un plus, pas une obligation : le mode classique avec HTTP/3 et TLS automatique apporte déjà de la valeur.
Passez votre chemin pour l'instant si votre application accumule l'état global et que personne n'a le budget de vérifier la réentrancité, si votre hébergeeur mutualisé impose PHP-FPM, ou si votre équipe d'exploitation n'a ni le temps ni l'envie d'apprendre un nouveau serveur. Dans ces cas, la bonne décision est de consolider l'existant : PHP 8.3 ou 8.4, OPcache configuré, Symfony 7.4 LTS, et un projet de test de FrankenPHP cadré pour plus tard.
La question finale n'est pas « FrankenPHP est-il meilleur ? » mais « quel est le coût complet du changement pour mon contexte ? ». Mesurez le bootstrap de votre application, estimez la part qu'il représente, chiffrez la dette de réentrancité, puis décidez. Les outils modernes récompensent les équipes qui savent mesurer avant de migrer ; c'est exactement la discipline développée dans nos guides d'audit et de montée de version, appliquée cette fois au serveur lui-même.