PgDoorman Basic Usage Guide

PgDoorman is a PostgreSQL connection pooler based on PgCat. This guide covers configuration, operation, and administration.

Command Line Options

PgDoorman offers several command-line options to customize its behavior when starting the service:

$ pg_doorman --help

PgDoorman: Nextgen PostgreSQL Pooler (based on PgCat)

Usage: pg_doorman [OPTIONS] [CONFIG_FILE] [COMMAND]

Commands:
  generate  Generate configuration for pg_doorman by connecting to PostgreSQL and auto-detecting databases and users
  help      Print this message or the help of the given subcommand(s)

Arguments:
  [CONFIG_FILE]  [env: CONFIG_FILE=] [default: pg_doorman.toml]

Options:
  -l, --log-level <LOG_LEVEL>    [env: LOG_LEVEL=] [default: INFO]
  -F, --log-format <LOG_FORMAT>  [env: LOG_FORMAT=] [default: text] [possible values: text, structured, debug]
  -n, --no-color                 disable colors in the log output [env: NO_COLOR=]
  -d, --daemon                   run as daemon [env: DAEMON=]
  -h, --help                     Print help
  -V, --version                  Print version

Available Options

OptionDescription
-d, --daemonRun in the background. Without this option, the process will run in the foreground.

In daemon mode, setting daemon_pid_file and syslog_prog_name is required. No log messages will be written to stderr after going into the background.
-l, --log-levelSet log level: INFO, DEBUG, or WARN.
-F, --log-formatSet log format. Possible values: text, structured, debug.
-n, --no-colorDisable colors in the log output.
-V, --versionShow version information.
-h, --helpShow help information.

Setup and Configuration

Configuration File Structure

PgDoorman supports both YAML and TOML configuration formats. YAML is recommended for new setups. The configuration is organized into several sections:

general:        # Global settings for the PgDoorman service
pools:
  <name>:       # Settings for a specific database pool
    users:
      - ...     # User settings for this pool

Important

Some parameters must be specified in the configuration file for PgDoorman to start, even if they have default values. For example, you must specify an admin username and password to access the administrative console.

Minimal Configuration Example

Here's a minimal configuration example to get you started:

general:
  host: "0.0.0.0"         # Listen on all interfaces
  port: 6432               # Port for client connections
  admin_username: "admin"
  admin_password: "admin"  # Change this in production!

pools:
  exampledb:
    server_host: "127.0.0.1"  # PostgreSQL server address
    server_port: 5432          # PostgreSQL server port
    pool_mode: "transaction"   # Connection pooling mode
    users:
      - pool_size: 40
        username: "doorman"
        password: "SCRAM-SHA-256$4096:6nD+Ppi9rgaNyP7...MBiTld7xJipwG/X4="

TOML

[general]
host = "0.0.0.0"
port = 6432
admin_username = "admin"
admin_password = "admin"

[pools.exampledb]
server_host = "127.0.0.1"
server_port = 5432
pool_mode = "transaction"

[pools.exampledb.users.0]
pool_size = 40
username = "doorman"
password = "SCRAM-SHA-256$4096:6nD+Ppi9rgaNyP7...MBiTld7xJipwG/X4="

For a complete list of configuration options, run pg_doorman generate --reference --output ref.yaml to get an annotated config with all parameters and defaults.

Automatic Configuration Generation

The generate command creates a configuration file by connecting to your PostgreSQL server and detecting databases and users. By default, the generated config includes inline comments explaining every parameter.

# View all available options
pg_doorman generate --help

# Generate a YAML configuration file (recommended)
pg_doorman generate --output pg_doorman.yaml

# Generate a TOML configuration file (for backward compatibility)
pg_doorman generate --output pg_doorman.toml

# Generate a reference config with all settings (no PG connection needed)
pg_doorman generate --reference --output pg_doorman.yaml

# Generate a reference config with Russian comments for quick start
pg_doorman generate --reference --ru --output pg_doorman.yaml

# Generate a config without comments (plain serialization)
pg_doorman generate --no-comments --output pg_doorman.yaml

The generate command supports several options:

