---
title: "Deploy PgBouncer"
description: "A simple PostgreSQL pooler to reduce database connection overhead."
category: "Storage"
url: https://railway.com/deploy/pgbouncer
---

# Deploy PgBouncer

A simple PostgreSQL pooler to reduce database connection overhead.

**[Deploy PgBouncer on Railway](https://railway.com/template/pgbouncer)**

- **Creator:** INF Labs
- **Category:** Storage

## Template content

### pgbouncer https://devicons.railway.app/post

- **Image:** ghcr.io/cloudnative-pg/pgbouncer:1.25.2
- **Start command:** `/bin/sh -c 'printf "%s\n" "[databases]" "${PGBOUNCER_DATABASE} = host=${POSTGRES_HOST} port=${POSTGRES_PORT} dbname=${POSTGRES_DATABASE} user=${POSTGRES_USER} password=${POSTGRES_PASSWORD}" "" "[pgbouncer]" "listen_addr = 0.0.0.0" "listen_port = ${PGBOUNCER_PORT}" "auth_type = plain" "auth_file = /tmp/userlist.txt" "pool_mode = ${POOL_MODE}" "default_pool_size = ${DEFAULT_POOL_SIZE}" "max_client_conn = ${MAX_CLIENT_CONN}" > /tmp/pgbouncer.ini && printf "\"%s\" \"%s\"\n" "${PGBOUNCER_USER}" "${PGBOUNCER_PASSWORD}" > /tmp/userlist.txt && exec pgbouncer /tmp/pgbouncer.ini'`

## Documentation

# Deploy and Host PgBouncer on Railway

PgBouncer is a lightweight PostgreSQL connection pooler designed to reduce database connection overhead and improve connection efficiency between applications and PostgreSQL.

This Railway template deploys PgBouncer as a standalone TCP service that connects to an existing PostgreSQL database.

## About Hosting

Hosting PgBouncer on Railway adds a dedicated connection-pooling layer between your application and PostgreSQL.

```text
Application
    │ PostgreSQL Protocol
    ▼
PgBouncer :6432
    │ PostgreSQL Protocol
    ▼
Existing PostgreSQL
```

PgBouncer accepts standard PostgreSQL connections and reuses a smaller number of backend database connections.

It works with standard PostgreSQL clients and frameworks, including:

* `psql`
* Prisma
* Drizzle
* Sequelize
* TypeORM
* Django
* SQLAlchemy
* JDBC
* Go PostgreSQL drivers
* Other PostgreSQL-compatible clients

This template deploys **PgBouncer only**. An existing PostgreSQL database is required.

## Why Deploy

PostgreSQL creates a dedicated backend process for each active connection. Applications with many concurrent connections can therefore consume significant database resources.

PgBouncer sits between applications and PostgreSQL and allows multiple client connections to share a controlled number of backend connections.

This can help:

* Reduce PostgreSQL connection overhead
* Handle larger numbers of application connections
* Protect PostgreSQL from connection spikes
* Improve connection reuse
* Centralize database access
* Separate application credentials from backend PostgreSQL credentials
* Reduce idle PostgreSQL connections
* Simplify connection management for APIs and web applications

PgBouncer is especially useful for applications with many short-lived or concurrent database connections.

## Common Use Cases

* PostgreSQL connection pooling
* High-concurrency APIs
* Web applications
* Serverless-style workloads
* Microservices sharing PostgreSQL
* Reducing idle database connections
* Protecting PostgreSQL connection limits
* Handling application connection spikes
* Centralizing PostgreSQL access
* Adding a lightweight proxy between applications and PostgreSQL

## Dependencies for

This template requires:

* Existing PostgreSQL server
* PostgreSQL hostname
* PostgreSQL port
* Database name
* Valid PostgreSQL username
* Valid PostgreSQL password
* Network connectivity from PgBouncer to PostgreSQL

It does not require:

* Redis
* MongoDB
* etcd
* RabbitMQ
* Object storage
* Railway Volume

PgBouncer does not store application data. Database persistence remains the responsibility of the PostgreSQL provider.

## Important: PostgreSQL Is Not Included

This template deploys **PgBouncer only**.

You must provide an existing PostgreSQL database, such as:

* Railway PostgreSQL
* Amazon RDS PostgreSQL
* Amazon Aurora PostgreSQL
* Google Cloud SQL
* Azure Database for PostgreSQL
* Supabase
* Neon
* Self-hosted PostgreSQL
* Another PostgreSQL-compatible provider

Backend PostgreSQL connection details are configured through environment variables.

## Important: TCP, Not HTTP

PgBouncer is not a web application.

It listens for PostgreSQL connections on:

```text
TCP 6432
```

Do not connect using an HTTP URL such as:

```text
https://example.up.railway.app
```

For external access, configure a Railway **TCP Proxy** for PgBouncer's internal port `6432`.

Applications running inside the same Railway project should preferably use Railway private networking.

## Environment Variables

This template generates PgBouncer's native configuration files when the container starts.

### PgBouncer Settings

| Variable             | Description                                            | Default       |
| -------------------- | ------------------------------------------------------ | ------------- |
| `PGBOUNCER_PORT`     | Incoming PostgreSQL TCP port                           | `6432`        |
| `PGBOUNCER_DATABASE` | Virtual database exposed to clients                    | —             |
| `PGBOUNCER_USER`     | Username applications use when connecting to PgBouncer | —             |
| `PGBOUNCER_PASSWORD` | Password applications use when connecting to PgBouncer | —             |
| `POOL_MODE`          | PgBouncer pooling strategy                             | `transaction` |
| `DEFAULT_POOL_SIZE`  | Maximum backend connections per pool                   | `20`          |
| `MAX_CLIENT_CONN`    | Maximum simultaneous client connections                | `100`         |

### PostgreSQL Backend Settings

| Variable            | Description                 | Default |
| ------------------- | --------------------------- | ------- |
| `POSTGRES_HOST`     | PostgreSQL hostname         | —       |
| `POSTGRES_PORT`     | PostgreSQL port             | `5432`  |
| `POSTGRES_DATABASE` | Actual PostgreSQL database  | —       |
| `POSTGRES_USER`     | Backend PostgreSQL username | —       |
| `POSTGRES_PASSWORD` | Backend PostgreSQL password | —       |

The PgBouncer database name may differ from the actual PostgreSQL database name.

Example:

```text
PGBOUNCER_DATABASE=app
POSTGRES_DATABASE=production
```

Applications connect to `app`, while PgBouncer connects to the actual `production` database.

## Client Credentials vs PostgreSQL Credentials

This template separates client credentials from PostgreSQL backend credentials.

```text
Application
    │
    │ PGBOUNCER_USER
    │ PGBOUNCER_PASSWORD
    ▼
PgBouncer
    │
    │ POSTGRES_USER
    │ POSTGRES_PASSWORD
    ▼
PostgreSQL
```

Applications therefore do not need direct access to the backend PostgreSQL credentials.

## Pool Modes

PgBouncer supports several connection pooling strategies.

| Mode          | Backend connection released | Best suited for                                     |
| ------------- | --------------------------- | --------------------------------------------------- |
| `session`     | When client disconnects     | Legacy applications and session-dependent workloads |
| `transaction` | After each transaction      | APIs and typical web applications                   |
| `statement`   | After each statement        | Specialized workloads                               |

This template uses:

```text
POOL_MODE=transaction
```

by default.

Transaction pooling generally provides more effective connection reuse for typical API and web application workloads.

Applications that depend heavily on session-level PostgreSQL state may require `session` mode instead.

## Connection Pooling

A typical connection flow may look like:

```text
100 application connections
          │
          ▼
      PgBouncer
          │
          ▼
20 PostgreSQL connections
```

The actual number of backend connections depends on:

* `DEFAULT_POOL_SIZE`
* Number of databases
* Number of users
* Application concurrency
* Transaction duration
* PostgreSQL connection limits

Avoid setting `DEFAULT_POOL_SIZE` equal to the PostgreSQL server's entire connection limit.

Reserve PostgreSQL connections for:

* Administrative access
* Database migrations
* Monitoring
* Maintenance
* Background jobs
* Other database services

## Connecting to PgBouncer

Use a standard PostgreSQL connection string:

```text
postgresql://PGBOUNCER_USER:PGBOUNCER_PASSWORD@TCP_HOST:TCP_PORT/PGBOUNCER_DATABASE
```

Example:

```text
postgresql://appuser:password@your-tcp-host:12345/app
```

Railway may assign an external TCP port different from PgBouncer's internal port.

PgBouncer continues listening internally on:

```text
6432
```

## Railway Networking

Recommended configuration:

```text
Protocol: TCP
Internal Port: 6432
HTTP Domain: Not required
TCP Proxy: Required only for external access
Volume: Not required
```

If PgBouncer and your application run inside the same Railway project, prefer Railway private networking.

## PgBouncer vs Direct PostgreSQL

| Feature                            | PgBouncer |     Direct PostgreSQL |
| ---------------------------------- | --------: | --------------------: |
| PostgreSQL wire protocol           |         ✅ |                     ✅ |
| Connection pooling                 |         ✅ | Application-dependent |
| Connection reuse                   |         ✅ |               Limited |
| Protects backend connection limits |         ✅ |                     ❌ |
| Dedicated pooling layer            |         ✅ |                     ❌ |
| Query routing                      |         ❌ |                     ❌ |
| Sharding                           |         ❌ |                     ❌ |
| Additional infrastructure          |         ✅ |                     ❌ |
| Simpler architecture               |         ❌ |                     ✅ |

Direct PostgreSQL connectivity remains perfectly suitable for small workloads with predictable connection counts.

PgBouncer becomes more useful as application concurrency and connection pressure increase.

## Why Railway?

Railway provides a convenient environment for running PgBouncer as a dedicated PostgreSQL pooling layer.

Benefits include:

* Simple standalone deployment
* Railway private networking
* Environment-based secret management
* PostgreSQL-compatible TCP endpoints
* Centralized service logs
* Independent scaling
* Easy integration with Railway PostgreSQL
* Support for PostgreSQL providers outside Railway
* Reproducible configuration

PgBouncer provides a lightweight database infrastructure layer between your applications and PostgreSQL while allowing applications to continue using standard PostgreSQL drivers.

## Similar templates

- [Garage S3 Storage](https://railway.com/deploy/garage-s3-storage) — Ultra-light S3 server: fast, open-source, plug-and-play.
- [Redis](https://railway.com/deploy/redis-1) — Self Host Latest Redis with Railway
- [EasyImg](https://railway.com/deploy/easyimg) — Simple self-hostable Nuxt.js personal image hosting system.

Open this page in a browser: https://railway.com/deploy/pgbouncer
