Connection pooling for PostgreSQL
Why PostgreSQL runs out of connections before it runs out of capacity, what the pooled endpoint on your Voroa database changes, and which endpoint to use when.
What this covers
PostgreSQL gives every connection its own process and its own memory, so the number of connections a database can hold is far lower than the number of requests it could actually serve. Applications that open a connection per request, or that run several copies each with its own pool, hit that ceiling and start getting refused long before the database is genuinely busy. A connection pooler sits in front and multiplexes many client connections onto a small number of real ones, so the database sees a steady handful instead of a crowd.
Your database has two endpoints
On the Database page, under External access, you may see a pooled port listed next to the external port. Both are on the same host, and they behave differently:
- The external port is direct. Your session reaches PostgreSQL itself, and every PostgreSQL feature works normally.
- The pooled port is a connection pooler. It accepts far more client connections than the database has slots, releasing each server connection back to the pool at the end of every transaction.
If no pooled port is listed, your database has one endpoint and it is the direct one. Nothing is missing from it.
Which one to use
Use the pooled port when you have many short-lived connections and each unit of work fits in one transaction: serverless functions, edge runtimes, scheduled jobs, or an application that scales to a lot of instances. This is what stops a busy application from exhausting the database’s connection slots.
Use the direct port when your work needs one session held open across statements. Because the pooler hands the server connection to somebody else after each transaction, these do not work through it:
LISTEN/NOTIFY- session-level advisory locks
- temporary tables
- cursors declared
WITH HOLD - session settings you expect to persist (
SEToutside a transaction) - prepared statements that are meant to outlive the transaction that created them
Many database drivers and ORMs use some of these by default, so if something works on the direct port and fails on the pooled one, this list is the first place to look. Migrations and schema changes are safest on the direct port.
The two ports also protect the database’s memory differently. The pooled port runs only as many queries at once as your instance’s memory can hold; further queries wait their turn instead of competing. The direct port has no such limit below the connection count, so an application that sends many heavy queries at the same time through it can use up the instance’s memory, and PostgreSQL then restarts and drops every open connection. Keep the direct port for admin and migration tools, and point an application that runs many queries at once at the pooled port.
You still want a pool in your application
The pooled endpoint does not replace a pool inside your own application - it works best alongside one. Keep your application pool’s maximum size small and let the pooled endpoint absorb the fan-out.
Related
- Connect to your Voroa PostgreSQL database from anywhere
- How to add environment variables on Voroa
- Service resource usage: see your RAM and CPU on Voroa
- Managed PostgreSQL on Voroa - sizes, prices and what every database includes.