# PostgreSQL Connection Limit Exceeded - Troubleshooting Guide

The dreaded "FATAL: sorry, too many clients already" error means PostgreSQL has hit its connection limit. This typically indicates either a connection leak in your application or insufficient connection pooling. Let's diagnose and fix the root cause.

Introduction

This article covers troubleshooting steps and solutions for PostgreSQL Connection Limit Exceeded - Troubleshooting Guide. The error typically occurs in production environments and can cause service disruptions if not addressed promptly.

Symptoms

Common error messages include:

```bash # Check current connection limit psql -U postgres -c "SHOW max_connections;"

# Default is typically 100 ```

```sql -- View current connection count SELECT count(*) AS total_connections FROM pg_stat_activity;

-- View connections by state SELECT state, count(*) AS count FROM pg_stat_activity GROUP BY state ORDER BY count DESC;

-- View connections by database SELECT datname AS database, count(*) AS connections FROM pg_stat_activity GROUP BY datname ORDER BY connections DESC;

-- View connections by user and application SELECT usename AS username, application_name, client_addr, count(*) AS connections FROM pg_stat_activity GROUP BY usename, application_name, client_addr ORDER BY connections DESC; ```

```bash # PostgreSQL reserves connections for superusers (default 3) psql -U postgres -c "SHOW superuser_reserved_connections;"

# Connect as superuser to diagnose psql -U postgres

# If that fails, increase reserved temporarily # This won't help if all superuser connections are also used ```

Common Causes

  • Configuration misconfiguration
  • Missing or incorrect credentials
  • Network connectivity issues
  • Version compatibility problems
  • Resource exhaustion or limits
  • Permission or access denied

Step-by-Step Fix

  1. 1.Check logs for specific error messages
  2. 2.Verify configuration settings
  3. 3.Test network connectivity
  4. 4.Review recent changes
  5. 5.Apply corrective action
  6. 6.Verify the fix

Understanding Connection Limits

```bash # Check current connection limit psql -U postgres -c "SHOW max_connections;"

# Default is typically 100 ```

```sql -- View current connection count SELECT count(*) AS total_connections FROM pg_stat_activity;

-- View connections by state SELECT state, count(*) AS count FROM pg_stat_activity GROUP BY state ORDER BY count DESC;

-- View connections by database SELECT datname AS database, count(*) AS connections FROM pg_stat_activity GROUP BY datname ORDER BY connections DESC;

-- View connections by user and application SELECT usename AS username, application_name, client_addr, count(*) AS connections FROM pg_stat_activity GROUP BY usename, application_name, client_addr ORDER BY connections DESC; ```

Immediate Recovery

When you can't connect due to connection limit, use these approaches:

Method 1: Use Reserved Superuser Connection

```bash # PostgreSQL reserves connections for superusers (default 3) psql -U postgres -c "SHOW superuser_reserved_connections;"

# Connect as superuser to diagnose psql -U postgres

# If that fails, increase reserved temporarily # This won't help if all superuser connections are also used ```

Method 2: Terminate Idle Connections

```sql -- Terminate idle connections (be careful in production) SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle' AND usename NOT IN ('postgres') AND query_start < now() - interval '5 minutes';

-- More aggressive: terminate all but current session SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE pid <> pg_backend_pid() AND usename NOT IN ('postgres'); ```

Method 3: Kill via Operating System

```bash # List PostgreSQL processes ps aux | grep postgres

# Identify idle connections ps aux | grep "postgres:" | grep "idle"

# Kill specific process (last resort) kill -TERM <pid>

# Kill all idle connections (very aggressive) pkill -f "idle in transaction" ```

Diagnosing Connection Leaks

A connection leak occurs when applications open connections but fail to close them:

```sql -- Find long-running connections SELECT pid, usename, application_name, client_addr, state, query_start, now() - query_start AS duration, query FROM pg_stat_activity WHERE state <> 'idle' ORDER BY query_start;

-- Find connections waiting for something SELECT pid, usename, state, wait_event_type, wait_event, query FROM pg_stat_activity WHERE wait_event IS NOT NULL ORDER BY query_start;

-- Find idle-in-transaction connections (dangerous!) SELECT pid, usename, application_name, state, query_start, now() - query_start AS idle_duration FROM pg_stat_activity WHERE state = 'idle in transaction' ORDER BY query_start; ```

Application Connection Leak Patterns

