DatabaseMeter

PostgreSQL Learn

PostgreSQL connection pooling: direct, session, and transaction modes

A pooler lets many clients share a smaller set of PostgreSQL server connections. The useful mode depends on whether your application needs session state, transaction affinity, short-lived concurrency, or a direct administrative connection.

What a connection pool changes

A direct client connection normally owns one PostgreSQL backend for the life of the session. A pooler sits between clients and PostgreSQL, reuses a bounded set of server connections, and may queue work when every pooled server connection is busy.

max_connections still limits PostgreSQL server connections and influences server resource allocation. A pooler can increase supported client concurrency, but it does not create unlimited database execution capacity.

Compare connection modes

Comparison of PostgreSQL direct and pooled connection modes
ModeConnection affinityTypical fit and limitation
DirectOne client session maps to one PostgreSQL backend.Administrative tools, migrations, replication, and persistent services; every open client consumes a server connection.
Session poolingA server connection stays assigned for the client session.Preserves most session behavior but reduces server-connection sharing while clients remain connected.
Transaction poolingA server connection is assigned for a transaction, then returned to the pool.Fits transient or highly concurrent clients; session-scoped features require compatibility review.

Inspect PostgreSQL connection limits safely

This query works across supported PostgreSQL versions even when a newer setting is absent: the pg_settings filter simply returns the settings available on that server.

SELECT
  name,
  setting::bigint AS connection_slots,
  source
FROM pg_settings
WHERE name IN (
  'max_connections',
  'reserved_connections',
  'superuser_reserved_connections'
)
ORDER BY name;

Reserved slots are not normal application capacity. Increasing max_connections is not a universal fix because PostgreSQL sizes resources from it and active work still competes for CPU, memory, locks, and I/O.

Inspect database-facing sessions

This bounded snapshot groups client backends without returning SQL text, client addresses, or process identifiers.

SELECT
  datname,
  usename AS role_name,
  COALESCE(NULLIF(application_name, ''), 'unlabeled') AS application_name,
  COALESCE(state, 'unknown') AS state,
  count(*) AS server_connections
FROM pg_stat_activity
WHERE backend_type = 'client backend'
GROUP BY datname, usename, application_name, state
ORDER BY server_connections DESC
LIMIT 50;

Choose and size a pool from workload evidence

  • Count application instances and each instance's maximum pool size; their product can matter more than one local setting.
  • Separate connected clients, busy server connections, and queued work. They are different capacity signals.
  • Test transaction-mode compatibility for prepared statements, temporary objects, advisory locks, session settings, and migration tools.
  • Keep a supported direct path for operations that require session affinity or bypassing the pooler.
  • Measure connection acquisition latency and query throughput under realistic concurrency before raising limits.

Common misleading interpretations

  • A low PostgreSQL backend count does not prove the pool has no queued clients.
  • Many idle direct sessions do not automatically mean the pool size should be zero; persistent services retain a working baseline.
  • Raising max_connections does not increase CPU or I/O capacity.
  • Changing a provider port does not convert a direct hostname into a supported pooled endpoint.
  • A transaction pool is not automatically compatible with every driver, ORM, migration, or session feature.

When DatabaseMeter can help

The PostgreSQL health check compares a database-facing connection snapshot with max_connections and labels elevated utilization as a single observation. Connected telemetry preserves bounded activity groups by application, role, and state for supported databases.

DatabaseMeter does not currently collect pooler client counts, queue depth, acquisition latency, or pool configuration. Confirm those signals in Neon, Supabase, or your application-side pooler before changing capacity.

Definitions and sources

Provider and PostgreSQL statements last reviewed August 29, 2026. Pricing consoles and invoices remain authoritative.