OptionDescription
--hostPostgreSQL host to connect to (uses localhost if not specified)
--port, -pPostgreSQL port to connect to (default: 5432)
--user, -uPostgreSQL user to connect as (requires superuser privileges to read pg_shadow)
--passwordPostgreSQL password to connect with
--database, -dPostgreSQL database to connect to (uses same name as user if not specified)
--sslPostgreSQL connection to server via SSL/TLS
--pool-sizePool size for the generated configuration (default: 40)
--session-pool-mode, -sSession pool mode for the generated configuration
--output, -oOutput file for the generated configuration (uses stdout if not specified)
--server-hostOverride server_host in config (uses the host parameter if not specified)
--no-commentsDisable inline comments in generated config (by default, comments are included)
--referenceGenerate a complete reference config with example values, no PG connection needed
--russian-comments, --ruGenerate comments in Russian for quick start guide
--format, -fOutput format: yaml (default) or toml. If --output is specified, format is auto-detected from file extension. This flag overrides auto-detection

The command connects to PostgreSQL, detects databases and users, and creates a documented configuration file.

PostgreSQL Environment Variables

The generate command also respects standard PostgreSQL environment variables like PGHOST, PGPORT, PGUSER, PGPASSWORD, and PGDATABASE.

Passthrough Authentication (Default)

PgDoorman uses passthrough authentication by default: the client's cryptographic proof (MD5 hash or SCRAM ClientKey) is automatically reused to authenticate to the backend PostgreSQL server. No plaintext passwords in config needed — just set password to the hash from pg_shadow / pg_authid.

Set server_username and server_password only when the backend user differs from the pool username (e.g., username mapping or JWT auth):

users:
  - username: "app_user"              # client-facing name
    password: "md5..."                # hash for client authentication
    server_username: "pg_app_user"    # different backend PostgreSQL user
    server_password: "real_password"  # plaintext password for that user

See server_username and server_password fields in the generated reference config for details.

Superuser Privileges

Reading user information from PostgreSQL requires superuser privileges to access the pg_shadow table.

Client access control (pg_hba)

PgDoorman can enforce client access rules using PostgreSQL-style pg_hba.conf semantics via the general.pg_hba parameter. You can embed rules directly in the config or reference a file path. See the reference section for full examples.

Trust mode: when a matching rule uses trust, PgDoorman will accept connections without prompting the client for a password, mirroring PostgreSQL behavior. TLS-related rule types are honored: hostssl requires TLS, hostnossl forbids TLS.

Running PgDoorman

After creating your configuration file, you can run PgDoorman from the command line:

$ pg_doorman pg_doorman.toml

If you don't specify a configuration file, PgDoorman will look for pg_doorman.toml in the current directory.

Connecting to PostgreSQL via PgDoorman

Once PgDoorman is running, connect to it instead of connecting directly to your PostgreSQL database:

$ psql -h localhost -p 6432 -U doorman exampledb

Your application's connection string should be updated to point to PgDoorman instead of directly to PostgreSQL:

postgresql://doorman:password@localhost:6432/exampledb

PgDoorman will handle the connection pooling transparently, so your application doesn't need to be aware that it's connecting through a pooler.

Administration

Admin Console

PgDoorman exposes an administrative interface through the special database pgdoorman (or pgbouncer for backward compatibility):

$ psql -h localhost -p 6432 -U admin pgdoorman

Once connected, you can view available commands:

pgdoorman=> SHOW HELP;
NOTICE:  Console usage
DETAIL:
	SHOW HELP|CONFIG|DATABASES|POOLS|POOLS_EXTENDED|POOLS_MEMORY|POOL_COORDINATOR|POOL_SCALING
	SHOW CLIENTS|SERVERS|USERS|CONNECTIONS|STATS|PREPARED_STATEMENTS|AUTH_QUERY
	SHOW LISTS|SOCKETS|LOG_LEVEL|VERSION
	SET log_level = '<filter>'
	RELOAD
	SHUTDOWN
	UPGRADE
	PAUSE [db]
	RESUME [db]
	RECONNECT [db]

Protocol Compatibility

The admin console currently supports only the simple query protocol. Some database drivers use the extended query protocol for all commands, making them unsuitable for admin console access. In such cases, use the psql command-line client for administration.

Security

Only the user specified by admin_username in the configuration file is allowed to log in to the admin console. If your general.pg_hba rules allow it, the admin console can also be accessed using the trust method (no password prompt), for example:

# Allow only local admin to access the admin DB without a password
host  pgdoorman  admin  127.0.0.1/32  trust

Use trust with extreme caution. Always restrict it by address and, where possible, require TLS via hostssl. In production, prefer password-based methods unless you fully understand the implications.

