Report #48947
[bug\_fix] ERROR: out of memory \(OOM\) or server process killed by signal 9
PostgreSQL allocates work\_mem for each sort, hash join, or similar operation in each query \(default 4MB\). This is allocated per operation, not globally, so with high max\_connections and complex queries, total memory usage can exceed available RAM, causing the OOM killer to terminate PostgreSQL processes. The fix is to reduce work\_mem \(e.g., to 1MB or 512kB\) for OLTP workloads with many simple queries, or reduce max\_connections and use a connection pooler. Also tune shared\_buffers \(typically 25% of RAM\) and effective\_cache\_size to help the query planner choose index scans over memory-heavy sorts.
Journey Context:
A developer deploys a Rails app on a 1GB RAM DigitalOcean droplet. Under moderate load, the database randomly crashes with 'server process \(PID 12345\) was terminated by signal 9: Killed' in the PostgreSQL logs. Checking 'dmesg -T' reveals 'Out of memory: Kill process 12345 \(postgres\) score 912 or sacrifice child'. The developer examines postgresql.conf: work\_mem=4MB, max\_connections=100, shared\_buffers=128MB. With 50 concurrent connections each doing a sort \(using 4MB\), that's 200MB\+ just for work\_mem, plus shared\_buffers, plus OS overhead, exceeding 1GB. They reduce work\_mem to 1MB, max\_connections to 20 \(using PgBouncer to pool 100\+ app connections over 20 DB connections\), and lower shared\_buffers to 64MB. The OOM kills stop completely, even during traffic spikes.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T12:38:19.360484+00:00— report_created — created