```python # Python - BAD (connection leak) def get_user(user_id): conn = psycopg2.connect(dsn) cursor = conn.cursor() cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,)) return cursor.fetchone() # Connection never closed!

# Python - GOOD (using context manager) def get_user(user_id): with psycopg2.connect(dsn) as conn: with conn.cursor() as cursor: cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,)) return cursor.fetchone() ```

```javascript // Node.js - BAD (connection leak) function getUser(userId) { const client = new Client(config); client.connect(); return client.query('SELECT * FROM users WHERE id = $1', [userId]); // Client never ended! }

// Node.js - GOOD (using async/await) async function getUser(userId) { const client = new Client(config); try { await client.connect(); const result = await client.query('SELECT * FROM users WHERE id = $1', [userId]); return result.rows[0]; } finally { await client.end(); } } ```

Connection Pooling Configuration

Without connection pooling, each application instance opens its own connections:

```bash # Install PgBouncer (recommended pooler) sudo apt-get install pgbouncer

# Configuration file: /etc/pgbouncer/pgbouncer.ini [databases] mydb = host=127.0.0.1 port=5432 dbname=mydb

[pgbouncer] listen_addr = 127.0.0.1 listen_port = 6432 auth_type = md5 auth_file = /etc/pgbouncer/userlist.txt pool_mode = transaction max_client_conn = 1000 default_pool_size = 25 min_pool_size = 5 reserve_pool_size = 5 reserve_pool_timeout = 3 ```

Connection Pool Settings Explained

```ini # Pool mode options: # - session: One server connection per client connection (least efficient) # - transaction: Server connection released after each transaction (recommended) # - statement: Server connection released after each statement (limitations apply)

# Size calculations: # max_client_conn = max expected concurrent clients # default_pool_size = max connections to PostgreSQL per database # = (target_concurrent_queries * avg_query_time) / avg_client_wait_time # Typical: 20-50 for most workloads

# Example for 100 concurrent clients with 25ms avg query time: # default_pool_size = (100 * 0.025) / 0.1 = 25 connections to PostgreSQL ```

Increasing max_connections

If connection pooling isn't enough:

```bash # Edit postgresql.conf sudo nano /etc/postgresql/16/main/postgresql.conf

# Increase connection limit max_connections = 200

# Also adjust shared memory proportionally # Each connection uses ~2MB for work_mem shared_buffers = 256MB # Increase if max_connections increased significantly ```

Calculate Memory Impact

sql
-- Calculate potential memory usage
SELECT 
    current_setting('max_connections')::int AS max_conn,
    current_setting('work_mem') AS work_mem,
    (current_setting('max_connections')::int * 
     replace(current_setting('work_mem'), 'MB', '')::int) AS total_work_mem_mb,
    (current_setting('max_connections')::int * 
     replace(current_setting('work_mem'), 'MB', '')::int) / 1024 AS total_work_mem_gb;

For high connection counts, use PgBouncer instead of increasing max_connections directly. PostgreSQL performance degrades with too many connections.

Connection Timeout Settings

bash
# Set connection timeouts in postgresql.conf
sudo nano /etc/postgresql/16/main/postgresql.conf
ini
# Connection-related timeouts
connection_limit_duration = 0           # Disable connection limit checks
authentication_timeout = 1min           # Max time for authentication
idle_in_transaction_session_timeout = 600000  # Kill idle transactions after 10 min

Kill Idle Transactions Automatically

```sql -- Set global idle transaction timeout (PostgreSQL 9.6+) ALTER SYSTEM SET idle_in_transaction_session_timeout = '600000'; -- 10 minutes SELECT pg_reload_conf();

-- Or per-session SET idle_in_transaction_session_timeout = '300000'; -- 5 minutes ```

Monitoring Connections

```sql -- Create connection monitoring view CREATE OR REPLACE VIEW connection_monitor AS SELECT pid, datname AS database, usename AS username, application_name, client_addr, state, wait_event_type, wait_event, query_start, now() - query_start AS duration, query FROM pg_stat_activity WHERE datname IS NOT NULL ORDER BY query_start;

-- Quick health check SELECT state, count(*) AS count, string_agg(DISTINCT usename, ', ') AS users FROM pg_stat_activity GROUP BY state;

-- Find connections per client IP SELECT client_addr::inet, count(*) AS connections, array_agg(DISTINCT usename) AS users FROM pg_stat_activity GROUP BY client_addr::inet ORDER BY connections DESC; ```

Setting Connection Limits Per User/Database

