Skip to content

PostgreSQL

Tested with: PostgreSQL 17.11 and 18.6 on Databasezy (CloudNativePG 1.27) · zb CLI 0.1

PostgreSQL is the general-purpose relational engine on Databasezy: SQL with transactions, JSONB, rich indexing and a large extension and driver ecosystem. Pick it when you are not sure which engine you need.

Each instance is a PostgreSQL cluster managed by CloudNativePG. It starts with a single primary; on paid plans you can add a standby for high availability (--ha) and read replicas (--replicas). The newest supported major is the default. Minor (patch) releases are not yet applied to running instances on a schedule.

PostgreSQL at a glance, from the engine catalogue
Status Available
CategoryRelational
Versions18, 17, 16, 15 (newest is the default)
Protocol and port PostgreSQL wire protocol on 5432
RuntimeOperator-backed (CloudNativePG)
Backupsbarman-cloud base backups + WAL
Point-in-time recoveryYes
PauseScale to zero
Free planYes (size f0)
FeaturesBuilt-in transaction-mode pooler, Extensions, Read replicas, High availability (standby)
LicencePostgreSQL

The image is CloudNativePG’s PostgreSQL image: the contrib modules plus pgvector, pgaudit and pg_failover_slots. PostGIS and pg_cron are not included.

The generated user can create the extensions PostgreSQL marks as trusted, for example:

psql
create extension if not exists pgcrypto;

The trusted ones are pgcrypto, uuid-ossp, hstore, citext, pg_trgm, btree_gin, btree_gist, ltree, unaccent, fuzzystrmatch, cube, intarray, isn, lo, seg, tablefunc, tcn, dict_int, tsm_system_rows and tsm_system_time. vector (pgvector), pg_stat_statements and pgaudit are in the image but only a superuser can create them, and you cannot request them for an instance yet. pg_available_extensions lists everything in the image, including the extensions you cannot create.

  1. Open the portal and choose New instance.
  2. Pick PostgreSQL and a version (18, 17, 16, 15).
  3. Choose a size and region. On the Free plan the size is f0. Secure placement is listed only after your organization has signed the BAA.
  4. Check the hourly price and monthly estimate, then confirm. The Connect tab fills in when the instance is ready.

Every snippet uses sslmode=verify-full or the driver’s equivalent. libpq-based drivers do not read the operating system’s trust store, so they get the CA bundle path explicitly.

PostgreSQL listens on port 5432 (PostgreSQL wire protocol). Versions: 18, 17, 16, 15. Replace the example host with the one on your instance's Connect tab; credentials are shown once at creation.

Connection URI
postgresql://app:<password>@pg-7f3k.us-east.databasezy.com:5432/app?sslmode=verify-full&sslrootcert=databasezy-ca.pem
db.js
import { readFileSync } from "node:fs";
import { Pool } from "pg";
const host = "pg-7f3k.us-east.databasezy.com";
export const pool = new Pool({
host,
port: 5432,
database: "app",
user: "app",
password: process.env.ZB_PASSWORD,
ssl: {
ca: readFileSync("databasezy-ca.pem", "utf8"),
rejectUnauthorized: true, // verify chain
servername: host, // verify hostname (verify-full)
},
max: 10, // keep well under the size's max_connections
idleTimeoutMillis: 30_000,
});
const { rows } = await pool.query("select version()");
console.log(rows[0]);

Tested with: PostgreSQL 18 · node-postgres (pg) 8.13

The PostgreSQL connection guide goes deeper on TLS, pooling and the allow-list. For serverless and edge runtimes, turn on the transaction-mode pooler under Connect → Pooler and read connection pooling first. Framework guides: Prisma, Drizzle, Django, SQLAlchemy, Rails, Laravel, Spring, Phoenix, Next.js.

See Connecting to Databasezy for host names, the CA bundle and the allow-list, which work the same for every engine.

You can bring an existing PostgreSQL database in from these sources. Each links to a step-by-step guide.

Where you can migrate a PostgreSQL database from, how, and whether continuous sync is available
Source How Continuous sync Guide status
Neon Connection string Yes Available
Supabase Connection string Yes Available
Amazon RDS and Aurora Connection string Yes Coming soon · phase 2
Render Connection string Yes Coming soon · phase 2
Railway Connection string Yes Coming soon · phase 2
Heroku Connection string, File upload No Coming soon · phase 2
Fly.io Connection string, Local tools (zb migrate --from local) Yes Coming soon · phase 2
Aiven Connection string Yes Coming soon · phase 2
DigitalOcean Managed Databases Connection string Yes Coming soon · phase 2
Crunchy Bridge Connection string Yes Coming soon · phase 2
Vercel Postgres (legacy, now Neon) Connection string Yes Coming soon · phase 2
Prisma Postgres Connection string No Coming soon · phase 2
Xata Connection string No Coming soon · phase 3
Netlify DB Connection string Yes Coming soon · phase 2
Google Cloud SQL Connection string Yes Coming soon · phase 3
Azure Database Connection string Yes Coming soon · phase 3
Self-hosted server Connection string, Local tools (zb migrate --from local) Yes Available
Local files and dumps File upload, Local tools (zb migrate --from local) No Available
Docker container Local tools (zb migrate --from local) No Available
Another Databasezy instance Instance to instance Yes Coming soon · phase 2

