Débit et latence
Ă quelle vitesse va-t-il, sur quelle mesure, et face Ă qui ? Câest votre deuxiĂšme question, et câest celle oĂč la hype fait le plus de dĂ©gĂąts. Sur le plus grand benchmark public qui compare des frameworks web de tous langages, les entrĂ©es PHP sâĂ©talent sur deux ordres de grandeur selon le runtime qui les fait tourner, des quarante premiĂšres places au dernier dixiĂšme. Le langage seul ne prĂ©dit rien ; le dĂ©ploiement prĂ©dit presque tout. Un Ă©cart pareil ne vous sert que si chaque chiffre vient avec son round, son matĂ©riel et son test, et ceux de ce chapitre les ont tous les trois.
Lâhistoire du moteur
Sur du code qui occupe le processeur, lâinterprĂ©teur a fait un grand pas une fois, puis des petits pas depuis. Le grand pas, câest PHP 7.0, en dĂ©cembre 2015, qui a remplacĂ© les structures de donnĂ©es internes du moteur. Son Ă©diteur affirmait alors que le temps dâexĂ©cution Ă©tait « souvent divisĂ© par deux » par rapport Ă PHP 5.6, dans un livre blanc sans mĂ©thodologie publiĂ©e. Une mesure indĂ©pendante, faite sur une seule machine avec toutes les versions de lâinterprĂ©teur de 5.6 Ă une build de dĂ©veloppement de PHP 8.0, retrouve la mĂȘme forme. Le score PHPBench, une suite synthĂ©tique de micro-benchmarks de lâinterprĂ©teur, passe de 288âŻ000 sur PHP 5.6 Ă 620âŻ000 sur PHP 7.0, puis monte par petites marches, entre rien et treize pour cent par version, jusquâĂ 876âŻ000 sur la build 8.0.
Depuis PHP 8.0, la vitesse de lâinterprĂ©teur sur une application web ne bouge plus, et ceux qui la mesurent le disent eux-mĂȘmes. Un hĂ©bergeur qui publie des benchmarks chaque annĂ©e a mesurĂ© WordPress Ă 146 requĂȘtes par seconde sur PHP 8.2 et Ă 148 sur PHP 8.5, sur la mĂȘme machine, et il Ă©crit que « les versions incrĂ©mentales produisent rarement de grands sauts de vitesse Ă elles seules ». Câest sa propre mesure, lancĂ©e Ă quinze requĂȘtes simultanĂ©es sur une machine de trente cĆurs ; elle dit donc le temps de rĂ©ponse, pas la capacitĂ©. Retenez ceci : une version actuelle de PHP est Ă peu prĂšs deux fois plus rapide que PHP 5 sur le travail propre de lâinterprĂ©teur, et une montĂ©e de version mineure ne vous apportera rien dâautre que des corrections et des fonctionnalitĂ©s.
Le benchmark multi-langages
Le Framework Benchmarks de TechEmpower est une suite publique qui a fait passer des centaines de frameworks web, dans des dizaines de langages, par les six mĂȘmes tests sur le mĂȘme matĂ©riel, chaque implĂ©mentation Ă©tant contribuĂ©e et entretenue par des volontaires dans un dĂ©pĂŽt public. Son dernier round achevĂ© est le Round 23, datĂ© du 24 fĂ©vrier 2025, exĂ©cutĂ© sur un serveur Ă processeur Xeon Gold 6330, 28 cĆurs et 56 threads, avec un rĂ©seau Ă 40 gigabits. Le dĂ©pĂŽt du projet a Ă©tĂ© archivĂ© le 24 mars 2026 : le Round 23 est donc le dernier, et ses chiffres sont les derniers de leur espĂšce. Rien dâautre ne compare autant de frameworks sous un mĂȘme protocole, câest pourquoi je les garde. Et comme les tests ne mesurent pas la mĂȘme chose, chaque chiffre nomme le sien.
Le test Fortunes est celui qui ressemble le plus Ă une page web : une requĂȘte en base qui renvoie une douzaine de lignes, un gabarit HTML rendu avec Ă©chappement. Sur ce test, 510 entrĂ©es ont terminĂ© le Round 23. Le graphique en retient seize, les leaders toutes catĂ©gories, le framework grand public de chaque langage majeur et les entrĂ©es PHP de chaque type de runtime. Le tableau brut avec toutes les entrĂ©es est rangĂ© Ă cĂŽtĂ© des donnĂ©es de graphiques du livre, pour que vous puissiez faire votre propre sĂ©lection.
Lisez les barres PHP de haut en bas. Les entrĂ©es PHP les plus rapides, sur les runtimes workerman et Swoole, en SQL brut et sans framework, occupent les rangs 31 Ă 38 sur 510, au-dessus de 730âŻ000 requĂȘtes par seconde, devant lâentrĂ©e ASP.NET Core de base, les entrĂ©es Go et Spring. Un framework PHP complet avec un ORM complet sur un runtime worker, lâentrĂ©e Ubiquity, atteint 428âŻ000 au rang 92. PHP nu sous PHP-FPM et nginx, le dĂ©ploiement standard, atteint 146âŻ000 au rang 248, environ un tiers devant Gin et FastAPI. Les deux frameworks PHP les plus utilisĂ©s, sous PHP-FPM, sont prĂšs du bas : Symfony Ă 26âŻ000 et Laravel Ă 16âŻ000, derriĂšre Rails Ă 43âŻ000 et Django Ă 32âŻ000. Un mĂȘme benchmark soutient donc Ă la fois que PHP peut compter parmi les runtimes web les plus rapides et quâune application PHP typique compte parmi les plus lentes. Quand on ne vous dit que lâun des deux, on vous vend quelque chose.
Une partie de lâĂ©cart tient au runtime. Une entrĂ©e qui garde lâapplication chargĂ©e entre deux requĂȘtes supprime le coĂ»t de dĂ©marrage, et câest lui qui domine le temps de requĂȘte dâun framework.
Le mĂȘme code Symfony passe de 26âŻ000 requĂȘtes par seconde sous PHP-FPM Ă 74âŻ000 sous FrankenPHP et 111âŻ000 sous Swoole, et le mĂȘme code Laravel de 16âŻ000 Ă 50âŻ000 sous workerman. Le reste de lâĂ©cart tient Ă lâentrĂ©e elle-mĂȘme. Chez TechEmpower, une entrĂ©e est entretenue par qui veut bien sâen occuper, et une entrĂ©e lente peut reflĂ©ter une configuration datĂ©e autant que le framework. LâentrĂ©e Laravel sous RoadRunner, Ă 8âŻ000, est plus lente que sous PHP-FPM ; je nâai pas dâexplication et je la rapporte telle quâelle a Ă©tĂ© mesurĂ©e.
Les autres tests dĂ©placent les rangs, pas lâhistoire. Sur le test de sĂ©rialisation JSON, qui nâa pas de base de donnĂ©es, lâentrĂ©e Swoole atteint 2,5 millions de requĂȘtes par seconde au rang 73, PHP-FPM nu 428âŻ000 et Laravel sous PHP-FPM 27âŻ000, tandis quâASP.NET Core est Ă 1,4 million, Node.js Ă 1,1 million, Spring Ă 328âŻ000 et Django Ă 167âŻ000. Sur le test Ă vingt requĂȘtes SQL, que le pilote de base de donnĂ©es bride, les leaders de tous les langages se rejoignent sous 90âŻ000, et les entrĂ©es PHP les plus rapides sont Ă 56âŻ000, devant FastAPI Ă 37âŻ000 et Spring Ă 32âŻ000.
La latence
Le dĂ©bit dit combien de requĂȘtes une machine peut absorber. La latence dit combien de temps un utilisateur attend, et ce qui la domine, câest ce que la requĂȘte attend, pas lâinterprĂ©teur. Tideways, un Ă©diteur de profileur et membre fondateur de la PHP Foundation, a mesurĂ© un hello-world PHP-FPM derriĂšre nginx sur une machine virtuelle Ă huit cĆurs, et relevĂ© un 99e centile de 0,9 milliseconde Ă 18âŻ000 requĂȘtes par seconde. Câest le plancher : lâinterprĂ©teur et le gestionnaire de processus coĂ»tent ensemble moins dâune milliseconde quand il nây a rien dâautre Ă faire, et tout ce qui vient au-dessus, câest lâapplication et ses dĂ©pendances.
Les chiffres de latence publics les plus utiles viennent dâune organisation qui publie ses propres objectifs et ses propres tableaux de bord. Les rĂšgles dâingĂ©nierie de Wikimedia exigent quâune requĂȘte GET sâachĂšve en 50 millisecondes Ă la mĂ©diane et en 200 millisecondes au 99e centile du temps passĂ© dans PHP, et en 500 millisecondes au 99e centile pour un POST. Son instance Grafana est publique et montre la distribution mesurĂ©e pour les requĂȘtes qui atteignent les serveurs applicatifs, câest-Ă -dire les dĂ©fauts de cache et les utilisateurs connectĂ©s, autrement dit les requĂȘtes chĂšres. Le jour oĂč jâai vĂ©rifiĂ©, la mĂ©diane Ă©tait dâenviron 170 millisecondes et la queue de distribution bien au-dessus de lâobjectif, pour des pages qui incluent le rendu du wikitexte depuis un cache dâanalyse froid. Je vous donne le tableau de bord plutĂŽt que lâinstantanĂ©, parce quâune semaine vous en dira plus quâune heure.
LĂ oĂč PHP perd
Sur du calcul pur, sans entrĂ©es-sorties, PHP est un interprĂ©teur avec un JIT en option, et il est un ordre de grandeur plus lent quâun runtime compilĂ© Ă la volĂ©e comme V8. Le Computer Language Benchmarks Game, qui compare des programmes contribuĂ©s sur les mĂȘmes petites tĂąches, place le programme n-body mono-thread le plus rapide Ă 2,2 secondes en Rust, 3,1 en C#, 6,0 en Java, 6,4 en Go, 8,6 en Node.js, 167 en Ruby avec YJIT, 204 en PHP 8.4 et 360 en Python 3.13.
Le graphique a ses rĂ©serves. Les programmes PHP tournent avec un tampon JIT configurĂ© mais opcache.jit laissĂ© Ă sa valeur par dĂ©faut de PHP 8.4, câest-Ă -dire dĂ©sactivé : ils mesurent donc lâinterprĂ©teur seul. La RFC du JIT rapporte un gain de quatre fois sur Mandelbrot une fois le JIT activĂ©, ce qui resserrerait lâĂ©cart sans le combler. Les programmes sont aussi contribuĂ©s, donc ils mesurent le meilleur programme que quelquâun a pris la peine dâĂ©crire. Avec ces deux rĂ©serves, lâordre tient. Pour du calcul numĂ©rique, de la simulation, lâanalyse de gros fichiers en boucle ou tout ce qui occupe un cĆur, PHP est dans la classe de Python et de Ruby, pas dans celle de Node.js, et trente Ă cent fois derriĂšre Go, Java, C# et Rust sur ce programme. LĂ oĂč PHP est le mauvais choix en tire la consĂ©quence.
La limite : les bons chiffres de dĂ©bit de PHP viennent des runtimes worker et de lâaccĂšs brut Ă la base, ce quâune Ă©quipe ordinaire ne fait pas tourner dĂšs le premier jour. Ses chiffres typiques, un framework complet sous PHP-FPM, sont ceux de Rails et de Django, quelques dizaines de milliers de requĂȘtes par seconde sur une grosse machine, ce qui reste plus que ce que la plupart des applications recevront jamais. Et sur du calcul pur, lâinterprĂ©teur est un ordre de grandeur derriĂšre V8.
Ce que vous pouvez vĂ©rifier vous-mĂȘme
Lâoutillage TechEmpower tourne encore depuis son dĂ©pĂŽt archivĂ©, avec Docker, et les tableaux bruts du Round 23 pour six tests sont rangĂ©s en CSV dans le dossier charts/raw/ du livre : vous pouvez vĂ©rifier ma sĂ©lection et en faire une autre. Plus prĂšs de chez vous, prenez lâapplication que vous construiriez, ou un Ă©quivalent open source, faites-la tourner sous PHP-FPM puis sous un runtime worker sur la mĂȘme machine, et mesurez avec wrk Ă la concurrence que vous attendez en production. Le rapport que vous obtiendrez est le seul qui compte. Pour la latence, ouvrez le tableau de bord public « Backend Pageview Timing » de Wikimedia et lisez-en une semaine.
Le dĂ©bit suppose des requĂȘtes indĂ©pendantes. Que se passe-t-il quand elles ne le sont pas ? Câest la question suivante.