Guide

FrankenPHP en 2026 : worker mode, Symfony et mise en production

FrankenPHP est devenu en 2026 un serveur d'application PHP utilisable en production : version stable 1.12.x, worker mode qui garde le kernel en mémoire, support natif du worker mode depuis Symfony 7.4, Early Hints et HTTP/3 intégrés. Ce guide explique ce qui change vraiment par rapport à PHP-FPM, comment l'adopter avec Symfony et où sont les limites.

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.

Ingénieure DevOps configurant un serveur d'application PHP moderne avec métriques de latence à l'écran
Le passage à un serveur d'application moderne se pilote comme tout changement d'infrastructure : en mesurant.

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.

Deux développeuses comparant le déploiement d'une application Symfony sur serveur d'application moderne et serveur traditionnel
L'intégration Symfony est officielle : depuis la 7.4, le worker mode est supporté nativement.

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èreFrankenPHPPHP-FPMRoadRunner
Modèle d'exécutionClassique ou worker modeBootstrap à chaque requêteWorkers persistants
Serveur web intégréOui, basé sur CaddyNon (Nginx/Apache requis)Oui
HTTP/3 et Early HintsOui, natifVia Nginx, config manuelleHTTP/3 selon version
Intégration SymfonyNative depuis 7.4, sinon runtime dédiéUniverselleRuntime dédié
Courbe d'adoptionImage Docker, un binaireMaximale, partout documentéeSimple côté Go, runtime PHP à ajouter
Position en 2026Mature, documentation productionRéférence historiqueMature, é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.

Équipe de développement supervisant un déploiement conteneurisé avec tableaux de bord de monitoring en salle serveur moderne
Le choix du serveur se justifie autant par l'exploitation que par les performances brutes.

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.

Questions fréquentes

FrankenPHP remplace-t-il Nginx ou Apache ?
Oui pour le trafic HTTP : FrankenPHP embarque son propre serveur web, basé sur Caddy, avec TLS automatique, HTTP/2 et HTTP/3. Il n'a pas besoin d'un reverse proxy pour servir une application PHP, même si garder un équilibreur de charge ou un CDN en amont reste une pratique courante. Il ne remplace pas les autres rôles que pouvaient jouer Nginx, comme la distribution de fichiers statiques d'un autre domaine ou la terminaison spécifique d'un certificat.
Le worker mode est-il compatible avec toutes les applications Symfony ?
Non. Le worker mode garde le kernel en mémoire entre les requêtes, donc tout état conservé dans des variables statiques, des services singleton modifiés ou des connexions ouvertes se propage d'une requête à l'autre. Une application écrite selon les conventions Symfony, avec des services stateless et une réinitialisation propre, fonctionne bien. Une application legacy qui accumule de l'état global nécessite une passe de vérification, voire reste en mode classique.
FrankenPHP est-il prêt pour la production en 2026 ?
Oui. Le projet publie des versions stables régulières, la version 1.12.7 datant du 7 août 2026, et une documentation dédiée au déploiement en production existe depuis plusieurs versions. Des équipes l'utilisent en production sur des API et des applications web. Comme pour tout serveur d'application, la précaution porte moins sur l'outil que sur la supervision, la gestion des montées de version et les tests de reprise après incident.
Quelle version de PHP choisir avec FrankenPHP ?
Une version encore sous support de sécurité, en visant le futur proche. Fin 2026, PHP 8.2 ne reçoit plus que des correctifs de sécurité jusqu'au 31 décembre 2026, PHP 8.3 jusqu'au 31 décembre 2027 et PHP 8.4 jusqu'au 31 décembre 2028. Ciblez PHP 8.3 au minimum et prévoyez la montée vers 8.4, ce qui colle aux prérequis des frameworks récents.
Comment revenir en arrière si le worker mode pose problème ?
Le retour est simple car FrankenPHP sert aussi en mode classique, proche de PHP-FPM, avec un bootstrap à chaque requête. Il suffit de retirer la configuration worker et de redémarrer le conteneur ou le service. La bonne pratique consiste à déployer d'abord en mode classique, d'activer le worker par environnement, puis de le valider en recette avec vos parcours critiques avant la production.