Donnees statistiques pour le calcul de la concurrence

Les formules de la section Efficacite des taches IO-bound utilisent plusieurs grandeurs cles. Voici une collection de mesures reelles qui permettent d'injecter des chiffres concrets dans les formules.


Elements des formules

Loi de Little :

$$ L = \lambda \cdot W $$

  • L -- le niveau de concurrence requis (combien de taches simultanement)
  • λ -- le debit (requetes par seconde)
  • W -- le temps moyen de traitement d'une requete

Formule de Goetz :

$$ N = N_{cores} \times \left(1 + \frac{T_{io}}{T_{cpu}}\right) $$

  • T_io -- temps d'attente E/S par requete
  • T_cpu -- temps de calcul CPU par requete

Pour un calcul pratique, il faut connaitre :

  1. Combien de requetes SQL sont executees par requete HTTP
  2. Combien de temps prend une requete SQL (E/S)
  3. Combien de temps prend le traitement CPU
  4. Quel est le debit du serveur
  5. Quel est le temps de reponse global

1. Requetes SQL par requete HTTP

Le nombre d'appels a la base de donnees depend du framework, de l'ORM et de la complexite de la page.

Application / FrameworkRequetes par pageSource
WordPress (sans plugins)~17Drupal Groups: How many queries per page
Symfony (Doctrine, page moyenne)<30 (seuil du profiler)Symfony Docs: Profiler testing
Laravel (CRUD simple)5-15Valeurs typiques de Laravel Debugbar
Laravel (avec probleme N+1)20-50+Laravel Daily: Debug Slow Queries
Drupal (sans cache)80-100Drupal Groups
Magento (catalogue)50-200+Typique pour le e-commerce complexe

Mediane pour une application ORM typique : 15-30 requetes par requete HTTP.

Symfony utilise un seuil de 30 requetes comme limite du "normal" -- au-dela, l'icone du profiler passe au jaune.

2. Temps par requete SQL (T_io par requete)

Temps d'execution de la requete sur le serveur BDD

Donnees des benchmarks sysbench OLTP de Percona (MySQL) :

ConcurrencePart des requetes <0,1 ms0,1-1 ms1-10 ms>10 ms
1 thread86%10%3%1%
32 threads68%30%2%<1%
128 threads52%35%12%1%

