Un administrador revisa métricas de memoria y procesos de PostgreSQL en una pantalla de monitoreo dentro de un centro de datos.

Postgres y el OOM killer: evita caídas

Postgres y el OOM killer pueden chocar cuando la memoria se agota en producción. Aquí ves por qué el overcommit estricto ayuda a equipos que operan PostgreSQL en Latinoamérica a mantener estabilidad, evitar kills inesperados y definir límites más predecibles.

Si operas PostgreSQL en producción, hay una decisión de sistema operativo que puede parecer menor hasta que te explota en la cara: cómo maneja Linux la memoria cuando el servidor se queda corto. En ese momento aparece el OOM killer, el proceso del kernel que mata tareas para recuperar memoria. Si te toca en el proceso equivocado, puedes pasar de una degradación controlada a una caída brusca de tu base de datos.

El problema no es teórico. En un servidor con varias cargas compartiendo RAM, Postgres puede estar funcionando bien durante horas y de pronto recibir presión de memoria por un pico de conexiones, un query pesado, un mantenimiento, o incluso otro servicio del mismo host. Si el sistema está configurado con overcommit permisivo, Linux puede prometer más memoria de la que realmente tiene y dejar que el problema aparezca tarde, cuando ya hay procesos críticos corriendo. Con overcommit estricto, en cambio, el kernel rechaza antes las asignaciones que no puede respaldar. Eso cambia mucho el tipo de fallo que ves.

Qué hace el OOM killer y por qué te afecta

El OOM killer no es un bug ni un capricho. Es el mecanismo de emergencia de Linux cuando ya no puede satisfacer una solicitud de memoria y no ve una salida limpia. Su trabajo es elegir un proceso para terminarlo y liberar RAM. El criterio no siempre coincide con lo que tú consideras más valioso. Puede matar una app de negocio, un worker, una tarea de mantenimiento o, en el peor caso, un proceso de PostgreSQL.

En sistemas con Postgres, eso importa porque la base no suele vivir sola. Muchas veces comparte máquina con agentes de observabilidad, jobs de backup, contenedores auxiliares o incluso otros servicios de la plataforma. Si el kernel decide que el proceso que debe morir es uno de Postgres, el impacto puede ser mayor que una simple query fallida: conexiones cortadas, replicas atrasadas, failovers innecesarios o una ventana de indisponibilidad que no habías planeado.

Cómo llega Linux a esa decisión

Linux no espera a que el sistema esté totalmente muerto para actuar. Cuando una asignación falla y el kernel ve que no puede satisfacerla, entra en modo de rescate. Ahí evalúa qué proceso liberar según heurísticas internas, prioridad y consumo de memoria. La lógica exacta puede variar según configuración, cgroups y otros factores, pero el resultado práctico es el mismo: alguien muere para que el resto sobreviva.

Eso se vuelve especialmente delicado en bases de datos porque PostgreSQL no es un proceso único simple. Tiene el postmaster, backends por conexión, procesos de autovacuum, background writer, wal writer y otros auxiliares. Si el sistema está bajo presión, el proceso que cae puede ser uno que no esperabas, y el efecto en la base puede ser más amplio que el consumo de memoria que originó el problema.

Según la documentación oficial de Linux, el comportamiento de overcommit se controla con vm.overcommit_memory y valores como 0, 1 y 2 cambian cómo el kernel permite o niega asignaciones. Puedes revisar la referencia del kernel en admin-guide/mm/overcommit-accounting.

Por qué PostgreSQL es sensible a la sobreasignación

PostgreSQL usa memoria de varias formas. Algunas asignaciones son por conexión, otras por query, y varias dependen de parámetros como work_mem, maintenance_work_mem y shared_buffers. El problema es que el consumo real no se ve solo en una cifra. Se multiplica por concurrencia, por el número de sesiones activas y por el tipo de operación que corre en ese momento.

Un ejemplo simple: si tienes 100 conexiones y cada una puede usar hasta 16 MB de work_mem en una consulta con sort o hash, ya no estás hablando de 1.6 GB teóricos aislados. En la práctica, varias operaciones pueden usar memoria al mismo tiempo, y además están los buffers compartidos, el overhead del proceso y el resto del sistema. Si agregas autovacuum o un backup concurrente, el margen se reduce rápido.

Memoria que se promete, memoria que se usa

Aquí está la trampa clásica: una configuración puede parecer segura en papel porque cada parámetro individual luce razonable. Pero el sistema operativo no mira solo parámetros aislados, mira el conjunto de reservas y el estado real de la RAM. Si el kernel permite reservar más de lo que puede respaldar, Postgres puede seguir aceptando trabajo hasta que algo más rompa.

