Servidores y VPS

Optimizar PHP-FPM en VPS: Pools, Workers y configuración

Configura PHP-FPM correctamente en tu VPS ajustando pools, modo de proceso y límites de workers para maximizar el rendimiento sin agotar la RAM.

Closeup of many cables with blue wires plugged in modern switch with similar adapters on blurred background in modern studio

La configuración predeterminada de PHP-FPM que viene con la mayoría de las distribuciones Linux está pensada para funcionar, no para rendir. Optimizar PHP-FPM en un VPS se reduce a calcular correctamente cuántos workers puedes ejecutar en paralelo sin agotar la RAM disponible, y a separar los pools por sitio para evitar que un pico de tráfico en un dominio arrastre al resto.

¿Por qué importa la configuración de PHP-FPM?

PHP-FPM (FastCGI Process Manager) gestiona un grupo de procesos PHP que esperan solicitudes del servidor web. Si configuras demasiados workers, la RAM se agota y el servidor comienza a hacer swapping, lo que destruye el rendimiento. Si configuras muy pocos, las solicitudes se encolan y los usuarios ven tiempos de respuesta lentos o errores 502.

En un VPS con recursos limitados, el equilibrio exacto entre esos dos extremos puede ser la diferencia entre un sitio rápido y un servidor que se cae a la primera hora pico.

Modos de gestión de procesos (pm)

PHP-FPM ofrece tres modos de gestión de procesos. Elegir el correcto es el primer paso de la optimización:

Modo Comportamiento Cuándo usarlo
static Número fijo de workers siempre activos VPS con tráfico predecible y constante
dynamic Workers se crean y destruyen según la demanda Tráfico variable; es el modo más común
ondemand Workers solo se crean cuando llega una petición VPS pequeños con muchos pools inactivos

Para la mayoría de los VPS con uno o varios sitios activos, dynamic es la mejor opción: permite absorber picos sin desperdiciar RAM en horas valle.

Cálculo de workers: la fórmula práctica

Antes de tocar cualquier archivo de configuración, necesitas saber cuánta RAM consume un proceso PHP en tu aplicación. Ejecuta esto mientras el sitio está recibiendo tráfico normal:

ps --no-headers -o rss -C php-fpm | awk '{ sum += $1 } END { print sum/NR/1024 " MB por proceso" }'

Con ese número, aplica la siguiente fórmula:

max_children = (RAM disponible para PHP) / (RAM por proceso)

Ejemplo con un VPS de 2 GB

  • RAM total: 2048 MB
  • Sistema operativo + MySQL: ~600 MB
  • RAM disponible para PHP: ~1400 MB
  • RAM por proceso PHP (WordPress típico): ~35 MB
  • max_children recomendado: ~40

Nunca establezcas pm.max_children por encima de este resultado. Es mejor quedarse corto y escalar que tener un servidor en swap.

Pools separados por sitio

La configuración de un único pool global es el error más común en VPS con varios sitios. Un pool por dominio ofrece ventajas claras:

  • Aislamiento: si un sitio tiene un pico o un bug en bucle, no consume los workers de los otros.
  • Seguridad: cada pool puede correr con su propio usuario Unix, evitando que un sitio comprometido lea archivos de otro.
  • Observabilidad: cada pool tiene su propio log y socket, facilitando el diagnóstico.

Crea un archivo por sitio en /etc/php-fpm.d/, por ejemplo sitio1.conf:

[sitio1]
user = sitio1
group = sitio1
listen = /run/php-fpm/sitio1.sock
listen.owner = nginx
listen.group = nginx

pm = dynamic
pm.max_children = 15
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 5
pm.max_requests = 500

slowlog = /var/log/php-fpm/sitio1-slow.log
request_slowlog_timeout = 5s

Parámetros clave explicados

  • pm.max_children: límite absoluto de workers simultáneos para este pool.
  • pm.start_servers: workers que arrancan al iniciar el pool (suele ser min_spare + (max_spare - min_spare) / 2).
  • pm.min_spare_servers: mínimo de workers ociosos que siempre deben estar disponibles.
  • pm.max_spare_servers: máximo de workers ociosos; los que superen este número se destruyen.
  • pm.max_requests: cada worker se reinicia después de este número de peticiones, previniendo fugas de memoria.
  • request_slowlog_timeout: registra en el slowlog cualquier petición que tarde más de N segundos — imprescindible para detectar scripts lentos.

