PgDoorman vs PgBouncer vs Odyssey vs PgCat

A practical feature matrix for choosing a PostgreSQL connection pooler. PgDoorman targets workloads where prepared statements in transaction mode, multithreaded performance, and operational ergonomics matter.

For benchmark numbers, see Benchmarks.

Authentication

FeaturePgDoormanPgBouncerOdyssey
MD5 passwordYesYesYes
SCRAM-SHA-256 (client)YesYesYes
SCRAM-SHA-256 passthrough (no plaintext password in config)YesNoYes
MD5 passthroughYesYesYes
auth_query (dynamic users)YesYesYes
auth_query passthrough mode (per-user backend identity)YesNoYes
pg_hba.conf formatYes (file or inline)NoSince 1.4
PAMYes (Linux)Yes (HBA)Yes
JWT (RSA-SHA256)YesNoNo
Talos (custom JWT with role extraction)YesNoNo
LDAPNoSince 1.25Yes
SCRAM channel binding (scram-sha-256-plus)NoYesYes
User name maps (cert/peer → DB user)NoSince 1.23Yes
Tunable scram_iterationsNoSince 1.25No

See Authentication.

TLS

FeaturePgDoormanPgBouncerOdyssey
Client-side TLS (4 modes: disable, allow, require, verify-full)YesYesYes
Server-side TLS to PostgreSQL (6 modes incl. verify-ca, verify-full)YesYesNo
mTLS to PostgreSQL (client cert)YesYesNo
Hot reload of TLS certificates on SIGHUPYes (server-side)NoNo
Minimum TLS 1.2 + Mozilla cipher listYesYesNo (allows TLS 1.0)
Direct TLS handshake (PG17, no SSLRequest)NoSince 1.25No
TLS 1.3 cipher controlNoSince 1.25No

See TLS.

Routing and high availability

FeaturePgDoormanPgBouncerOdyssey
Patroni-assisted fallback (built-in /cluster lookup)YesNoNo
Bundled TCP proxy with role-based routing (patroni_proxy)YesNoNo
Replica lag guardYes (max_lag_in_bytes in patroni_proxy)NoYes (watchdog query)
Round-robin / least-connections multi-hostYes (patroni_proxy)Since 1.24Yes
target_session_attrs (read-write / read-only)Yes (via patroni_proxy roles)NoYes
Sequential routing (rules in order)NoNoYes
Connection type routing (TCP vs UNIX)NoNoYes
Availability zone-aware host selectionNoNoYes

See Patroni-assisted fallback, patroni_proxy.

Pooling

FeaturePgDoormanPgBouncerOdyssey
Pool modes (transaction, session)YesYes (+ statement)Yes
Pool Coordinator (cross-user max_db_connections with priority eviction)YesNo (no eviction)No
Reserve pool with min_guaranteed_pool_sizeYesReserve onlyNo
Pre-replacement on server_lifetime expiryYesNoNo
Anticipation/burst scaling (scaling_warm_pool_ratio, fast retries)YesNoNo
Direct-handoff (waiter receives returning connection in microseconds)YesNoNo
min_pool_size (warm connections)YesNoYes
Prepared statement cache (two-level, query interner, statement remap)YesSince 1.21Since 1.3
Smart DISCARD on checkinRESET ALL + drop cacheNoYes (auto)
LISTEN / NOTIFY pinning in transaction modeNoNoExperimental
Cross-rule connection cap (shared_pool)NoNoSince 1.5.1
PAUSE / RESUME / RECONNECTYesYesYes (1.4.1+)

See Pool Coordinator, Pool pressure.

Limits and timeouts

FeaturePgDoormanPgBouncerOdyssey
server_idle_check_timeout (probe before checkout)YesNoNo
idle_timeout (server connection)YesYesYes
server_lifetimeYesYesYes
query_wait_timeoutYesYesYes
client_idle_timeoutNoSince 1.24No
transaction_timeoutNoSince 1.25No
max_user_client_connectionsNoSince 1.24No
Per-user query_timeoutNoSince 1.24No
Per-user reserve_pool_sizeNoSince 1.24No
query_wait_notify (NOTICE while waiting for backend)NoSince 1.25Yes (pool_notice_after_waiting_ms)

See General settings reference, Pool settings reference.

Observability

FeaturePgDoormanPgBouncerOdyssey
Built-in Prometheus endpointYesExternal (pgbouncer_exporter)Yes
Latency percentiles per pool (p50, p90, p95, p99)Yes (HDR Histogram)NoYes (TDigest)
Prepared statement counters in statsYesSince 1.24No
JSON structured loggingYes (--log-format Structured)NoYes
Runtime log level control (SET log_level)YesNoNo
Admin SHOW POOL_COORDINATOR / SHOW POOL_SCALING / SHOW SOCKETSYesNoNo
Admin SHOW PREPARED_STATEMENTSYesNoNo
Admin SHOW HOSTS (host CPU/memory)NoNoYes
Admin SHOW RULES (dump routing)NoNoYes
TLS connection metrics (handshake duration, errors, active count)Yes (server-side)NoNo
Patroni API metricsYesNoNo
Fallback metrics (active flag, current host, hits)YesNoNo

See Prometheus metrics reference, Admin commands.

Operations

FeaturePgDoormanPgBouncerOdyssey
Graceful binary upgrade (zero-downtime, in-flight clients preserved)YesLimited (SO_REUSEPORT)No
YAML configYesNo (INI)No (own format)
TOML configYes (legacy)NoNo
Human-readable durations & sizes (30s, 1h, 256MB)YesNoNo
Config test mode (pg_doorman -t)YesNoNo
Auto-config from PostgreSQL (pg_doorman generate --host)YesNoNo
SIGHUP reloadYes (incl. server TLS certs)YesYes
systemd sd-notify integrationYes (Type=notify)NoNo
Memory cap (max_memory_usage)YesNoNo

See Binary upgrade, Signals.

Protocol

FeaturePgDoormanPgBouncerOdyssey
Simple queryYesYesYes
Extended queryYesYesPartial
Pipelined batchesYesYesPartial
Async FlushYesYesNo
Cancel requests over TLSYesYesYes
COPY IN / COPY OUTYesYesYes
Replication passthrough (replication=true startup)NoSince 1.23No
Protocol version negotiation (3.2)NoSince 1.23No
server_drop_on_cached_plan_errorNoNoSince 1.5.1

When PgDoorman is not the right fit

  • You need LDAP authentication. Use Odyssey or PgBouncer 1.25+.
  • You need SCRAM channel binding (scram-sha-256-plus) end-to-end. Use PgBouncer or Odyssey.
  • You need replication passthrough for logical replication tools. Use PgBouncer 1.23+.
  • You need availability-zone-aware routing or sequential pg_hba-style routing rules. Use Odyssey.
  • You need transaction_timeout enforced by the pooler. Use PgBouncer 1.25+.

For prepared statements in transaction mode, Patroni HA without external proxies, multithreaded throughput, and zero-downtime restarts, PgDoorman is the closer fit.