Con overcommit estricto, el sistema se vuelve más conservador. No te deja prometer memoria de forma irreal. Eso obliga a que el error aparezca antes, normalmente en el punto de asignación, donde es más fácil detectar, medir y corregir. Para una base de datos en producción, ese tipo de falla es mucho más manejable que una muerte aleatoria por OOM.

El costo real de una muerte por OOM

Cuando el OOM killer mata un backend de PostgreSQL, el efecto visible puede ser una transacción abortada. Pero si mata el proceso principal o varios procesos auxiliares, el costo sube. Puedes perder conexiones activas, disparar reconexiones en cascada y generar una carga extra justo cuando menos te conviene.

Además, el reinicio automático no siempre resuelve el problema de fondo. Si la causa sigue presente, la máquina puede volver a entrar en presión de memoria y repetir el ciclo. Eso convierte un incidente de capacidad en una serie de caídas intermitentes, que suelen ser más difíciles de diagnosticar que un fallo único y limpio.

Qué significa usar strict memory overcommit

Strict memory overcommit, en Linux, corresponde al modo vm.overcommit_memory=2. En ese modo, el kernel calcula de forma más estricta si una asignación de memoria puede ser respaldada por la RAM disponible y el swap configurado, usando también el overcommit_ratio según el caso. Si no hay respaldo suficiente, la asignación falla de inmediato.

La ventaja es directa: reduces la probabilidad de que el sistema acepte carga de más y termine matando procesos por sorpresa. En vez de dejar que la presión se acumule hasta un evento de emergencia, fuerzas a que el problema se manifieste antes, de forma más predecible. Para infraestructura de bases de datos, eso suele ser una mejor negociación entre disponibilidad y error temprano.

Modo permisivo versus modo estricto

La diferencia práctica entre un modo y otro se ve mejor con una tabla simple:

ModoQué permiteRiesgo principalComportamiento típico
0 heurísticoDecide según heurísticas del kernelDifícil de predecirPuede aceptar más de lo ideal
1 siempre overcommitPromete memoria de forma agresivaOOM más tarde y más bruscoFalla cuando ya hay presión fuerte
2 estrictoLimita según respaldo realMás errores de asignación tempranosRechaza antes y evita sorpresas

En producción, el punto no es elegir el modo más “optimista”, sino el que te da mejores fallos. Si una asignación no puede sostenerse, prefieres enterarte en la capa que la pidió, no cuando el kernel ya está cazando procesos.

Qué cambia para Postgres en la práctica

Con overcommit estricto, Postgres puede recibir un error al intentar reservar memoria para una operación, en lugar de empujar al sistema al borde. Eso no elimina la necesidad de dimensionar bien shared_buffers, work_mem o el número de conexiones. Solo hace que el sistema sea más honesto sobre su capacidad real.

Ese comportamiento ayuda mucho cuando operas varias bases o varios servicios en el mismo host. También mejora la previsibilidad en entornos con picos, como ecommerce, fintech o analítica, donde una carga puntual puede disparar el uso de memoria en segundos.

Cómo se configura y qué revisar antes de tocarlo

Antes de cambiar el modo de overcommit, conviene revisar el contexto completo del servidor. No basta con poner un valor y asumir que todo se arregla. Necesitas entender cuánta RAM tienes, cuánto swap existe, qué otros procesos viven en la máquina y qué tan agresiva es tu configuración de PostgreSQL.

El cambio se hace con sysctl o editando la configuración persistente del sistema. Un ejemplo típico sería:

sudo sysctl -w vm.overcommit_memory=2
sudo sysctl -w vm.overcommit_ratio=90

Eso aplica el cambio de forma temporal. Para hacerlo persistente, normalmente se coloca en un archivo de configuración de sysctl, según la distribución que uses. La documentación de sysctl y del kernel te da el detalle fino, pero la idea operativa es sencilla: defines una política más estricta para las reservas de memoria.

Checklist antes del cambio

  1. Mide el consumo real de RAM del host durante horas pico y fuera de pico.
  2. Revisa el número de conexiones activas y el máximo configurado en PostgreSQL.
  3. Calcula un techo razonable para work_mem por sesión y por tipo de consulta.
  4. Verifica cuánto swap tienes y si realmente se usa o solo está ahí como respaldo.
  5. Confirma que los procesos críticos del host no compiten con Postgres por la misma RAM.
  6. Prueba el cambio en staging con cargas parecidas a producción.

