Table of Contents
The Error
psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed:
could not fork new process for connection: Cannot allocate memory
This error is misleading. It usually does not mean your server is out of RAM in the way people expect. It means that when PostgreSQL’s postmaster tried to fork() a new backend process to serve your connection, the kernel refused the request with ENOMEM. The refusal can come from actual memory pressure, from kernel overcommit accounting, or from per-process resource limits. Understanding which one is the cause is the whole job.
Step 1: Confirm the Server Is Actually Up
Because the socket connection is being refused at fork time, PostgreSQL itself is often still running. Verify this before you assume the database has crashed.
sudo systemctl status postgresql-14
ps -ef | grep postgres | head
If the postmaster process is alive but new connections fail, you are dealing with a resource problem at connection time rather than a database outage. This matters because restarting PostgreSQL may temporarily clear the symptom without fixing the root cause.
Step 2: Check Real Memory and Swap
Look at how much memory and swap are genuinely available on the host.
free -h
cat /proc/meminfo | grep -E 'MemFree|MemAvailable|Commit|Swap'
If MemAvailable is very low and SwapFree is near zero, the machine is under genuine memory pressure. On a database server this is frequently caused by too many concurrent backends, an oversized shared_buffers or work_mem, or another process on the box consuming RAM. Each PostgreSQL connection is a separate OS process and can consume several megabytes or more, so a connection spike multiplies quickly.
Step 3: Investigate Memory Overcommit Settings
This is the most common hidden cause. Linux decides whether to grant a fork() based on its overcommit policy, and a strict policy will reject forks even when free RAM appears available.
cat /proc/sys/vm/overcommit_memory
cat /proc/sys/vm/overcommit_ratio
A value of 2 for overcommit_memory means strict accounting: the kernel will only allow allocations up to swap + RAM * overcommit_ratio / 100. On a server with little or no swap and a low ratio, a busy PostgreSQL instance can hit this ceiling and every new fork fails with Cannot allocate memory, even though free -h shows headroom. The PostgreSQL project generally recommends either overcommit_memory = 2 with a carefully tuned ratio and adequate swap, or leaving it at the default 0. If you are hitting fork failures under strict mode, raising the ratio or adding swap usually resolves it:
# Temporary
sudo sysctl -w vm.overcommit_ratio=80
# Persistent
echo 'vm.overcommit_ratio = 80' | sudo tee -a /etc/sysctl.d/99-postgres.conf
sudo sysctl --system
Step 4: Check Per-Process and cgroup Limits
If the host has plenty of memory but only the postgres user is affected, the constraint is likely a resource limit rather than a system-wide shortage.
Inspect the limits applied to the running postmaster:
cat /proc/$(pgrep -o -u postgres postgres)/limits
Pay attention to Max processes (RLIMIT_NPROC) and Max address space (RLIMIT_AS). A low nproc cap will block new backends once the process count is reached, and the kernel reports this as an allocation failure. On systemd-managed servers, the service unit can also impose TasksMax, MemoryMax, or MemoryHigh through a cgroup:
See also: Mastering the Linux Command Line — Your Complete Free Training Guide
systemctl show postgresql-14 | grep -E 'TasksMax|MemoryMax|MemoryHigh|LimitNPROC'
If TasksMax is set too low, PostgreSQL cannot spawn enough backends. Raise it with a drop-in override:
sudo systemctl edit postgresql-14
[Service]
TasksMax=infinity
LimitNPROC=infinity
Then reload and restart:
sudo systemctl daemon-reload
sudo systemctl restart postgresql-14
Step 5: Look for a Connection Leak or Storm
Even with correct kernel settings, an application that opens connections without closing them will eventually exhaust every limit you configure. Check how many backends currently exist and where they come from.
SELECT count(*) FROM pg_stat_activity;
SELECT client_addr, state, count(*)
FROM pg_stat_activity
GROUP BY client_addr, state
ORDER BY count(*) DESC;
If you see hundreds of idle connections, the real fix is on the client side or in front of the database. Introducing a pooler such as PgBouncer dramatically reduces the number of OS processes PostgreSQL must fork, which both resolves the memory error and improves overall stability.
Step 6: Review Recent System Hardening Changes
Security hardening can quietly introduce this failure. STIG-style remediation often sets kernel.core_pattern, tightens sysctl values, restricts services through systemd cgroups, or lowers process limits. If the error appeared right after a hardening playbook ran, compare the current kernel and limit settings against a known-good baseline, and specifically re-check the vm.overcommit_* values and any TasksMax/LimitNPROC constraints introduced by new unit-file drop-ins. A change intended to constrain a general-purpose host can be too aggressive for a database that legitimately needs many processes.
Step 7: Check the Kernel Log for the Real Reason
Finally, confirm your diagnosis against what the kernel actually recorded.
sudo dmesg -T | grep -Ei 'oom|fork|memory' | tail -20
sudo journalctl -u postgresql-14 --since "1 hour ago"
If the OOM killer has been active, you will see it here and the answer is genuine memory pressure that needs capacity or tuning changes. If there is no OOM activity but forks are still failing, the cause is almost certainly overcommit accounting or a process/cgroup limit from the earlier steps.
Summary of the Diagnostic Path
The fastest way to resolve this error is to work from the outside in: confirm the server is still running, check whether memory is genuinely exhausted, then rule out the two most common silent culprits — Linux memory overcommit accounting (vm.overcommit_memory / vm.overcommit_ratio) and per-process or cgroup limits (RLIMIT_NPROC, TasksMax). In most production cases the RAM is fine and the real fix is either loosening an overly strict overcommit policy, raising the process limits imposed on the postgres service, or putting a connection pooler in front of the database to stop a connection storm from ever reaching the fork limit.