Monitoring PgDoorman

The admin console provides several commands to monitor the current state of PgDoorman:

  • SHOW STATS - View performance statistics
  • SHOW CLIENTS - List current client connections
  • SHOW SERVERS - List current server connections
  • SHOW POOLS - View connection pool status
  • SHOW DATABASES - List configured databases
  • SHOW USERS - List configured users

These commands are described in detail in the Admin Console Commands section below.

Reloading Configuration

If you make changes to the pg_doorman.toml file, you can apply them without restarting the service:

pgdoorman=# RELOAD;

When you reload the configuration:

  1. PgDoorman reads the updated configuration file
  2. Changes to database connection parameters are detected
  3. Existing server connections are closed when they're next released (according to the pooling mode)
  4. New server connections immediately use the updated parameters

This allows you to make configuration changes with minimal disruption to your applications.

Admin Console Commands

The admin console provides a set of commands to monitor and manage PgDoorman. These commands follow a SQL-like syntax and can be executed from any PostgreSQL client connected to the admin console.

Show Commands

The SHOW commands display information about PgDoorman's operation. Each command provides different insights into the pooler's performance and current state.

SHOW STATS

The SHOW STATS command displays comprehensive statistics about PgDoorman's operation:

pgdoorman=> SHOW STATS;

Statistics are presented per (database, user) pair:

MetricDescription
databaseDatabase name
userUsername
total_xact_countTotal SQL transactions since startup
total_query_countTotal SQL commands since startup
total_receivedTotal bytes received from clients
total_sentTotal bytes sent to clients
total_xact_timeTotal microseconds in transactions (including idle in transaction)
total_query_timeTotal microseconds executing queries
total_wait_timeTotal microseconds clients spent waiting for a server connection
total_errorsTotal error count since startup
avg_xact_countAverage transactions per second in the last 15-second period
avg_query_countAverage queries per second in the last 15-second period
avg_recvAverage bytes received per second from clients
avg_sentAverage bytes sent per second to clients
avg_errorsAverage errors per second in the last 15-second period
avg_xact_timeAverage transaction duration in microseconds
avg_query_timeAverage query duration in microseconds
avg_wait_timeAverage wait time for a server in microseconds

Performance Monitoring

Pay special attention to the avg_wait_time metric. If this value is consistently high, it may indicate that your pool size is too small for your workload.

SHOW SERVERS

The SHOW SERVERS command displays detailed information about all server connections:

pgdoorman=> SHOW SERVERS;
ColumnDescription
server_idUnique identifier for the server connection
server_process_idPID of the backend PostgreSQL server process (if available)
database_nameName of the database this connection is using
userUsername PgDoorman uses to connect to the PostgreSQL server
application_nameValue of the application_name parameter set on the server connection
stateCurrent state of the connection: active, idle, or used
waitWait state of the connection: idle, read, or write
transaction_countTotal number of transactions processed by this connection
query_countTotal number of queries processed by this connection
bytes_sentTotal bytes sent to the PostgreSQL server
bytes_receivedTotal bytes received from the PostgreSQL server
age_secondsLifetime of the current server connection in seconds
prepare_cache_hitNumber of prepared statement cache hits
prepare_cache_missNumber of prepared statement cache misses
prepare_cache_sizeNumber of unique prepared statements in the cache

Connection States

  • active: The connection is currently executing a query
  • idle: The connection is available for use
  • used: The connection is allocated to a client but not currently executing a query

SHOW CLIENTS

The SHOW CLIENTS command displays information about all client connections to PgDoorman:

pgdoorman=> SHOW CLIENTS;
ColumnDescription
client_idUnique identifier for the client connection
databaseName of the database (pool) the client is connected to
userUsername the client used to connect
application_nameApplication name reported by the client
addrClient's IP address and port (IP:port)
tlsWhether the connection uses TLS encryption (true or false)
stateCurrent state of the client connection: active, idle, or waiting
waitWait state of the client connection: idle, read, or write
transaction_countTotal number of transactions processed for this client
query_countTotal number of queries processed for this client
error_countTotal number of errors for this client
age_secondsLifetime of the client connection in seconds

Monitoring Long-Running Connections

The age_seconds column can help identify long-running connections that might be holding resources unnecessarily. Consider implementing connection timeouts in your application for idle connections.

SHOW POOLS

