Linux OOM Killer Tuning for VPS: Una Guía Práctica
12 min de lectura - 8 de junio de 2026

Ajuste el OOM killer de Linux en su VPS para proteger las bases de datos y SSH, limitar los procesos fuera de control con cgroups y evitar que se mate el servicio equivocado.
Ajuste del OOM killer de Linux para VPS
El OOM killer de Linux es el último recurso del kernel cuando se agota la memoria: elige un proceso y lo termina para mantener el sistema en funcionamiento. En un VPS, donde la RAM es escasa y no hay a dónde recurrir, la elección predeterminada suele ser la incorrecta. Tu base de datos se ve afectada, un proceso de larga duración sobrevive y te quedas sin saber por qué. Esta guía explica cómo el OOM killer puntúa los procesos, cómo inclinar esa puntuación hacia tus servicios críticos y cómo utilizar cgroups para que un único proceso descontrolado no pueda derribar el resto del sistema con él.
Cómo elige el OOM killer a su víctima
Cuando el kernel no puede recuperar suficiente memoria mediante la expulsión de la caché de páginas o el intercambio, invoca al OOM killer. Cada proceso tiene una oom_score puntuación entre 0 y 1000, derivada principalmente de su tamaño de conjunto residente (RSS) y del uso del intercambio. El proceso con la puntuación más alta recibe un SIGKILL.
El RSS domina el cálculo, por lo que la terminación casi siempre recae sobre el mayor consumidor de memoria. A menudo se trata de su base de datos, su servidor de aplicaciones o cualquier proceso de larga duración que esté realizando el trabajo más útil. El proceso que realmente desencadenó la asignación, el «invoker», rara vez es el que se termina.
Hay dos tipos de eventos OOM que debes diferenciar:
- OOM global: el host (o tu VPS en su conjunto) se ha quedado sin RAM y sin espacio de intercambio. El kernel analiza todos los procesos y termina el que tiene la puntuación más alta.
- OOM de cgroup: un cgroup específico ha alcanzado su límite de memoria. El kernel solo termina procesos dentro de ese cgroup, incluso si el resto del sistema tiene memoria de sobra.
Si has configurado límites de unidad en systemd o estás ejecutando contenedores, la mayoría de tus eventos OOM serán OOM de cgroup. Eso es bueno: el alcance del impacto queda contenido.
Detectar la presión sobre la memoria antes de que se produzca el bloqueo
Los eventos OOM casi nunca son repentinos. Normalmente hay primero un periodo de aumento de la presión, y el objetivo de la monitorización es detectarlo dentro de ese periodo.
free -h te ofrece la vista del sistema. La columna que importa es available, no free: representa la caché de páginas recuperable y refleja lo que realmente se puede asignar sin necesidad de intercambio. Mantén MemAvailable por encima de aproximadamente el 10-15 % de MemTotal en momentos de máxima carga.
Para la atribución por proceso, ordena por RSS:
ps aux --sort=-%mem | head -10O utilice htop y ordena por RES. Los valores que se ven aquí se incorporan directamente a la puntuación del kernel, por lo que las entradas principales son los objetivos más probables de OOM.
En los kernels 4.20 y posteriores, la información de estancamiento por presión (Pressure Stall Information) es el sistema de alerta temprana que vale la pena integrar en la monitorización:
cat /proc/pressure/memoryLa some avg10 cifra es el porcentaje de tiempo en el que al menos una tarea se ha quedado bloqueada esperando memoria durante los últimos diez segundos. Por debajo del 5 % está bien. Valores sostenidos por encima del 10 % significan que el sistema está dedicando tiempo real bloqueado en la recuperación de memoria, y es plausible que se produzca un OOM kill.
El thrashing de swap aparece en vmstat 1 como un valor distinto de cero si y so que se mantienen a lo largo del tiempo. Una pequeña cantidad de intercambio residente es inofensiva. El intercambio constante de entrada y salida no lo es.
Protección de procesos críticos con oom_score_adj
La puntuación que calcula el kernel puede ajustarse por proceso mediante oom_score_adj, en una escala de -1000 (inmune) a +1000 (matarme primero). El ajuste se suma directamente a la puntuación final.
Para un cambio puntual en un proceso en ejecución:
echo -500 | sudo tee /proc/$(pidof sshd)/oom_score_adjPara cualquier cosa que quieras que persista tras los reinicios, configúralo en la unidad de systemd. Ese es el lugar adecuado para sshd, tu base de datos y cualquier otra cosa que no puedas permitirte perder:
[Service]
OOMScoreAdjust=-900Valores predeterminados sensatos con los que empezar:
- sshd: -1000. Si pierdes el acceso remoto durante una crisis de memoria, la recuperación se complica mucho.
- MySQL, PostgreSQL, Redis: de -800 a -900. Una protección sólida sin hacerlos completamente intocables en una situación verdaderamente catastrófica.
- Procesos de aplicación, trabajos por lotes, tareas cron: de +100 a +500. Estos son los procesos que prefieres que se cierren antes que tu base de datos.
No lo pongas todo en -1000. Si no se puede matar nada, el kernel acabará entrando en pánico o bloqueándose, lo cual es peor.
Limitación de la memoria con cgroups y systemd
Ajustar las puntuaciones influye en quién se elimina. Los cgroups influyen en si la eliminación global llega a producirse. Al asignar a cada servicio un límite máximo estricto, se concentran los fallos de memoria en un único cgroup en lugar de permitir que un solo proceso agote todo el VPS.
En un archivo de unidad de systemd:
[Service]
MemoryHigh=400M
MemoryMax=512M
OOMPolicy=stop
Restart=on-failure
RestartSec=5sMemoryHigh es un limitador suave: el kernel recupera agresivamente páginas del cgroup por encima de este punto, pero no termina ningún proceso. MemoryMax es el límite máximo estricto. Si el cgroup intenta asignar más allá de este límite, el kernel elimina un proceso dentro del cgroup. Con Restart=on-failure el servicio se reinicia inmediatamente.
En cgroup v2 (Ubuntu 22.04 y posteriores, Debian reciente, RHEL 9), memory.oom.group termina todos los procesos del cgroup a la vez en lugar de dejar procesos huérfanos. Útil para servicios multiproceso como los pools de PHP-FPM, donde un grupo a medio terminar funcionará mal.
Algunas notas específicas de la aplicación que vale la pena aplicar:
- PHP-FPM: configúralo
pm = ondemanden instancias VPS pequeñas y ajustapm.max_childrenen función del RSS medio por trabajador, no del valor predeterminado. Un grupo dimensionado con 4 GB de margen en un VPS de 2 GB agotará la memoria (OOM) la primera vez que se llene. - Node.js: limita el montón de V8 con
--max-old-space-size=512(en MB). Sin ello, Node seguirá creciendo sin problemas hasta que intervenga el kernel. - MySQL y PostgreSQL:
innodb_buffer_pool_sizeyshared_buffersdeberían dejar un margen de memoria libre para la caché de páginas del sistema operativo, la memoria de conexión y cualquier otro usuario del servidor. Los valores predeterminados asumen un servidor dedicado.
Lectura de los registros tras un evento OOM
Cuando se activa el OOM killer, el kernel volca un informe detallado en el búfer circular. Se puede extraer con:
dmesg -T | grep -iE 'killed process|out of memory'
journalctl -k --grep='Out of memory'El bloque que hay que leer con atención comienza con el invocador y termina con la víctima. El kernel imprime una lista completa de tareas con el RSS de cada proceso, el uso de swap y el oom_score_adj. Hay tres cosas que vale la pena comprobar:
- La restricción.
CONSTRAINT_NONEsignifica un OOM global,CONSTRAINT_MEMCGsignifica que un cgroup ha alcanzado su límite. La solución es diferente en cada caso. Free swap. Si esto es0kB, se han agotado tanto la RAM como el swap. Añade swap, aumentaMemoryMaxal proceso causante o reducir la concurrencia.- La puntuación de la víctima frente al resto. Si la puntuación de la víctima no es mucho más alta que la de los siguientes procesos, tus
oom_score_adjvalores no están funcionando lo suficiente. Aumenta la diferencia.
En el caso concreto de los OOM de cgroup, el contador de terminaciones se encuentra memory.events dentro del cgroup:
cat /sys/fs/cgroup/system.slice/mysql.service/memory.eventsUn oom_kill significa que el servicio está alcanzando su límite repetidamente. Esa es una señal para aumentar MemoryMax, analizar la carga de trabajo o trasladar el servicio a un plan de mayor capacidad, en lugar de seguir reiniciándolo en bucle.
Conclusión
Ajustar el OOM killer no consiste en hacer que desaparezca. Se trata de controlar qué proceso paga el precio cuando se agota la memoria y de reducir el alcance del impacto cuando esto ocurre. La pauta que se mantiene en producción:
- Protege con puntuación los servicios que no puedes permitirte perder, especialmente sshd y tus bases de datos.
- Limita todo lo demás con
MemoryMaxen una unidad de systemd para que un solo proceso descontrolado suponga un simple reinicio, no una interrupción del servicio. - Vigila el PSI y
MemAvailableen lugar de esperar admesga que te informe de lo sucedido a posteriori. - Deja entre un 15 y un 20 por ciento de RAM como margen. El ajuste no puede compensar un VPS que es simplemente demasiado pequeño para la carga de trabajo.
Si la presión sobre la memoria es estructural en lugar de configurable, necesitas más RAM o un almacenamiento respaldado por swap más rápido. Los planes VPS de FDC Servers se ejecutan en AMD EPYC con almacenamiento NVMe, lo que mantiene las lecturas respaldadas por swap lo suficientemente rápidas como para que los picos de memoria breves no se conviertan en bloqueos.

Linux OOM Killer Tuning for VPS: Una Guía Práctica
Ajuste el OOM killer de Linux en su VPS para proteger las bases de datos y SSH, limitar los procesos fuera de control con cgroups y evitar que se mate el servicio equivocado.
12 min de lectura - 8 de junio de 2026
Linux Traffic Control (tc): una guía práctica
12 min de lectura - 5 de junio de 2026