LinkBench (Percona, approximation d'une charge de travail reelle Facebook) :

Operationp50p95p99
GET_NODE0,4 ms39 ms77 ms
UPDATE_NODE0,7 ms47 ms100 ms

Source : Percona: MySQL and Percona Server in LinkBench, Percona: Query Response Time Histogram

Latence reseau (aller-retour)

ScenarioAller-retourSource
Unix-socket / localhost<0,1 msCYBERTEC PostgreSQL
LAN, centre de donnees unique~0,5 msCYBERTEC PostgreSQL
Cloud, cross-AZ1-5 msCYBERTEC PostgreSQL
Cross-region10-50 msValeurs typiques

Total : temps complet par requete SQL

Temps complet = temps d'execution cote serveur + aller-retour reseau.

EnvironnementSELECT simple (p50)Requete moyenne (p50)
Localhost0,1-0,5 ms0,5-2 ms
LAN (DC unique)0,5-1,5 ms1-4 ms
Cloud (cross-AZ)2-6 ms3-10 ms

Pour un environnement cloud, 4 ms par requete moyenne est une estimation bien fondee.

3. Temps CPU par requete SQL (T_cpu par requete)

Le temps CPU couvre : l'analyse des resultats, l'hydratation des entites ORM, le mapping d'objets, la serialisation.

Les benchmarks directs de cette valeur specifique sont rares dans les sources publiques, mais peuvent etre estimes a partir des donnees de profilage :

  • Blackfire.io separe le wall time en temps d'E/S et temps CPU (Blackfire: Time)
  • Dans les applications PHP typiques, la base de donnees est le principal goulot d'etranglement, et le temps CPU constitue une faible fraction du wall time (Datadog: Monitor PHP Performance)

Estimation indirecte via le debit :

Symfony avec Doctrine (BDD + rendu Twig) traite ~1000 req/s (Kinsta PHP Benchmarks). Cela signifie que le temps CPU par requete ≈ 1 ms. Avec ~20 requetes SQL par page → ~0,05 ms CPU par requete SQL.

Endpoint API Laravel (Sanctum + Eloquent + JSON) → ~440 req/s (Sevalla: Laravel Benchmarks). Temps CPU par requete ≈ 2,3 ms. Avec ~15 requetes → ~0,15 ms CPU par requete SQL.

4. Debit (λ) des applications PHP

Benchmarks executes sur 30 vCPU / 120 Go RAM, nginx + PHP-FPM, 15 connexions concurrentes (Kinsta, Sevalla) :

ApplicationType de pagereq/s (PHP 8.4)
LaravelWelcome (sans BDD)~700
LaravelAPI + Eloquent + Auth~440
SymfonyDoctrine + Twig~1 000
WordPressPage d'accueil (sans plugins)~148
Drupal 10--~1 400

A noter que WordPress est significativement plus lent car chaque requete est plus lourde (plus de requetes SQL, rendu plus complexe).


5. Temps de reponse global (W) en production

Donnees de LittleData (2023, 2 800 sites e-commerce) :

PlateformeTemps de reponse serveur moyen
Shopify380 ms
Moyenne e-commerce450 ms
WooCommerce (WordPress)780 ms
Magento820 ms

Source : LittleData: Average Server Response Time

Benchmarks industriels :

CategorieTemps de reponse API
Excellent100-300 ms
Acceptable300-600 ms
Necessite optimisation>600 ms

Calcul pratique avec la loi de Little

Scenario 1 : API Laravel dans le cloud

Donnees d'entree :

  • λ = 440 req/s (debit cible)
  • W = 80 ms (calcule : 20 SQL × 4 ms E/S + 1 ms CPU)
  • Coeurs : 8

Calcul :

$$ L = \lambda \cdot W = 440 \times 0.080 = 35 \text{ taches concurrentes} $$

Sur 8 coeurs, cela fait ~4,4 taches par coeur. Ceci correspond au fait que Laravel avec 15 workers PHP-FPM concurrents atteint deja 440 req/s. Il reste de la marge.

Scenario 2 : API Laravel dans le cloud, 2000 req/s (cible)

Donnees d'entree :

  • λ = 2000 req/s (debit cible)
  • W = 80 ms
  • Coeurs : 8

Calcul :

$$ L = 2000 \times 0.080 = 160 \text{ taches concurrentes} $$

PHP-FPM ne peut pas gerer 160 workers sur 8 coeurs -- chaque worker est un processus separe avec ~30-50 Mo de memoire. Total : ~6-8 Go pour les workers seuls.

Avec des coroutines : 160 taches × ~4 Kio ≈ 640 Kio. Une difference de quatre ordres de grandeur.

Scenario 3 : avec la formule de Goetz

Donnees d'entree :

  • T_io = 80 ms (20 requetes × 4 ms)
  • T_cpu = 1 ms
  • Coeurs : 8

Calcul :

$$ N = 8 \times \left(1 + \frac{80}{1}\right) = 8 \times 81 = 648 \text{ coroutines} $$

Debit (via la loi de Little) :

$$ \lambda = \frac{L}{W} = \frac{648}{0.081} \approx 8,000 \text{ req/s} $$

C'est le plafond theorique avec utilisation complete des 8 coeurs. En pratique, il sera plus bas en raison de la surcharge de l'ordonnanceur, du GC, des limites du pool de connexions. Mais meme 50% de cette valeur (4 000 req/s) est un ordre de grandeur superieur aux 440 req/s de PHP-FPM sur les memes 8 coeurs.

Resume : d'ou viennent les chiffres

GrandeurValeurSource
Requetes SQL par requete HTTP15-30WordPress ~17, seuil Symfony <30
Temps par requete SQL (cloud)3-6 msPercona p50 + CYBERTEC aller-retour
CPU par requete SQL0,05-0,15 msCalcul inverse a partir des benchmarks de debit
Debit Laravel~440 req/s (API)Benchmarks Sevalla/Kinsta, PHP 8.4
Temps de reponse e-commerce (moy.)450 msLittleData, 2 800 sites
Temps de reponse API (norme)100-300 msBenchmark industriel

References

Benchmarks de frameworks PHP

Benchmarks de bases de donnees

Temps de reponse des systemes de production

Profilage PHP