```sql -- Limit connections per user ALTER USER webapp CONNECTION LIMIT 50; ALTER USER reporting CONNECTION LIMIT 10; ALTER USER admin CONNECTION LIMIT 5;

-- Limit connections per database ALTER DATABASE production CONNECTION LIMIT 100; ALTER DATABASE staging CONNECTION LIMIT 50;

-- Check limits SELECT rolname, rolconnlimit FROM pg_roles WHERE rolconnlimit <> -1;

SELECT datname, datconnlimit FROM pg_database WHERE datconnlimit <> -1; ```

Prevention

  1. 1.Use connection pooling: PgBouncer or built-in pooling in frameworks
  2. 2.Monitor connection counts: Set up alerts at 80% of max_connections
  3. 3.Set idle timeouts: Prevent abandoned connections
  4. 4.Use connection limits per user/database: Prevent one app from consuming all connections
  5. 5.Close connections properly: Always use try/finally or context managers
  6. 6.Size work_mem appropriately: More connections = lower per-connection work_mem
  7. 7.Monitor for leaks: Regular audits of connection duration

Connection limit issues are almost always a sign of either missing connection pooling or application bugs. The fix is rarely to increase max_connections - it's to fix the leak or add proper pooling.

Additional Troubleshooting Steps

Step 5: Advanced Diagnostics ```bash # Deep diagnostic analysis database diagnostic analyze --full

# Check system logs journalctl -u database -n 100

# Network connectivity test nc -zv database.local 443 ```

Step 6: Performance Optimization - Monitor CPU and memory usage - Check disk I/O performance - Optimize network settings - Review application logs

Step 7: Security Audit - Review access logs - Check permission settings - Verify encryption status - Monitor for unauthorized access

Common Pitfalls and Solutions

Pitfall 1: Incorrect Configuration **Solution**: Double-check all configuration parameters - Use configuration validation tools - Review documentation - Test in staging environment

Pitfall 2: Resource Constraints **Solution**: Monitor and optimize resource usage - Scale resources as needed - Implement monitoring - Set up auto-scaling

Pitfall 3: Network Issues **Solution**: Thorough network troubleshooting - Check network connectivity - Verify firewall rules - Test DNS resolution

Real-World Case Studies

Case Study: Large-Scale Deployment **Scenario**: Enterprise DATABASE deployment with PostgreSQL Connection Limit Exceeded - Troubleshooting Guide errors **Resolution**: - Implemented comprehensive monitoring - Optimized configuration settings - Added redundancy and failover **Result**: 99.99% uptime achieved

Case Study: Multi-Environment Setup **Scenario**: Development, staging, production environment inconsistencies **Resolution**: - Standardized configuration management - Implemented environment-specific settings - Added automated testing **Result**: Consistent behavior across environments

Best Practices Summary

Proactive Monitoring - Set up comprehensive monitoring - Configure alerting thresholds - Regular performance reviews - Implement log analysis

Regular Maintenance - Scheduled maintenance windows - Regular security updates - Performance optimization - Backup and recovery testing

Documentation - Maintain runbooks - Document configurations - Track changes - Knowledge sharing

Quick Reference Checklist

  • [ ] Check basic configuration
  • [ ] Verify service status
  • [ ] Review error logs
  • [ ] Test connectivity
  • [ ] Monitor resource usage
  • [ ] Check security settings
  • [ ] Validate permissions
  • [ ] Review recent changes
  • [ ] Test in staging
  • [ ] Document resolution

This comprehensive troubleshooting guide covers all aspects of PostgreSQL Connection Limit Exceeded - Troubleshooting Guide errors. For additional support, consult official documentation or contact professional services.

  • [Database troubleshooting: Fix Backup Exclusive Lock Table Production Writes ](backup-exclusive-lock-table-production-writes)
  • [Fix Connection Pool Leak Application Not Closing Issue in Database](connection-pool-leak-application-not-closing)
  • [Fix Connection Reset Idle Timeout Firewall Issue in Database](connection-reset-idle-timeout-firewall)
  • [Fix Connection Reset Idle Timeout Serverless Database Issue in Database](connection-reset-idle-timeout-serverless-database)
  • [Fix Connection String Encoding Special Characters Issue in Database](connection-string-encoding-special-characters)

<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "PostgreSQL Connection Limit Exceeded - Troubleshooting Guide", "description": "Complete guide to fix PostgreSQL Connection Limit Exceeded - Troubleshooting Guide. Step-by-step solutions, real-world examples, prevention strategies.", "url": "https://www.fixwikihub.com/fix-postgresql-connection-limit", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2025-11-23T18:41:21.332Z", "dateModified": "2025-11-23T18:41:21.332Z" } </script>