InvestigaciónEstadísticas de concurrencia

Datos estadísticos para el cálculo de concurrencia ​

Las fórmulas de la sección Eficiencia de tareas limitadas por E/S operan con varias magnitudes clave. A continuación se presenta una colección de mediciones reales que permiten insertar números concretos en las fórmulas.


Elementos de las fórmulas ​

Ley de Little:

$$ L = \lambda \cdot W $$

  • L — el nivel de concurrencia requerido (cuántas tareas simultáneamente)
  • λ — rendimiento (solicitudes por segundo)
  • W — tiempo promedio de procesamiento de una solicitud

Fórmula de Goetz:

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

  • T_io — tiempo de espera de E/S por solicitud
  • T_cpu — tiempo de cómputo de CPU por solicitud

Para el cálculo práctico, necesitas conocer:

  1. Cuántas consultas SQL se ejecutan por solicitud HTTP
  2. Cuánto tarda una consulta SQL (E/S)
  3. Cuánto tarda el procesamiento de CPU
  4. Cuál es el rendimiento del servidor
  5. Cuál es el tiempo total de respuesta

1. Consultas SQL por solicitud HTTP ​

El número de llamadas a la base de datos depende del framework, el ORM y la complejidad de la página.

Aplicación / FrameworkConsultas por páginaFuente
WordPress (sin plugins)~17Drupal Groups: How many queries per page
Symfony (Doctrine, página promedio)<30 (umbral del profiler)Symfony Docs: Profiler testing
Laravel (CRUD simple)5–15Valores típicos de Laravel Debugbar
Laravel (con problema N+1)20–50+Laravel Daily: Debug Slow Queries
Drupal (sin caché)80–100Drupal Groups
Magento (catálogo)50–200+Típico para e-commerce complejo

Mediana para una aplicación ORM típica: 15–30 consultas por solicitud HTTP.

Symfony utiliza un umbral de 30 consultas como límite "normal" — al superarlo, el icono del profiler cambia a amarillo.

2. Tiempo por consulta SQL (T_io por consulta) ​

Tiempo de ejecución de la consulta en el servidor de BD ​

Datos de los benchmarks OLTP de sysbench de Percona (MySQL):

ConcurrenciaPorcentaje de consultas <0,1 ms0,1–1 ms1–10 ms>10 ms
1 hilo86%10%3%1%
32 hilos68%30%2%<1%
128 hilos52%35%12%1%

LinkBench (Percona, aproximando la carga de trabajo real de Facebook):

Operaciónp50p95p99
GET_NODE0,4 ms39 ms77 ms
UPDATE_NODE0,7 ms47 ms100 ms

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

Latencia de red (ida y vuelta) ​

EscenarioIda y vueltaFuente
Unix-socket / localhost<0,1 msCYBERTEC PostgreSQL
LAN, mismo centro de datos~0,5 msCYBERTEC PostgreSQL
Nube, entre zonas (AZ)1–5 msCYBERTEC PostgreSQL
Entre regiones10–50 msValores típicos

Total: Tiempo completo por consulta SQL ​

Tiempo completo = tiempo de ejecución en el servidor + ida y vuelta de red.

EntornoSELECT simple (p50)Consulta promedio (p50)
Localhost0,1–0,5 ms0,5–2 ms
LAN (mismo DC)0,5–1,5 ms1–4 ms
Nube (entre AZ)2–6 ms3–10 ms

Para un entorno en la nube, 4 ms por consulta promedio es una estimación bien fundamentada.

3. Tiempo de CPU por consulta SQL (T_cpu por consulta) ​

El tiempo de CPU cubre: análisis del resultado, hidratación de entidades del ORM, mapeo de objetos, serialización.

Los benchmarks directos de este valor específico son escasos en fuentes públicas, pero pueden estimarse a partir de datos del profiler:

  • Blackfire.io separa el wall time en tiempo de E/S y tiempo de CPU (Blackfire: Time)
  • En aplicaciones PHP típicas, la base de datos es el cuello de botella principal, y el tiempo de CPU constituye una fracción pequeña del wall time (Datadog: Monitor PHP Performance)

Estimación indirecta mediante rendimiento:

