Process Architecture
The postmaster and a backend process per connection, background workers (checkpointer, bgwriter, WAL writer, autovacuum, WAL senders), shared memory and the double-buffering debate, startup and crash restart, and connection pooling as a requirement with PgBouncer's modes.
Postmaster, backends and background workers
-- what is running right now SELECT pid, backend_type, state, wait_event_type, wait_event, now() - xact_start AS xact_age, left(query, 60) FROM pg_stat_activity ORDER BY xact_age DESC NULLS LAST; -- memory per backend that multiplies: work_mem is per sort/hash node, per query, per backend SHOW work_mem; -- 4MB default; 200 connections × 3 sorts × 64MB = 38 GB worst case
shared_buffers and the double-buffering debate: Postgres reads through the OS page cache, so a hot page can live both in shared_buffers and in the kernel cache. The usual guidance is shared_buffers at about 25% of RAM and effective_cache_size (a planner hint, not an allocation) at 50-75%, leaving the OS cache to do the rest. Postgres 18's asynchronous IO and ongoing direct IO work are steps away from relying on the kernel cache.
Connection pooling as a requirement
| PgBouncer mode | server connection held for | breaks | use |
|---|---|---|---|
| session | the whole client session | nothing | only limits connection churn; no multiplexing |
| transaction | one transaction | SET (use SET LOCAL), session advisory locks, LISTEN, WITH HOLD cursors, temp tables across transactions | the standard for web apps |
| statement | one statement | multi-statement transactions | rare; autocommit-only workloads |
; pgbouncer.ini [databases] app = host=10.0.0.5 dbname=app [pgbouncer] pool_mode = transaction max_client_conn = 5000 ; clients PgBouncer accepts default_pool_size = 40 ; server connections per database/user pair max_prepared_statements = 200 ; protocol-level prepared statements in transaction mode (1.21+)
Startup sequence, briefly: the postmaster reads configuration, allocates shared memory, starts the startup process to replay WAL if the last shutdown was not clean (reading pg_control), then starts background workers and accepts connections. Alternatives to PgBouncer: PgCat and Supavisor (multi-threaded poolers with sharding features), Odyssey, and cloud proxies such as RDS Proxy.