« All posts

PostgreSQL and the Linux OOM Killer: A Safer Default

How strict Linux memory overcommit (vm.overcommit_memory=2) prevents OOM-killer-driven crashes in PostgreSQL, backed by a direct benchmark comparison.

Under Linux's default memory overcommit policy, a process that touches more physical memory than exists gets SIGKILLed by the OOM killer. PostgreSQL is unusually exposed to this: every backend shares one memory segment holding shared buffers, WAL buffers, and lock tables, so a single backend killed mid-query forces the postmaster to assume corruption, terminate every connection, replay the WAL, and restart the entire instance.

The fix is strict overcommit (vm.overcommit_memory=2) with an explicit commit limit computed in kilobytes rather than relying on the kernel's default ratio: 80% of the RAM left after reserving huge pages for shared_buffers, plus a 2GB buffer for sidecar processes. This makes the kernel return ENOMEM while physical memory is still available, so PostgreSQL handles the failure as an ordinary recoverable error.

A controlled memory-pressure test on an m7i.2xlarge compared both policies directly. Under the default loose policy, a backend was OOM-killed, the entire instance crashed, all 20 bystander sessions were dropped, and the server was unreachable for 30 seconds. Under strict overcommit, the same load produced a single 'out of memory' error on one query that rolled back cleanly, with zero dropped sessions and no downtime. Steady-state throughput differences between the two policies were negligible — 2.2% on select-only and 0.6% on read-write workloads, both within normal run-to-run variance.