Skip Navigation
Show nav
Heroku Dev Center Dev Center
  • Get Started
  • Documentation
  • Changelog
  • Search
Heroku Dev Center Dev Center
  • Get Started
    • Node.js
    • Ruby on Rails
    • Ruby
    • Python
    • Java
    • PHP
    • Go
    • Scala
    • Clojure
    • .NET
  • Documentation
  • Changelog
  • More
    Additional Resources
    • Home
    • Elements
    • Products
    • Pricing
    • Careers
    • Help
    • Status
    • Events
    • Podcasts
    • Compliance Center
    Heroku Blog

    Heroku Blog

    Find out what's new with Heroku on our blog.

    Visit Blog
  • Log in or Sign up
View categories

Categories

  • Heroku Architecture
    • Compute (Dynos)
      • Dyno Management
      • Dyno Concepts
      • Dyno Behavior
      • Dyno Reference
      • Dyno Troubleshooting
    • Stacks (operating system images)
    • Networking & DNS
    • Platform Policies
    • Platform Principles
    • Buildpacks
  • Developer Tools
    • AI Tools
    • Command Line
    • Heroku VS Code Extension
  • Deployment
    • Deploying with Git
    • Deploying with Docker
    • Deployment Integrations
  • Continuous Delivery & Integration (Heroku Flow)
    • Continuous Integration
  • Language Support
    • Node.js
      • Working with Node.js
      • Troubleshooting Node.js Apps
      • Node.js Behavior in Heroku
    • Ruby
      • Rails Support
        • Working with Rails
      • Working with Bundler
      • Working with Ruby
      • Ruby Behavior in Heroku
      • Troubleshooting Ruby Apps
    • Python
      • Working with Python
      • Background Jobs in Python
      • Python Behavior in Heroku
      • Working with Django
    • Java
      • Java Behavior in Heroku
      • Working with Java
      • Working with Maven
      • Working with Spring Boot
      • Troubleshooting Java Apps
    • PHP
      • Working with PHP
      • PHP Behavior in Heroku
    • Go
      • Go Dependency Management
    • Scala
    • Clojure
    • .NET
      • Working with .NET
  • Databases & Data Management
    • Heroku Postgres
      • Postgres Basics
      • Postgres Getting Started
      • Postgres Performance
      • Postgres Data Transfer & Preservation
      • Postgres Availability
      • Postgres Special Topics
      • Migrating to Heroku Postgres
    • Heroku Key-Value Store
    • Apache Kafka on Heroku
    • Other Data Stores
  • AI
    • Inference Essentials
    • Inference API
    • Inference Quick Start Guides
    • AI Models
    • Tool Use
    • AI Integrations
    • Vector Database
  • Monitoring & Metrics
    • Logging
  • App Performance
  • Add-ons
    • All Add-ons
  • Collaboration
  • Security
    • App Security
    • Identities & Authentication
      • Single Sign-on (SSO)
    • Private Spaces
      • Infrastructure Networking
    • Compliance
  • Heroku Enterprise
    • Enterprise Accounts
    • Enterprise Teams
  • Patterns & Best Practices
  • Extending Heroku
    • Platform API
    • App Webhooks
    • Heroku Labs
    • Building Add-ons
      • Add-on Development Tasks
      • Add-on APIs
      • Add-on Guidelines & Requirements
    • Building CLI Plugins
    • Developing Buildpacks
    • Dev Center
  • Accounts & Billing
  • Troubleshooting & Support
  • Integrating with Salesforce
    • Heroku AppLink
      • Heroku AppLink Reference
      • Working with Heroku AppLink
      • Getting Started with Heroku AppLink
    • Heroku Connect (Salesforce sync)
      • Heroku Connect Administration
      • Heroku Connect Reference
      • Heroku Connect Troubleshooting
    • Other Salesforce Integrations
  • Databases & Data Management
  • Heroku Postgres
  • Postgres Performance
  • Client-Side Postgres Connection Pooling

Client-Side Postgres Connection Pooling

English — 日本語に切り替える

Table of Contents [expand]

  • Use Case
  • Configuration
  • Language/Library Specific Configuration
  • Tweak Settings
  • Version Support
  • Caveats and Limits

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.

Feedback

Log in to submit feedback.

Information & Support

  • Getting Started
  • Documentation
  • Changelog
  • Compliance Center
  • Training & Education
  • Blog
  • Support Channels
  • Status

Language Reference

  • Node.js
  • Ruby
  • Java
  • PHP
  • Python
  • Go
  • Scala
  • Clojure
  • .NET

Other Resources

  • Careers
  • Elements
  • Products
  • Pricing
  • RSS
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku Blog
    • Heroku News Blog
    • Heroku Engineering Blog
  • Twitter
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku
    • Heroku Status
  • Github
  • LinkedIn
  • © 2026 Salesforce, Inc. All rights reserved. Various trademarks held by their respective owners. Salesforce Tower, 415 Mission Street, 3rd Floor, San Francisco, CA 94105, United States
  • heroku.com
  • Legal
  • Terms of Service
  • Privacy Information
  • Responsible Disclosure
  • Trust
  • Contact
  • Cookie Preferences
  • Your Privacy Choices