Table of Contents [expand]
Last updated May 06, 2026
Heroku provides a buildpack to run PgBouncer alongside application code. You’re meant to use it with other buildpacks.
The Heroku PgBouncer buildpack allows for transaction pooling of PostgreSQL database connections among multiple workers in a dyno. For example, 10 Ruby unicorn workers can share a single database connection, reducing the total number of concurrent connections from your app to the database. Client-side connection pooling helps control the number of database connections that each of your database dynos uses, saving database resources.
The buildpack’s source code is available on GitHub.
This article is only applicable for apps using classic buildpacks. There currently is no Cloud Native Buildpack version for PgBouncer, and classic buildpacks aren’t compatible with Fir-generation apps.
Use Case
You have many workers per dyno holding database connections that remain idle for most of their lifetime, and you’re concerned about reaching the connection limits of your Postgres database or about database resource exhaustion.
See this answer on Stack Overflow for more advantages of connection pooling.
See Caveats and Limits for more information.
Configuration
Add the PgBouncer buildpack to your app:
$ heroku buildpacks:add --index 1 heroku/pgbouncer
Edit the Procfile and prepend bin/start-pgbouncer to the process command where you want to use PgBouncer. The following example configures web processes to connect to Postgres via client-side PgBouncer and worker processes to connect directly to Postgres.
web: bin/start-pgbouncer your-web-app
worker: your-worker-app
After deploying your changes, your app is now using PgBouncer to connect to Postgres.
All connections to Heroku Postgres require SSL.
Connecting to Multiple Databases
You can configure your app to use client-side connection pooling through PgBouncer for multiple databases by adjusting the PGBOUNCER_URLS config var. Set PGBOUNCER_URLS to a space-separated list with the config var names of the databases you want your app to connect to through PgBouncer:
$ heroku config:set PGBOUNCER_URLS="DATABASE_URL HEROKU_POSTGRESQL_ROSE_URL"
Language/Library Specific Configuration
Set ignore_startup_parameters for Certain Postgres Drivers
Some drivers, like Go’s pq driver before its version v1.11.0, include the extra_float_digits parameter in the connection string they use to connect to Postgres. PgBouncer doesn’t allow this parameter by default and you must configure PgBouncer to ignore it. Set the PGBOUNCER_IGNORE_STARTUP_PARAMETERS config var on your app to ignore extra_float_digits:
$ heroku config:set PGBOUNCER_IGNORE_STARTUP_PARAMETERS=extra_float_digits
The PgBouncer buildpack recognizes the PGBOUNCER_IGNORE_STARTUP_PARAMETERS config var and adds ignore_startup_parameters = extra_float_digits to PgBouncer’s config file when a dyno starts.
SSL Mode for Local PgBouncer Connection
The default SSL configuration for some database drivers, like Go’s pq driver or any other drivers that force sslmode=required, can conflict with the PgBouncer buildpack and result in the error:
pq: SSL is not enabled on the server
This error occurs because the PgBouncer service running locally on your Heroku dynos hasn’t enabled SSL/TLS for local connections. Database drivers that use sslmode=prefer by default automatically fallback to non-SSL connections, preventing the conflict.
If your app only connects to Postgres via the client-side PgBouncer, adjust PGSSLMODE to disable SSL connections for Postgres:
$ heroku config:set PGSSLMODE=disable
Alternatively, adjust the setting specifically for your web dynos running PgBouncer via inline environment variables in the Procfile file:
web: PGSSLMODE=disable bin/start-pgbouncer
The database connections from your app dynos are still secure. PgBouncer uses SSL to connect to the Postgres server. Setting PGSSLMODE only disables SSL on the localhost connections from the app to PgBouncer.
Disable Prepared Statements in Rails
For Rails apps, you can disable prepared statements by setting prepared_statements: false in your app’s config/database.yml file.
Tweak Settings
Some PgBouncer settings are configurable through app config vars at run time. Refer to the appropriate documentation for PgBouncer to see which settings are right for your app.
You can adjust these config vars to tune PgBouncer’s settings either by setting the config variables for your app, or as inline environment variables directly in the Procfile process command. See PgBouncer Configuration for configuring the default settings.
Via config variables:
$ heroku config:set PGBOUNCER_POOL_MODE=session
Via inline environment variables in the Procfile file:
web: PGBOUNCER_POOL_MODE=session bin/start-pgbouncer
Configurable Settings
PGBOUNCER_AUTH_TYPE
The default is scram-sha-256. You can change to md5 or plain depending on server support.
PGBOUNCER_SERVER_TLS_SSLMODE
The default is require.
PGBOUNCER_POOL_MODE
The default is transaction.
PGBOUNCER_MAX_CLIENT_CONN
The default is 100.
PGBOUNCER_DEFAULT_POOL_SIZE
The default is 1.
PGBOUNCER_MIN_POOL_SIZE
The default is 0.
PGBOUNCER_RESERVE_POOL_SIZE
The default is 1.
PGBOUNCER_RESERVE_POOL_TIMEOUT
The default is 5.0 seconds.
PGBOUNCER_SERVER_LIFETIME
The default is 3600.0 seconds.
PGBOUNCER_SERVER_IDLE_TIMEOUT
The default is 600.0 seconds.
PGBOUNCER_URLS
The default is DATABASE_URL. Contains all overridden config variables to connect to PgBouncer. For example, set this variable to AMAZON_RDS_URL to send RDS connections through PgBouncer.
PGBOUNCER_CONNECTION_RETRY
The default is no.
PGBOUNCER_LOG_CONNECTIONS
The default is 1. If your app doesn’t use persistent database connections, this setting can be noisy and you must set it to 0.
PGBOUNCER_LOG_DISCONNECTIONS
The default is 1. If your app doesn’t use persistent database connections, this setting can be noisy and you must set it to 0.
PGBOUNCER_LOG_POOLER_ERRORS
The default is 1.
PGBOUNCER_STATS_PERIOD
The default is 60.
PGBOUNCER_SERVER_RESET_QUERY
The default is empty when pool mode is transaction, and DISCARD ALL; when pool mode is session.
PGBOUNCER_IGNORE_STARTUP_PARAMETERS
The default is empty and the most commonly ignored parameter is extra_float_digits. Adds parameters to ignore when PgBouncer is starting. Some Postgres libraries, like Go’s pq, append this parameter, making it impossible to use this buildpack.
You can separate multiple parameters via commas.
For example:
PGBOUNCER_IGNORE_STARTUP_PARAMETERS="extra_float_digits, some_other_param"
PGBOUNCER_MAX_PREPARED_STATEMENTS
The default is 0, which disables PgBouncer’s tracking protocol-level named prepared statements.
You can enable this feature and configure the maximum number of prepared statements tracked by PgBouncer by setting a non-zero value.
Version Support
The Heroku PgBouncer buildpack uses PgBouncer version 1.24 by default.
See Viewing Connection Pool Info for details on how to connect to your pgbouncer’s internal database and View Version to check your pgbouncer’s version.
Caveats and Limits
Refer to PgBouncer’s feature matrix for all connection pooling caveats.
Incompatibility with Advisory Locks
Connection pooling and connections to a PostgreSQL through pgbouncer aren’t compatible with advisory locks.
Incompatibility with LISTEN and NOTIFY
Connection pooling and connections to a PostgreSQL through PgBouncer aren’t compatible with PostgreSQL’s LISTEN and NOTIFY.
Unexpected Session Configuration in ORMs
Some object-relational mappings (ORMs), like ActiveRecord before v4.2.5, can set session variables during queries to ensure consistency. While session variables can be useful when connecting to Postgres directly, it can cause unexpected behavior and difficult-to-diagnose errors with transactional connection pooling. Make sure you thoroughly test apps before moving to connection pooling, including auditing ORM code for any “overly helpful” session configuration.
See an example of these problems in the GoCardless Engineering Blog.