Ajustes adicionales de rendimiento

Más allá de los pools, hay parámetros globales y de php.ini que impactan directamente en el rendimiento:

OPcache: obligatorio en producción

OPcache guarda en memoria el bytecode compilado de PHP, eliminando la compilación en cada petición. Verifica que esté activo y bien configurado:

opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.revalidate_freq=60

Con OPcache bien dimensionado, un WordPress puede responder hasta 3-4 veces más rápido en peticiones repetidas.

Límites de memoria y tiempo

Ajusta estos valores en el pool o en php.ini según tus necesidades reales, no a valores exageradamente altos:

memory_limit = 128M
max_execution_time = 30
max_input_time = 30

Subir memory_limit a 512 M sin necesidad solo te da menos margen para workers adicionales.

Para más configuraciones avanzadas de servidor, visita nuestra sección de guías completas para VPS donde encontrarás artículos sobre Nginx, MariaDB y seguridad.

Verificar y monitorizar la configuración

Antes de recargar PHP-FPM, valida la configuración para evitar errores de sintaxis:

php-fpm -t

Si todo está bien, recarga sin cortar peticiones activas:

systemctl reload php-fpm

Para monitorizar el estado en tiempo real, activa el socket de estado en el pool:

pm.status_path = /status

Y consulta el endpoint desde Nginx o Apache configurando una ruta interna. Verás métricas como workers activos, peticiones en cola y total de peticiones procesadas — exactamente lo que necesitas para ajustar tus valores sobre datos reales.

Conclusiones clave

  • Calcula siempre pm.max_children basándote en el consumo real de RAM por proceso, no en valores genéricos.
  • Usa el modo dynamic para absorber picos sin desperdiciar recursos en horas de baja actividad.
  • Separa los pools por sitio para aislar recursos, mejorar la seguridad y facilitar el diagnóstico.
  • Activa y dimensiona OPcache correctamente — es la mejora de rendimiento más sencilla y con mayor impacto.
  • El slowlog es tu mejor aliado para detectar scripts lentos antes de que provoquen un problema de CPU.
  • Valida siempre con php-fpm -t antes de recargar.

¿No tienes claro cuáles son los valores óptimos para tu carga de trabajo específica? Los especialistas de elenlace.com pueden auditar tu configuración actual de PHP-FPM, ajustar cada pool y configurar el monitoreo para que tu VPS rinda al máximo.

Preguntas frecuentes

¿Cuántos workers de PHP-FPM necesito por cada GB de RAM?

Depende del consumo real de tu aplicación. Para WordPress sin plugins pesados, un proceso típico consume entre 25-40 MB, lo que equivale a unos 25-40 workers por GB destinado a PHP. Mide siempre con ps --no-headers -o rss -C php-fpm en condiciones de tráfico real.

¿Qué diferencia hay entre usar un socket Unix y una dirección TCP para el pool?

Los sockets Unix (archivos .sock) son más rápidos porque evitan el stack de red del sistema operativo. Úsalos cuando Nginx/Apache y PHP-FPM están en el mismo servidor. Solo usa TCP (127.0.0.1:9000) si PHP-FPM corre en un servidor separado.

¿Con qué frecuencia debo revisar la configuración de PHP-FPM?

Revisa los valores después de cada cambio significativo en el tráfico, al instalar plugins o módulos que aumenten el consumo de memoria, y al menos una vez cada tres meses como mantenimiento preventivo.

¿El modo ondemand es una buena opción para ahorrar RAM?

Sí, pero solo en pools de sitios con tráfico muy bajo o esporádico. Para sitios con tráfico constante, ondemand puede introducir latencia notable en cada arranque de worker. Combina ambos modos: dynamic para los sitios principales y ondemand para los secundarios inactivos.

¿Prefieres que lo hagamos por ti? En El Enlace resolvemos hosting y desarrollo web profesional.

Para saber más

Otros proveedores y guías que vale la pena comparar:

← Todos