Why This Matters
Postgres connections are expensive - each one consumes 1-3MB of RAM and has significant startup overhead. Without pooling, applications exhaust connections under load, causing crashes and timeouts.
This is especially critical for:
- Serverless functions: Each invocation creates a new connection
- High-traffic APIs: Hundreds of concurrent requests
- Microservices: Multiple services competing for connections
Warning: Supabase free tier allows only 60 direct connections. Without pooling, you'll hit this limit with just 60 concurrent users.
The Problem
Incorrect - New connection per request
-- Each request creates a new connection
-- Application code: db.connect() per request
-- Result: 500 concurrent users = 500 connections = crashed database
-- Check current connections
SELECT count(*) FROM pg_stat_activity; -- 487 connections!
The Solution
Correct - Connection pooling
-- Use a pooler like PgBouncer between app and database
-- Application connects to pooler, pooler reuses a small pool to Postgres
-- Configure pool_size based on: (CPU cores * 2) + spindle_count
-- Example for 4 cores: pool_size = 10
-- Result: 500 concurrent users share 10 actual connections
SELECT count(*) FROM pg_stat_activity; -- 10 connections
Pool Modes
- Transaction mode: Connection returned after each transaction (best for most apps)
- Session mode: Connection held for entire session (needed for prepared statements, temp tables)
Supabase: Use the pooler connection string (port 6543) for transaction mode, or direct connection (port 5432) for session mode with features like prepared statements.
Check Your Connection Usage
Connect your Supabase project to monitor connection usage and identify bottlenecks.
Start Supabase AuditCommon Mistakes
- Using direct connection in serverless: Always use the pooler URL for Vercel, Netlify, AWS Lambda, etc.
- Pool too large: More connections doesn't mean faster - it increases contention. Start with (cores * 2) + 2.
- Not closing connections: Always return connections to the pool. Use connection lifecycle hooks.