Fix 'Cannot allocate memory' in PostgreSQL on Linux
PostgreSQL hits this when the OS runs out of memory or kernel params are too low. Quick fix: restart the service. Real fix: tune kernel.shmmax and vm.overcommit.
30-Second Fix: Restart the Service
Before you dive into kernel tuning, try this: restart PostgreSQL. I've seen this error pop up because a runaway query ate all available connections, and a restart flushes them all out.
sudo systemctl restart postgresql-14
# or on older systems:
sudo service postgresql restart
Wait 10 seconds. Try connecting again. If it works, you're done — but keep reading, because it'll happen again unless you fix the root cause.
No luck? Move to the next step.
5-Minute Fix: Check Memory and Kernel Parameters
This error almost always means PostgreSQL can't allocate shared memory or fork a new process. First, check your actual free memory:
free -h
# look at the 'available' column — not 'free'. If it's below 500MB, you're out of RAM.
If memory is low, kill some processes. Use htop or top, sort by memory usage (M in top), and kill anything eating more than 10% that isn't critical.
Next, check the kernel's shared memory limits. The culprit is often kernel.shmmax being set too low for PostgreSQL's shared_buffers.
sysctl kernel.shmmax
# default is usually 18446744073692774399 (18 exabytes on 64-bit) — fine.
# But if you see 33554432 (32MB) or lower, that's your problem.
Also check vm.overcommit_memory. If it's set to 2, the kernel is strict about memory overcommit and will deny allocations even if there's swap available.
sysctl vm.overcommit_memory
# 0 = heuristic (good), 1 = always allow (risky), 2 = strict (bad for PG)
If vm.overcommit_memory is 2, change it to 0 or 1.
sudo sysctl -w vm.overcommit_memory=0
sudo sysctl -w kernel.shmmax=17179869184 # 16GB, adjust to your RAM
sudo sysctl -p
Make these permanent by adding them to /etc/sysctl.conf or a file in /etc/sysctl.d/:
echo 'vm.overcommit_memory = 0' | sudo tee -a /etc/sysctl.conf
echo 'kernel.shmmax = 17179869184' | sudo tee -a /etc/sysctl.conf
Restart PostgreSQL again. If it works, you're solid. If not, move to advanced.
15+ Minute Fix: Tune PostgreSQL Memory Settings
Sometimes the problem isn't the OS — it's PostgreSQL itself asking for too much. Open postgresql.conf (usually in /etc/postgresql/14/main/ or /var/lib/pgsql/14/data/).
Three settings matter here:
shared_buffers— should be 25% of your system RAM max. If you have 8GB, set it to 2GB. Never go over 4GB on a 32-bit system.max_connections— each connection eats about 10MB. If you have 200 connections, that's 2GB right there. Cut it down if you can.work_mem— per-sort memory. If you have 100 connections andwork_memis 32MB, that's 3.2GB potential peak. Set it lower, like 4MB, and let the queries sort on disk if needed.
Here's a sensible config for an 8GB server with moderate load:
shared_buffers = 2GB
max_connections = 100
work_mem = 4MB
maintenance_work_mem = 256MB
After changing these, restart PostgreSQL:
sudo systemctl restart postgresql-14
Still failing? Check the logs. Tail them while trying to connect:
sudo journalctl -u postgresql-14 -f
# or check /var/log/postgresql/postgresql-14-main.log
Look for lines like out of memory or could not fork. If you see FATAL: sorry, too many clients already, you hit max_connections — reduce it or increase max_connections and restart.
Last Resort: Disable Overcommit Entirely
If you're on a development box and don't care about stability, set vm.overcommit_memory=1. This tells the kernel to never deny a memory request. It can cause OOM kills, but it'll stop the PostgreSQL error cold.
sudo sysctl -w vm.overcommit_memory=1
Make it permanent the same way as above. Don't do this on a production database server — you'll get random process kills under memory pressure.
Don't Bother With These
- Increasing swap — rarely helps. PostgreSQL doesn't like swapping.
- Setting
kernel.shmall— almost never the issue on modern kernels. - Reinstalling PostgreSQL — a complete waste of time.
Stick with the steps above. Nine times out of ten, it's vm.overcommit_memory=2 or shared_buffers set way too high. Fix those and you're golden.
Was this solution helpful?