The SHOW POOLS command displays information about connection pools. A new pool entry is created for each (database, user) pair:

pgdoorman=> SHOW POOLS;
ColumnDescription
databaseName of the database
userUsername associated with this pool
pool_modePooling mode in use: session or transaction
cl_idleNumber of idle client connections (not in a transaction)
cl_activeNumber of active client connections (linked to servers or idle)
cl_waitingNumber of client connections waiting for a server connection
cl_cancel_reqNumber of cancel requests from clients
sv_activeNumber of server connections linked to clients
sv_idleNumber of idle server connections available for immediate use
sv_usedNumber of server connections recently used but not yet idle
sv_loginNumber of server connections currently in the login process
pool_sizeConfigured maximum pool size for this (database, user) pair
maxwaitMaximum wait time in seconds for the oldest client in the queue
maxwait_usMicrosecond part of the maximum waiting time
avg_xact_timeAverage transaction time in microseconds
pausedWhether the pool is paused: 1 (paused) or 0 (active)

Performance Alert

If the maxwait value starts increasing, your server pool may not be handling requests quickly enough. This could be due to an overloaded PostgreSQL server or insufficient pool_size setting.

SHOW USERS

The SHOW USERS command displays information about all configured users:

pgdoorman=> SHOW USERS;
ColumnDescription
nameUsername as configured in PgDoorman
pool_modePooling mode assigned to this user: session or transaction

SHOW DATABASES

The SHOW DATABASES command displays information about all configured database pools:

pgdoorman=> SHOW DATABASES;
ColumnDescription
nameName of the configured pool
hostHostname of the PostgreSQL server
portPort number of the PostgreSQL server
databaseActual database name on the backend (may differ from pool name if server_database is set)
force_userUser forced for this pool (if configured)
pool_sizeMaximum number of server connections for this pool
min_pool_sizeMinimum number of server connections to maintain
reserve_poolMaximum number of additional reserve connections
pool_modeDefault pooling mode for this pool
max_connectionsMaximum allowed server connections (from max_db_connections)
current_connectionsCurrent number of server connections for this pool

Connection Management

Monitor the ratio between current_connections and pool_size to ensure your pool is properly sized. If current_connections frequently reaches pool_size, consider increasing the pool size.

SHOW SOCKETS

The SHOW SOCKETS command displays TCP/TCP6/Unix socket state counts (Linux only):

pgdoorman=> SHOW SOCKETS;

Shows aggregated counts of socket states (ESTABLISHED, SYN_SENT, etc.) parsed from /proc/net/tcp, /proc/net/tcp6, and /proc/net/unix.

SHOW VERSION

The SHOW VERSION command displays the PgDoorman version information:

pgdoorman=> SHOW VERSION;

This is useful for verifying which version you're running, especially after upgrades.

Control Commands

PgDoorman provides control commands that allow you to manage the service operation directly from the admin console.

SHUTDOWN

The SHUTDOWN command gracefully terminates the PgDoorman process:

pgdoorman=> SHUTDOWN;

When executed:

  1. PgDoorman stops accepting new client connections
  2. Existing transactions are allowed to complete (within the configured timeout)
  3. All connections are closed
  4. The process exits

Service Interruption

Using the SHUTDOWN command will terminate the PgDoorman service, disconnecting all clients. Use this command with caution in production environments.

SET log_level

Change the log level at runtime without restarting the pooler:

-- Global level
pgdoorman=> SET log_level = 'debug';

-- Per-module (RUST_LOG syntax)
pgdoorman=> SET log_level = 'warn,pg_doorman::pool::pool_coordinator=debug';

-- View current level
pgdoorman=> SHOW LOG_LEVEL;

-- Reset to startup default
pgdoorman=> SET log_level = 'default';

Changes are ephemeral — lost on restart. Valid levels: error, warn, info, debug, trace, off.

RELOAD

The RELOAD command refreshes PgDoorman's configuration without restarting the service:

pgdoorman=> RELOAD;

This command:

  1. Rereads the configuration file
  2. Updates all changeable settings
  3. Applies changes to connection parameters for new connections
  4. Maintains existing connections until they're released back to the pool

Zero-Downtime Configuration Changes

The RELOAD command allows you to modify most configuration parameters without disrupting existing connections. This is ideal for production environments where downtime must be minimized.

PAUSE

