Skip to main content...
PostgreSQL + Database Internals
20 min

Day 87: Connection pooling (PgBouncer); partitioning

Connection pooling: Postgres connections aren't free

Each Postgres connection is a full OS process (Phase 0, Day 2) with real memory overhead — a few hundred connections is already a meaningful load, and thousands can exhaust the database entirely. PgBouncer sits between your app and Postgres, pooling a small number of real backend connections and multiplexing many more client connections onto them.

A minimal pgbouncer.ini
[databases]
mydb = host=127.0.0.1 port=5432 dbname=mydb

[pgbouncer]
pool_mode = transaction
max_client_conn = 1000
default_pool_size = 20

Why this matters especially in Kubernetes

Every horizontally scaled Pod (Phase 8) opening its own Postgres connection pool multiplies fast — 50 pods × 10 connections each = 500 connections, which can overwhelm a database sized for far fewer. PgBouncer (or a managed equivalent like RDS Proxy) is what makes horizontal app scaling and a fixed-size database compatible.

Partitioning

Partitioning splits one logical table into multiple physical pieces (e.g. by date range or by a key), so queries and maintenance operations (like vacuum, Day 90) that only need one partition don't have to touch the whole table — critical once a table grows into the hundreds of millions of rows.

Key terms

PgBouncer
A connection pooler multiplexing many client connections onto fewer real Postgres backend connections.
Partitioning
Splitting one logical table into multiple physical pieces for scalability.

Scaling an API from 10 to 100 pods in Kubernetes suddenly causes "too many connections" errors on Postgres. What's the standard fix?

We use cookies

We use cookies to enhance your browsing experience, serve personalized content, and analyze our traffic. By clicking "Accept All", you consent to our use of cookies. Learn more

    Day 87: Connection pooling (PgBouncer); partitioning | RBTechIconX