PostgreSQL
Your own PostgreSQL 18 with connection pooling on, a direct address for tools that need one, and limits you set. Laravel, Django and Node.js just connect.
Updated 17 Oct 20263 min read
PostgreSQL 18 runs as its own database, with its own memory and processor limits. Connection pooling is on from the start, so apps that open many short connections, like Node.js and serverless-style apps, don't run out. Your app gets two addresses: a pooled one for everyday use, and a direct one for tools that need it.
Add one
Open your project's Overview, and under Add a service choose Database.
Choose PostgreSQL. Its detail says the version and "connection pooling on".
Set the memory and processor limits with the sliders. They start at 512 MB and half a processor; the lowest memory PostgreSQL may have is 256 MB.
Keep or change the name, tick the apps that should get its connection details, and choose Add.
It's ready in about a minute. It pays for the memory and processor it really uses, every hour, and for what it stores. There's no shared PostgreSQL.
The two addresses
| Port | Variable | Use it for | |
|---|---|---|---|
| Pooled | 6432 | DATABASE_URL, and DB_PORT | Your app, its workers and its scheduled tasks |
| Direct | 5432 | DATABASE_DIRECT_URL | Migrations that need one session, LISTEN, and tools that ask for a direct connection |
Both use the same host, user and password. The pool works one transaction at a time: each transaction gets a connection, and gives it back when it ends. That's what lets hundreds of short requests share a few real connections. Anything that needs the same connection across transactions, like LISTEN and NOTIFY, session advisory locks or SET without LOCAL, belongs on the direct address.
Example: Juma's Django app
Juma runs a Django app called api in his project soko. He adds PostgreSQL, names it postgres, and ticks api. These variables appear on api, managed by the database:
DB_CONNECTION=pgsql
DB_HOST=postgres.soko.internal
DB_PORT=6432
DB_DATABASE=db_soko
DB_USERNAME=db_sokoDB_PASSWORD, DATABASE_URL and DATABASE_DIRECT_URL are there too, with the password in them. In Django, he reads DATABASE_URL with a library such as dj-database-url. For his migrations, which he runs from the app's terminal, the pooled address works too; a tool that complains about it can use DATABASE_DIRECT_URL instead.
The main user and the database have the same name: db_ and the project's name.
Laravel on PostgreSQL
Laravel reads DB_CONNECTION=pgsql and the other DB_ variables as they are. Nothing needs to change in config/database.php.
Node.js
Most Node.js libraries, like pg, Prisma and Drizzle, take one connection address. Give them DATABASE_URL. Prisma's migrations want a direct connection: point its directUrl setting at DATABASE_DIRECT_URL.
Importing
You can import a plain .sql dump, made with pg_dump in its plain format. A custom-format archive (pg_dump -Fc) is refused, with a message: export the old database again as plain SQL. See Import and export.
New passwords
When you choose Change the password, a new one is made, and every attached app gets it and restarts. For PostgreSQL there's no second password to keep beside the new one, so for the few seconds until the apps restart, a new connection with the old password is refused. Connections already open, and the pool's, carry on. See Users and passwords.
Memory
More memory takes effect at once. Less memory restarts the database in a few seconds. A new major version, like 18 to 19, is a new database and an import.