The PAUSE [db] command blocks new backend connection acquisition for the specified database (or all databases if no argument is given). Active transactions continue to work — only new connection requests are blocked.

-- Pause all pools
pgdoorman=> PAUSE;

-- Pause only pools for a specific database
pgdoorman=> PAUSE mydb;

Clients that request a new backend connection while the pool is paused will wait until RESUME is issued or until query_wait_timeout expires (whichever comes first). If the timeout expires, the client receives a timeout error.

Use SHOW POOLS to verify pause state — the paused column will show 1 for paused pools.

When to use PAUSE

PAUSE is useful during maintenance operations when you want to prevent new queries from reaching the backend:

  • Database failover: PAUSE → switch backend → RECONNECT → RESUME
  • Full connection rotation: PAUSE → RECONNECT → RESUME ensures all connections are recreated
  • Backend maintenance: PAUSE while performing schema changes, then RESUME

RESUME

The RESUME [db] command lifts a PAUSE and immediately unblocks all waiting clients:

-- Resume all pools
pgdoorman=> RESUME;

-- Resume only pools for a specific database
pgdoorman=> RESUME mydb;

Clients that were waiting due to PAUSE will immediately proceed to acquire a backend connection.

RECONNECT

The RECONNECT [db] command forces all backend connections to be recreated:

-- Reconnect all pools
pgdoorman=> RECONNECT;

-- Reconnect only pools for a specific database
pgdoorman=> RECONNECT mydb;

When executed:

  1. The pool's internal epoch counter is incremented
  2. All idle connections are immediately closed
  3. Active connections (currently serving a transaction) continue working but are discarded when returned to the pool — they will not be reused

This means RECONNECT does not interrupt active transactions. New connections are created on demand with the current epoch, so they will be accepted by recycle().

Connection Rotation Patterns

Gradual rotation (minimal disruption): RECONNECT alone — idle connections are dropped immediately, active connections are dropped when they finish their current transaction. New connections are created as needed.

Full rotation (guaranteed all-new connections): PAUSE → RECONNECT → RESUME — pausing first ensures no new transactions start, then RECONNECT marks everything for disposal. After RESUME, all subsequent queries get fresh connections.

RECONNECT and min_pool_size

After RECONNECT, pools with min_pool_size configured will be automatically replenished to their minimum size on the next retain cycle. The new connections will have the current epoch.

Edge Cases and Behavior

The following table describes behavior in edge cases for PAUSE, RESUME, and RECONNECT:

ScenarioBehavior
PAUSE an already paused poolNo-op (idempotent). No error is returned.
RESUME a non-paused poolNo-op (idempotent). No error is returned.
RECONNECT a paused poolWorks: idle connections are drained and epoch is bumped. When RESUME is issued, new connections will be created with the new epoch.
PAUSE/RESUME/RECONNECT with nonexistent databaseReturns an error: No pool for database "xxx". Without a database argument, all pools are affected (no error even if there are no pools).
query_wait_timeout during PAUSEClients waiting for a connection receive a timeout error, as expected. The pool remains paused.
RELOAD during PAUSERELOAD recreates pools from configuration, so pause state is lost. This is expected — new configuration means new pools.
GC of paused dynamic poolsPaused dynamic pools are protected from garbage collection, even if they have 0 connections.
Replenish during PAUSEPools with min_pool_size are not replenished while paused — no new connections are created. Replenishment resumes after RESUME.
Connection lifetime during PAUSEThe retain task continues to close expired connections (idle timeout, server lifetime). Connections still age normally.
Multiple RECONNECT callsEach call increments the epoch further. Only connections created after the latest RECONNECT are valid.

Signal Handling

PgDoorman responds to standard Unix signals for control and management. Send signals using kill (e.g., kill -HUP <pid>).

SignalEffect
SIGHUPConfiguration reload — equivalent to the RELOAD admin command.
SIGUSR2Binary upgrade + graceful shutdown. Validates the new binary with -t, spawns a new process, then shuts down. Recommended for upgrades. See Binary Upgrade Process.
SIGINTForeground + TTY (Ctrl+C): graceful shutdown only (no binary upgrade). Daemon / no TTY: binary upgrade + graceful shutdown (legacy behavior).
SIGTERMImmediate shutdown. Active connections are terminated.

Process Management

In systemd-based environments, the default unit file uses ExecReload=/bin/kill -SIGUSR2 $MAINPID to trigger binary upgrade on systemctl reload.