Why Connections Are Expensive in PostgreSQL
Understand the per-backend memory and scheduling costs that make pooling essential at scale.
One Connection, One Process
PostgreSQL uses a process-per-connection model. Every client connection is handled by its own dedicated OS process called a backend, forked from the postmaster when the connection is accepted.
This design is robust and simple, but it has a real cost: a process is far heavier than a thread. Unlike databases that multiplex many sessions onto a thread pool, PostgreSQL pays a per-process price for every single open connection, whether it is actively running a query or sitting idle.
You can see one backend per connection directly in the catalog:
SELECT pid, usename, application_name, state
FROM pg_stat_activity
WHERE backend_type = 'client backend';The Cost of Forking
Opening a connection is not free. Each new backend requires PostgreSQL to:
- Fork a new OS process from the postmaster
- Attach to shared memory and set up its local memory context
- Authenticate the client and validate the database/role
- Load catalog and relation cache entries on first access
This setup can take several milliseconds before a single query runs. An application that opens and closes a connection for every HTTP request pays this tax thousands of times per minute, turning connection churn into a measurable latency and CPU drain.
All lessons in this course
- Why Connections Are Expensive in PostgreSQL
- Transaction vs Session Pooling Modes
- Sizing Pools Against Core Count
- Diagnosing Pool Saturation and Queueing