Symfony con Doctrine (BD + renderizado Twig) procesa ~1000 req/s (Kinsta PHP Benchmarks). Esto significa que el tiempo de CPU por solicitud ≈ 1 ms. Con ~20 consultas SQL por página → ~0,05 ms de CPU por consulta SQL.

Laravel API endpoint (Sanctum + Eloquent + JSON) → ~440 req/s (Sevalla: Laravel Benchmarks). Tiempo de CPU por solicitud ≈ 2,3 ms. Con ~15 consultas → ~0,15 ms de CPU por consulta SQL.

4. Rendimiento (λ) de aplicaciones PHP ​

Benchmarks ejecutados en 30 vCPU / 120 GB RAM, nginx + PHP-FPM, 15 conexiones concurrentes (Kinsta, Sevalla):

AplicaciónTipo de páginareq/s (PHP 8.4)
LaravelWelcome (sin BD)~700
LaravelAPI + Eloquent + Auth~440
SymfonyDoctrine + Twig~1.000
WordPressPágina principal (sin plugins)~148
Drupal 10—~1.400

Nótese que WordPress es significativamente más lento porque cada solicitud es más pesada (más consultas SQL, renderizado más complejo).


5. Tiempo total de respuesta (W) en producción ​

Datos de LittleData (2023, 2.800 sitios de e-commerce):

PlataformaTiempo promedio de respuesta del servidor
Shopify380 ms
Promedio de e-commerce450 ms
WooCommerce (WordPress)780 ms
Magento820 ms

Fuente: LittleData: Average Server Response Time

Benchmarks de la industria:

CategoríaTiempo de respuesta API
Excelente100–300 ms
Aceptable300–600 ms
Necesita optimización>600 ms

Cálculo práctico usando la Ley de Little ​

Escenario 1: Laravel API en la nube ​

Datos de entrada:

  • λ = 440 req/s (rendimiento objetivo)
  • W = 80 ms (calculado: 20 SQL × 4 ms E/S + 1 ms CPU)
  • Núcleos: 8

Cálculo:

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

En 8 núcleos, eso es ~4,4 tareas por núcleo. Esto coincide con el hecho de que Laravel con 15 workers PHP-FPM concurrentes ya alcanza 440 req/s. Hay margen de mejora.

Escenario 2: Laravel API en la nube, 2000 req/s (objetivo) ​

Datos de entrada:

  • λ = 2000 req/s (rendimiento objetivo)
  • W = 80 ms
  • Núcleos: 8

Cálculo:

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

PHP-FPM no puede manejar 160 workers en 8 núcleos — cada worker es un proceso separado con ~30–50 MB de memoria. Total: ~6–8 GB solo para workers.

Con corrutinas: 160 tareas × ~4 KiB ≈ 640 KiB. Una diferencia de cuatro órdenes de magnitud.

Escenario 3: Usando la fórmula de Goetz ​

Datos de entrada:

  • T_io = 80 ms (20 consultas × 4 ms)
  • T_cpu = 1 ms
  • Núcleos: 8

Cálculo:

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

Rendimiento (mediante la Ley de Little):

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

Este es el techo teórico con utilización completa de 8 núcleos. En la práctica, será menor debido a la sobrecarga del planificador, GC, límites del pool de conexiones. Pero incluso el 50% de este valor (4.000 req/s) es un orden de magnitud mayor que 440 req/s de PHP-FPM en los mismos 8 núcleos.

Resumen: De dónde vienen los números ​

MagnitudValorFuente
Consultas SQL por solicitud HTTP15–30WordPress ~17, umbral de Symfony <30
Tiempo por consulta SQL (nube)3–6 msPercona p50 + CYBERTEC ida y vuelta
CPU por consulta SQL0,05–0,15 msCálculo inverso desde benchmarks de rendimiento
Rendimiento de Laravel~440 req/s (API)Benchmarks de Sevalla/Kinsta, PHP 8.4
Tiempo de respuesta e-commerce (promedio)450 msLittleData, 2.800 sitios
Tiempo de respuesta API (norma)100–300 msBenchmark de la industria

Referencias ​

Benchmarks de frameworks PHP ​

Benchmarks de bases de datos ​

Tiempos de respuesta de sistemas en producción ​

Perfilado de PHP ​