Deploy PgBouncer
A simple PostgreSQL pooler to reduce database connection overhead.
pgbouncer
Just deployed
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.
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:
TCP 6432
Do not connect using an HTTP URL such as:
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:
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.
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:
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:
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:
postgresql://PGBOUNCER_USER:PGBOUNCER_PASSWORD@TCP_HOST:TCP_PORT/PGBOUNCER_DATABASE
Example:
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:
6432
Railway Networking
Recommended configuration:
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.
Template Content
POSTGRES_HOST
Hostname of the upstream PostgreSQL server
POSTGRES_USER
Username PgBouncer uses to connect to PostgreSQL
PGBOUNCER_USER
Username clients use when connecting through PgBouncer
POSTGRES_DATABASE
Actual database name on the upstream PostgreSQL server
POSTGRES_PASSWORD
Password PgBouncer uses to connect to PostgreSQL
PGBOUNCER_DATABASE
Virtual database name exposed by PgBouncer
PGBOUNCER_PASSWORD
Password clients use when connecting through PgBouncer