Connect
Pick the pooled or the direct endpoint, take your credentials from the Connect tab, and connect with verify-full against your system trust store. Examples for psql and the common drivers.
Connecting to a Balta service takes two things: an endpoint, and a role and password. Both are on the service's Connect tab. There is no certificate file to download.
This page is the short path. Connection strings covers each parameter in detail.
1. Take your credentials
- Open the service and select the Connect tab.
- Endpoint gives you the hostname and both ports.
- Under Credentials, reveal the Password.
Every reveal is recorded in your audit log. That is deliberate, and the panel says so before you press it.
2. Choose an endpoint
Both endpoints share one hostname and differ only by port, and the lower of your two ports is the pooled one. The pair is your service's own: services in a location share their hosts' addresses and are told apart by port, so a second service does not get the same pair as the first. They do not change for the life of the service.
| Endpoint | Port | Use it for |
|---|---|---|
| Pooled | The lower | Web and SaaS application traffic, serverless functions, anything with high connection churn. This is the default |
| Direct | The higher | LISTEN and NOTIFY, session advisory locks, session-level SET, WITH HOLD cursors, temporary tables across transactions |
The examples on this page use 25438 and 25439. That pair belongs to one service and to no
other. Yours are on the Connect tab.
Use pooled unless you need something on the right. Using both from the same application is normal: put your job-queue listener on direct and everything else on pooled.
Full compatibility detail is in pooled versus direct.
3. Verify against the trust store you already have
Your endpoint presents a publicly trusted certificate. Your client checks it against the roots its platform already ships, so there is nothing to download and no path to fill in.
Which store that is depends on the client. libpq reads the operating system's, and
sslrootcert=system is how you ask for it. The JVM reads cacerts, and pgjdbc reaches it only
when the URL also carries sslfactory=org.postgresql.ssl.DefaultJavaSSLFactory. Node reads either
its own root list or the operating system's, depending on where the binary came from, and needs
rejectUnauthorized: true with servername.
sslrootcert=system needs libpq 16 or newer; on an older libpq give it the path to the operating
system's bundle instead: /etc/ssl/certs/ca-certificates.crt on Debian and Ubuntu,
/etc/pki/tls/certs/ca-bundle.crt on RHEL and its family, and
$(brew --prefix)/etc/openssl@3/cert.pem with Homebrew's libpq on macOS.
TLS and certificate verification covers the rest.
4. Connect with full verification
psql "postgresql://[email protected]:25438/appdb?sslmode=verify-full&sslrootcert=system"sslmode=verify-full checks the certificate chain and that the hostname matches. Anything
weaker accepts a certificate for a different host. Every example in this documentation uses
verify-full, and none of them should be copied with a weaker mode.
Keep the password out of the connection string. A password in a URL ends up in process listings,
shell history, container inspect output and log lines. Supply it through PGPASSWORD or ~/.pgpass
instead, as the examples below do.
Client examples
export PGPASSWORD=REDACTED-EXAMPLE-ONLY
psql "postgresql://[email protected]:25438/appdb?sslmode=verify-full&sslrootcert=system"More languages, including Ruby on Rails, Django and JDBC, are on client examples.
What you will see
A successful psql connection opens a prompt on appdb, the database your service was created
with. \conninfo confirms which port you reached and that the connection is encrypted.
Troubleshooting
- Check you are using TLS. Non-TLS connections are refused, not downgraded.
- Check what your client verifies against. A missing or wrong
sslrootcertproduces a verification failure, not a plaintext fallback. Java and Node do not readsslrootcertat all, and each needs its own parameter above. - Check the endpoint. The pooled and direct endpoints use different ports.
Check the service's IP allowlist as well. An address that is not on it cannot open a connection, and the packet is dropped before PostgreSQL is reached — so the symptom is a timeout rather than a refusal. A rule saved a moment ago takes a few seconds to reach the host. See IP allowlists for how the two allowlists differ.
A session variable your framework sets and reads back in a later transaction is the other common surprise. On the pooled endpoint it does not error: it reads the default, and the bug surfaces somewhere else entirely. Move that consumer to the direct endpoint. See pooled versus direct.
Message-by-message detail is on error messages.