PostgreSQL sources can use continuous sync: logical replication keeps the target current after the copy, so cutover takes seconds. Moving to a new major version is an instance-to-instance migration; see engine version upgrades.

How migrations work explains preflight, verification and cutover.

CloudNativePG takes barman-cloud base backups and archives the write-ahead log continuously to object storage; point-in-time recovery replays that log up to the moment you choose.

PostgreSQL backups use barman-cloud base backups + WAL. They run inside the instance's namespace, stream straight to the cell's object storage and are checksummed on upload. How often they run and how long they are kept follows your plan's backup policy. A backup is always taken before a resize or a version upgrade.

Point-in-time recovery is supported: you can restore to any moment inside the PITR window of your plan or the PITR add-on. Restores create a new instance by default and leave the original untouched; an in-place restore asks you to type the instance name and takes a pre-change backup first.

shell
zb backups create postgres-demo --label before-release # manual snapshot
zb backups list postgres-demo
zb backups restore postgres-demo <backup-id> --name postgres-demo-restore
# Point in time (RFC 3339) inside the PITR window
zb backups pitr-window postgres-demo
zb backups restore postgres-demo <backup-id> --at "2026-09-27T08:15:00Z" --name postgres-demo-pitr

PostgreSQL can scale to zero. A paused instance has no running pods and bills no compute; its storage and backups are kept and billed as usual. Connections are refused until you resume it. On the Free plan an instance pauses by itself after 15 minutes without connections and wakes on the next one; the gateway holds that connection for up to 30 seconds while it starts.

shell
zb instances pause postgres-demo
zb instances resume postgres-demo

See Pause and resume for schedules, wake times and billing while paused.

PostgreSQL runs on every size, including the Free plan's f0. The size sets the CPU, memory, storage ceiling and connection limit; the gateway refuses connections over the limit with a protocol error. Storage grows in steps up to the ceiling, and you can resize at any time.

Sizes available for PostgreSQL: vCPU, memory, storage ceiling, connection limit and monthly price
Size vCPU Memory Max storage Max connections ≈ $ / month
f0 0.063 512 MiB 1 GB 20 Free
s0 0.25 1 GiB 20 GB 60 $10
s1 0.5 2 GiB 50 GB 100 $15
s2 1 4 GiB 200 GB 200 $60
m2 2 8 GiB 500 GB 400 $110
m4 4 16 GiB 1 TB 800 $210
l8 8 32 GiB 4 TB 1,500 $410
l16 16 64 GiB 8 TB 3,000 $960
xl32 32 128 GiB 16 TB 5,000 $1,870

Full details, including hourly prices and burst CPU, are in the size catalogue; plan quotas are in limits and quotas.

Every instance has one database user, the generated app. It owns the app database and its public schema: it can create schemas, tables and the trusted extensions, and grant privileges on the objects it owns. It is not a superuser and cannot create other roles or databases (CloudNativePG creates the database owner without CREATEROLE or CREATEDB), so your application, migrations and reporting tools all connect as app. Separate users per tool are not available yet; use schemas to keep their objects apart, and rotate the password if it leaks.

  • TLS on every connection. TLS 1.2 is the minimum and TLS 1.3 is preferred; plaintext is never offered. Verify the server, not just the encryption: use sslmode=verify-full. See TLS and the CA bundle.
  • IP allow-list. The gateway checks the client address before authentication, on every plan. Manage it under Network → Allow-list in the portal or with PUT /v1/orgs/{org}/instances/{id}/network.
  • Credentials. Generated inside the cell, shown once, never stored by the control plane. Rotate them with an overlap window so nothing breaks.
  • Secure hosting. Secure placement (HIPAA-ready) is a per-instance option once your organization has signed the BAA: dedicated nodes, customer-managed keys and immutable backups. See Secure hosting and the BAA.
  • Staff access. Databasezy staff cannot read your data without a grant you issue. See data confidentiality.

The trusted ones listed under Extensions: run create extension <name> as the generated user. vector, pg_stat_statements and pgaudit are in the image but need a superuser, and PostGIS and pg_cron are not available. When you migrate in, preflight lists extensions on the source that Databasezy does not ship, before anything is copied.

Create a new instance on the newer version and run zb migrate --from <old> --to <new> --mode copy_and_sync. Test against the new instance while sync runs, then cut over. A running instance never changes major version on its own.

Not yet. The generated app user cannot create roles, so every client connects as app. See Security.

Long-running services should keep their own pool and stay under the size’s connection limit. Serverless functions and edge runtimes should use the built-in transaction-mode pooler, keeping in mind that session state such as LISTEN and session-level prepared statements does not carry across transactions.

Yes, on paid plans. Pass --replicas <n> (and --ha for a standby) when you create the instance.