---
title: "Deploy PgBouncer with Postgres"
description: "A PostgreSQL database with lightweight connection pooling via PgBouncer."
category: "Storage"
url: https://railway.com/deploy/pgbouncer-with-postgres
---

# Deploy PgBouncer with Postgres

A PostgreSQL database with lightweight connection pooling via PgBouncer.

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

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

## Template content

### Postgres https://devicons.railway.app/i/postgresql.svg

- **Image:** ghcr.io/railwayapp-templates/postgres-ssl:18

### 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 with Postgres on Railway

PgBouncer with Postgres deploys a lightweight PostgreSQL connection pooler together with a Railway PostgreSQL database.

PgBouncer sits between your application and PostgreSQL, reducing connection overhead and allowing many client connections to share a smaller number of backend database connections.

## About Hosting

This template deploys two services:

```text
Application
    │ PostgreSQL Protocol
    ▼
PgBouncer :6432
    │ Railway Private Network
    ▼
PostgreSQL :5432
```

PgBouncer acts as the database endpoint used by your application, while PostgreSQL stores the actual application data.

The PostgreSQL service uses Railway-managed persistent storage. PgBouncer itself does not require a Railway Volume.

PgBouncer works with standard PostgreSQL clients and drivers, including:

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

## Why Deploy

PostgreSQL creates backend processes for active connections. Applications with high concurrency or many short-lived connections can therefore consume significant database resources.

PgBouncer provides a lightweight pooling layer that can reduce the number of direct PostgreSQL connections.

This template can help:

* Reduce PostgreSQL connection overhead
* Improve connection reuse
* Handle larger numbers of application connections
* Protect PostgreSQL from connection spikes
* Reduce idle backend connections
* Centralize database connectivity
* Separate application credentials from PostgreSQL credentials
* Keep PostgreSQL private behind PgBouncer
* Simplify PostgreSQL infrastructure for APIs and web applications

Applications continue using normal PostgreSQL connection strings and drivers.

## Common Use Cases

* High-concurrency APIs
* Web applications
* SaaS applications
* Microservices using PostgreSQL
* Serverless-style workloads
* Reducing PostgreSQL connection pressure
* Protecting database connection limits
* Centralized database access
* Applications with many short-lived connections
* Adding connection pooling to Railway PostgreSQL

## Dependencies for

This template includes:

* PgBouncer
* Railway PostgreSQL

It does not require:

* Redis
* MongoDB
* etcd
* RabbitMQ
* Object storage
* A Railway Volume for PgBouncer

PostgreSQL persistence is handled by Railway's PostgreSQL service.

## Architecture

```text
                    Railway
                       │
                       ▼
                ┌─────────────┐
                │  PgBouncer  │
                │ TCP :6432   │
                └──────┬──────┘
                       │
                       │ Private Network
                       ▼
                ┌─────────────┐
                │ PostgreSQL  │
                │ TCP :5432   │
                └─────────────┘
```

Applications should connect to PgBouncer rather than directly to PostgreSQL for normal application traffic.

## Important: TCP, Not HTTP

PgBouncer is not a web application.

It listens for PostgreSQL connections on:

```text
TCP 6432
```

Do not connect through an HTTP URL such as:

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

Use a PostgreSQL client or driver.

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

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

## Environment Variables

PgBouncer generates its native configuration during container startup.

### PgBouncer Settings

| Variable             | Description                              | Default       |
| -------------------- | ---------------------------------------- | ------------- |
| `PGBOUNCER_PORT`     | Incoming PostgreSQL TCP port             | `6432`        |
| `PGBOUNCER_DATABASE` | Virtual database exposed to applications | `app`         |
| `PGBOUNCER_USER`     | Username applications use to connect     | `pgbouncer`   |
| `PGBOUNCER_PASSWORD` | Password applications use to connect     | Generated     |
| `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

The PostgreSQL backend values are automatically referenced from the Railway PostgreSQL service.

Typical variables include:

```text
POSTGRES_HOST
POSTGRES_PORT
POSTGRES_DATABASE
POSTGRES_USER
POSTGRES_PASSWORD
```

These values should reference the Railway PostgreSQL service variables such as:

```text
PGHOST
PGPORT
PGDATABASE
PGUSER
PGPASSWORD
```

Users normally do not need to manually enter PostgreSQL backend credentials.

## Client Credentials vs PostgreSQL Credentials

This template separates application credentials from PostgreSQL backend credentials.

```text
Application
    │
    │ PGBOUNCER_USER
    │ PGBOUNCER_PASSWORD
    ▼
PgBouncer
    │
    │ PostgreSQL service credentials
    ▼
PostgreSQL
```

Applications therefore do not need direct access to the PostgreSQL username and password.

This allows PgBouncer credentials to be rotated independently from the database account.

## Pool Modes

PgBouncer supports multiple pooling strategies.

| Mode          | Backend connection released | Best suited for                          |
| ------------- | --------------------------- | ---------------------------------------- |
| `session`     | When client disconnects     | Session-dependent or legacy applications |
| `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 usually provides better connection reuse for APIs and web applications.

Applications that depend heavily on session-level PostgreSQL features may need `session` mode instead.

## Connection Pooling

A typical deployment may look like:

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

The actual number of backend connections depends on:

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

Avoid configuring the pool to consume the entire PostgreSQL connection limit.

Keep spare capacity for:

* Administration
* Database migrations
* Monitoring
* Maintenance
* Background jobs
* Other database consumers

## Connecting to PgBouncer

Use a standard PostgreSQL connection string:

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

Example:

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

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

PgBouncer continues listening internally on:

```text
6432
```

The PostgreSQL service itself should normally remain private.

## PgBouncer with Postgres vs Direct PostgreSQL

| Feature                                | PgBouncer with Postgres |     Direct PostgreSQL |
| -------------------------------------- | ----------------------: | --------------------: |
| PostgreSQL included                    |                       ✅ |                     ✅ |
| PostgreSQL wire protocol               |                       ✅ |                     ✅ |
| Dedicated connection pooling           |                       ✅ |                     ❌ |
| Connection reuse                       |                       ✅ | Application-dependent |
| Protects backend connection limits     |                       ✅ |                     ❌ |
| Separate application credentials       |                       ✅ |                     ❌ |
| PostgreSQL can remain private          |                       ✅ |                     ✅ |
| Additional infrastructure              |                       ✅ |                     ❌ |
| Simpler architecture                   |                       ❌ |                     ✅ |
| Better for high connection concurrency |                       ✅ |               Limited |

Direct PostgreSQL remains simpler for applications with low and predictable connection usage.

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

## Why Railway?

Railway provides a convenient environment for running PgBouncer together with PostgreSQL in a single project.

Benefits include:

* Railway-managed PostgreSQL
* Persistent database storage
* Private service networking
* Environment-based secret management
* PostgreSQL-compatible TCP endpoints
* Centralized logs
* Independent PgBouncer scaling
* Reproducible multi-service deployments
* Simple integration between PgBouncer and PostgreSQL

PgBouncer with Postgres provides a compact PostgreSQL stack with built-in connection pooling while keeping the database architecture simple.

## 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-with-postgres
