En el mundo del rendimiento, pocas cifras suenan tan rotundas como 1.000.000 de peticiones por segundo (RPS). Se repite en charlas, titulares y debates de arquitectura, pero casi siempre con un matiz que cambia toda la historia: ese millón rara vez llega ?de golpe? a los servidores de aplicación. Lo que permite alcanzar volúmenes de ese calibre no es un framework milagroso ni un ajuste oscuro del kernel, sino una combinación de caché en el edge (CDN), diseño de endpoints cacheables, colas para desacoplar escrituras, motores de búsqueda especializados como Elasticsearch y runtimes PHP de proceso persistente.
La foto completa se parece más a una autopista con peajes inteligentes que a un único motor empujando más fuerte. Y en esa autopista, PHP 8+ puede jugar un papel relevante si se coloca donde mejor rinde: sirviendo lógica de negocio rápida, validación, autenticación y orquestación, mientras el sistema reparte el trabajo pesado en capas.
RPS no es rendimiento ?de la app?: es rendimiento del sistema
El dato de RPS, por sà solo, engaña. Dos sistemas pueden presumir del mismo número y ser radicalmente distintos:
La lección que aplican los equipos que realmente operan a escala es sencilla: primero se reduce el número de peticiones que llegan a origen. Solo después se optimiza la aplicación.
La arquitectura que hace posible el salto: de fuera hacia dentro
1) CDN/Edge caching: el ?acelerador? que convierte un API normal en uno masivo
Para aspirar a 1.000.000 RPS, la primera pregunta no es ?¿qué runtime uso??, sino ?¿qué porcentaje de tráfico puedo convertir en cache hit??. En un escenario realista, el 90?99% de muchas rutas de lectura (GET) deberÃa resolverse sin tocar PHP.
Claves prácticas que suelen marcar la diferencia:
En medios de programación se habla mucho de ?optimizar PHP?, pero en producción el gran salto suele venir de aquÃ: convertir el API en algo cacheable por diseño, no por casualidad.
Diseño de endpoints para que el CDN trabaje a favor
En una pila clásica Nginx + PHP-FPM, cada request repite costes: bootstrap del framework, carga de contenedor, autoload, configuración? Para un API pequeño puede bastar, pero cuando se busca exprimir latencia y throughput, la tendencia es clara: procesos persistentes que ?arrancan una vez? y procesan muchas peticiones.
En 2025, tres opciones se citan una y otra vez en proyectos serios:
RoadRunner: workers PHP gestionados por un servidor en Go
RoadRunner actúa como servidor de aplicaciones y gestor de procesos: mantiene workers PHP vivos y les entrega peticiones HTTP/HTTPS, incluso con soporte moderno (HTTP/2 h2c y HTTP/3). Este enfoque reduce el coste por request y permite escalar con una estrategia más propia de ?application servers? que de CGI tradicional.
Ejemplo conceptual de configuración de pool en .rr.yaml:
Â
http:
address: 0.0.0.0:8080
pool:
num_workers: 64
max_jobs: 5000
supervisor:
max_worker_memory: 256
La idea no es ?poner 64 y listo?, sino ajustar workers a núcleos, latencias de I/O y patrón de carga.
Swoole / OpenSwoole: modelo event-driven con corutinas
Swoole y OpenSwoole llevan años empujando una propuesta clara: I/O asÃncrona, corutinas y servidores embebidos para reducir latencia bajo concurrencia alta. Es potente, pero obliga a disciplina: un proceso largo en PHP no se comporta como el PHP ?clásico?, y el control del estado en memoria se convierte en tema central.
FrankenPHP: servidor moderno sobre Caddy con ?worker mode?
FrankenPHP ha ganado presencia por combinar una experiencia moderna de servidor (HTTP/2, HTTP/3, configuración estilo Caddy) con un modo worker que mantiene la aplicación cargada en memoria. Además, se integra con ecosistemas como Symfony Runtime y con Laravel Octane.
3) Laravel Octane y Symfony Runtime: el puente ?práctico? hacia procesos largos
No todo el mundo quiere reescribir su aplicación para un runtime nuevo. Aquà aparecen dos piezas que en medios de programación se han convertido en ?puentes? hacia alto rendimiento:
El mensaje técnico que se repite es el mismo: más rendimiento, sÃ, pero a cambio de asumir que hay memoria viva entre peticiones. Y eso exige higiene.
El gran enemigo: fugas de memoria y estado compartido
En runtimes persistentes, los bugs cambian de forma:
Por eso se imponen polÃticas como:
Redis y microcaché: la capa que salva al origen incluso cuando el CDN no ayuda
Cuando el CDN no puede cachear (personalización, auth, variación por usuario), el siguiente escalón suele ser:
Patrones que suelen funcionar a gran escala:
Elasticsearch: búsqueda y agregaciones, con indexación desacoplada
Elasticsearch brilla cuando se usa como lo que es: motor de búsqueda. En un API de alto tráfico, el error tÃpico es pedirle demasiado en tiempo real, con escrituras sincronizadas y refresh agresivo.
En pipelines serios, la receta se repite:
Esto reduce latencias del usuario y evita que la búsqueda se convierta en cuello de botella por refresh constantes.
RabbitMQ: el seguro de vida para las escrituras (y para la resiliencia)
Cuando un API quiere aguantar picos sin romperse, lo primero que intenta es quitar trabajo del camino crÃtico. RabbitMQ aparece justo ahÃ: separar ?recibo la intención del usuario? de ?procesaré esto con garantÃas?.
Patrón tÃpico para endpoints de escritura:
En entornos donde la durabilidad importa, también se debate el uso de colas más robustas (como quorum queues), con la consecuencia obvia: seguridad a cambio de coste. Esa decisión depende de negocio, no de moda.
«Deep system tuning»: lo que se ajusta cuando la arquitectura ya está bien
Una vez que el sistema está bien dividido (CDN + cachés + colas + runtimes persistentes), llega el momento de ?apretar? la máquina. Ahà aparecen clásicos:
En un medio de programación conviene subrayar algo: no existe un sysctl mágico. El tuning vale lo que vale el diagnóstico: si el cuello está en caché, tocar TCP no arregla nada; si el problema es saturación de conexiones, optimizar PHP tampoco.
Un blueprint «publicable» y repetible
Lecturas (GET) a escala
Escrituras (POST/PUT) sin dolor
PHP 8+ como núcleo de lógica, no como cuello de botella
Preguntas frecuentes
¿Es realmente posible servir 1.000.000 RPS con un API en PHP?
SÃ, si el sistema está diseñado para que la mayorÃa de peticiones se resuelvan en el CDN/edge y el origen solo atienda una fracción (cache misses, auth, escrituras). Pretender 1.000.000 RPS sostenidos golpeando directamente a PHP suele ser un planteamiento irreal o prohibitivamente caro.
¿Qué conviene elegir para un API: RoadRunner, Swoole u FrankenPHP?
Depende del contexto: RoadRunner destaca por su modelo de workers gestionados y un enfoque muy ?servidor de aplicaciones?; Swoole/OpenSwoole por su modelo asÃncrono y corutinas; FrankenPHP por su integración con Caddy y su worker mode, especialmente atractivo con Symfony Runtime o Laravel Octane. La clave es asumir procesos persistentes y controlar estado/memoria.
¿Cómo se integra Elasticsearch sin penalizar la latencia del API?
Separando lecturas de indexación: el API responde y encola eventos, y procesos de ingesta hacen bulk indexing con ajustes de refresh adecuados. Además, cachear búsquedas repetidas (CDN/Redis) evita recalcular consultas populares.
¿Qué patrón evita que las escrituras tiren el sistema cuando hay picos?
El patrón ?aceptar rápido y procesar en background?: POST ? validar ? publicar en RabbitMQ ? responder 202 ? consumidores procesan con reintentos e idempotencia. Es la base de muchos sistemas que necesitan absorber picos sin convertir cada request en una operación pesada.