Si operas en Kubernetes o en una plataforma con cgroups, también debes revisar los límites del contenedor o del pod. El comportamiento de memoria no depende solo del kernel global. Los límites del grupo de control pueden cambiar por completo cómo se llega a un OOM, y ese OOM puede ocurrir dentro del contenedor antes de que el host entero sufra.

Cómo lo pensamos nosotros al operar bases en producción

Cuando nosotros operamos PostgreSQL, preferimos que el sistema falle temprano y de forma visible antes que aceptar una carga imposible y esperar al OOM killer. Esa preferencia no viene de teoría, viene de incidentes reales donde la causa original era pequeña pero el efecto final era grande. Un proceso muerto por memoria no siempre deja una pista clara, y reconstruir el contexto después cuesta tiempo.

También nos importa que el comportamiento sea consistente entre entornos. Si en staging la memoria se comporta de una manera y en producción de otra, las pruebas pierden valor. Por eso una política estricta ayuda: hace que los límites sean más parecidos entre sí y reduce la cantidad de sorpresas cuando una carga crece.

Cuándo sí y cuándo no conviene

Strict overcommit no es una receta mágica para todos los servidores. Si tienes una máquina generalista con cargas muy variables y aplicaciones que toleran mejor un OOM tardío que un rechazo temprano, el balance puede ser distinto. Pero en un host dedicado a bases de datos, o al menos con prioridad clara para Postgres, suele ser una apuesta razonable.

Tampoco reemplaza el sizing. Si shared_buffers está sobredimensionado, si permites demasiadas conexiones o si work_mem está inflado, el problema sigue ahí. La política estricta solo evita que el sistema oculte el exceso hasta que ya sea tarde.

Tabla resumen

Pregunta cortaRespuesta corta
¿Qué hace el OOM killer?Mata procesos para liberar memoria cuando Linux ya no puede seguir.
¿Por qué afecta a Postgres?Porque puede matar backends o procesos auxiliares críticos.
¿Qué es overcommit estricto?Un modo de Linux que niega reservas sin respaldo suficiente.
¿Qué gana tu operación?Fallos más tempranos, predecibles y fáciles de diagnosticar.
¿Reemplaza el tuning de Postgres?No, solo reduce el riesgo de sorpresas por memoria.
¿Dónde revisar el detalle oficial?En la documentación del kernel de Linux sobre overcommit.

La idea central es simple: si tu base de datos vive en un host con memoria limitada, no quieres que el sistema operativo te venda una promesa falsa. Quieres límites claros, errores tempranos y menos probabilidades de que el OOM killer elija por ti qué proceso debe morir. Para Postgres en producción, esa diferencia vale mucho más que unos cuantos megabytes reservados de forma optimista.

Referencias útiles

Preguntas frecuentes

¿El OOM killer siempre mata a PostgreSQL primero?
No. El kernel elige según su heurística y el contexto del sistema. A veces mata un worker, otra app del host o un proceso auxiliar, y el impacto final puede variar mucho.
¿Strict overcommit evita por completo los OOM?
No los elimina, pero cambia el momento y la forma del fallo. En lugar de aceptar memoria de más y morir tarde, el sistema rechaza antes las asignaciones que no puede respaldar.
¿Esto sirve si Postgres corre en un contenedor?
Sí, pero debes revisar también los límites del contenedor y del cgroup. El comportamiento de memoria puede disparar un OOM dentro del pod aunque el host todavía tenga recursos.
¿Qué parámetro de Linux activa el modo estricto?
El valor `vm.overcommit_memory=2`. Según la documentación oficial del kernel, ese modo aplica una política más estricta para las reservas de memoria.
¿Debo subir `work_mem` si activo overcommit estricto?
No por defecto. Primero mide tu carga real y ajusta con cuidado, porque un `work_mem` alto multiplicado por muchas conexiones puede empeorar la presión de memoria.
¿Qué pasa si una query necesita más memoria de la que hay?
La asignación puede fallar antes, y eso es preferible a que el sistema entre en una situación donde el kernel mate procesos al azar. El error temprano te da una señal más útil para corregir capacidad o consulta.
¿Es buena idea para un servidor dedicado solo a Postgres?
En muchos casos sí, sobre todo si buscas estabilidad predecible. Aun así, debes validar el sizing de memoria, conexiones y swap antes de cambiar la política.

Azirgo

¿Listo para construir tu Producto Digital?

Sitios web, apps móviles, software a medida y soluciones blockchain. Cuéntanos qué tienes en mente y armamos un plan claro contigo.

  • Cotización clara en 48 horas
  • Equipo en Ecuador, atención en español
  • Desde un MVP hasta un producto en producción