Home » How to solve FATAL: sorry, too many clients already in PostgreSQL and Node.js
Web & Code

How to solve FATAL: sorry, too many clients already in PostgreSQL and Node.js

✨ Quick Answer

The error FATAL: sorry, too many clients already in PostgreSQL occurs when the number of active and idle client connections exceeds the limit configured in the max_connections parameter (which defaults to 100 on standard PostgreSQL server installations).

The error FATAL: sorry, too many clients already in PostgreSQL occurs when the number of active and idle client connections exceeds the limit configured in the max_connections parameter (which defaults to 100 on standard PostgreSQL server installations).

In modern web stacks using Node.js, Next.js, or Serverless functions (AWS Lambda, Vercel), instantiating direct database clients on every HTTP request rapidly exhausts the database process pool and memory.

Quick Diagnostics

Cause
Unclosed connection leaks
Solution
Always invoke client.release() inside finally blocks when using client checkouts
Cause
Serverless functions spawning unpooled connections
Solution
Implement a centralized Connection Pooler such as PgBouncer or Supabase / Prisma Pooler
Cause
max_connections limit set too low for hardware
Solution
Increase max_connections in postgresql.conf if the server has sufficient RAM

Step-by-Step Solution

Inspect active and idle connection distribution Connect to PostgreSQL using psql and execute the following diagnostic query:

SQL
SELECT state, count(*) 
FROM pg_stat_activity 
GROUP BY state;

To inspect which queries are consuming connection slots:

SQL
SELECT pid, usename, client_addr, state, query_start, query 
FROM pg_stat_activity 
WHERE state != 'idle' 
ORDER BY query_start DESC;

Terminate stuck or zombie connections If you need immediate database recovery access:

SQL
SELECT pg_terminate_backend(pid) 
FROM pg_stat_activity 
WHERE state = 'idle' AND pid <> pg_backend_pid();

Configure global Connection Pooling in Node.js Never create new Client() per API endpoint. Always reuse a single shared Pool:

JAVASCRIPT
import { Pool } from 'pg';

const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
  max: 20, // Max concurrent connections per worker
  idleTimeoutMillis: 30000,
  connectionTimeoutMillis: 2000,
});

export async function query(text, params) {
  const client = await pool.connect();
  try {
    return await client.query(text, params);
  } finally {
    client.release(); // Crucial: return connection back to pool
  }
}

Increase max_connections in postgresql.conf For dedicated production servers with 8GB+ RAM, adjust /etc/postgresql/16/main/postgresql.conf:

INI
max_connections = 250
shared_buffers = 2GB

Restart the service to apply changes:

BASH
sudo systemctl restart postgresql

Prevention Advice

Recommended security practices:

  • Deploy PgBouncer in transaction mode: Place PgBouncer in front of PostgreSQL in production. This allows serving over 10,000 concurrent client requests using only 50 physical backend database connections.
  • Connection monitoring: Configure automated alerts when active connections exceed 80% of max_connections.