data-infra
Glossary ↗Connection Pooling
Connection pooling is a technique where a fixed set of pre-established database connections is kept open and shared across incoming requests, rather than every request opening a brand-new connection to the database and closing it when done. Opening a database connection is expensive relative to the actual query it will run — it involves a TCP handshake, authentication, and (for Postgres specifically) spinning up a dedicated backend process per connection — so doing this on every single request is a significant, avoidable tax on latency and server resources. Why it matters for AI/SaaS builders: this becomes an acute, product-breaking problem specifically in serverless and edge deployments (Vercel, AWS Lambda, Cloudflare Workers), which is now the default deployment model for a huge share of new AI products. Serverless functions spin up and tear down constantly, and without pooling, each invocation opening its own database connection can exhaust Postgres's fairly low default connection limit (commonly 100) within seconds under real traffic, causing "too many connections" errors that take down the whole app — a failure mode that doesn't show up in local development and only appears once real concurrent users hit production. How it works: a connection pooler sits between the application and the database, maintaining a set of already-open connections and handing them out to requests as needed, returning them to the pool when a request finishes rather than closing them. Application-level pools (built into most database drivers and ORMs) work within a single long-running server process; but serverless functions are stateless and short-lived, so they need an external pooler like PgBouncer or a managed equivalent (Supabase's built-in pooler, Neon's connection pooling, PlanetScale's proxy) that persists independently of any single function invocation and multiplexes many serverless connections down to a small number of real database connections. Worked example: an AI SaaS deployed on Vercel serverless functions starts seeing intermittent 500 errors under load — the Postgres logs show `FATAL: too many connections`, because each of hundreds of concurrent Lambda invocations opened its own direct connection to the database. The fix: route the application's database URL through PgBouncer in transaction-pooling mode, which multiplexes those hundreds of ephemeral serverless connections down to a stable pool of 20 real backend connections — eliminating the connection-exhaustion errors without changing a single line of query code. The fix also cuts average query latency slightly, since reusing an already-open pooled connection avoids the handshake overhead that was previously being paid on every single invocation — a rare case where fixing a reliability bug and improving performance come from the exact same change.
Related terms