Voltro + Fly.io Postgres

Run Voltro on Fly.io with a Postgres app — Flycast internal routing, the connection string, full LISTEN/NOTIFY reactivity, and the unmanaged-database tradeoff.

Fly Postgres is a Fly app running Postgres, not a fully managed database — you own backups, failover, and scaling. It maps to Voltro's postgres dialect with the full reactive surface: LISTEN/NOTIFY CDC, advisory-lock cluster workflows, read replicas, JSONB. No transaction pooler sits in front by default, so reactivity works directly.

Connect

Inside the Fly private network, connect over the app's .internal / Flycast address:

# Fly private network (6PN) — app-to-database within your org
DB_DIALECT=postgres
DB_URL=postgresql://postgres:[PASSWORD]@[PG-APP-NAME].internal:5432/[DB]
# Flycast (internal load-balanced address — preferred for HA clusters)
DB_DIALECT=postgres
DB_URL=postgresql://postgres:[PASSWORD]@[PG-APP-NAME].flycast:5432/[DB]

When you fly postgres attach, Fly sets a DATABASE_URL secret on the consuming app — map it straight to DB_URL.

Enabling CDC

Voltro's change-data-capture is LISTEN/NOTIFY, on by default (CDC=1) — no extension, no flag. A Fly Postgres app has no transaction pooler in front by default, so the .internal / Flycast connection you map to DB_URL is session-mode and reactivity works immediately. If you front it with a pgbouncer app for connection scaling, keep that pooler in session mode or pin the single CDC listener to a direct connection so LISTEN/NOTIFY survives.

Pooling / SSL / region

  • No pooler by default. Postgres reactivity works directly. If you front it with a pgbouncer app for connection scaling, keep it in session mode (or run the CDC listener on a direct connection) so LISTEN/NOTIFY survives.
  • SSL: traffic over the Fly private network (6PN / Flycast) is already isolated; you typically don't need sslmode=require internally. Public access does.
  • Region locality: if you run Postgres read replicas across regions, set DB_REPLICA_URLS + DB_REPLICA_REGIONS and let the framework's FLY_REGION auto-detection prefer same-region replicas. See read replicas.

Unmanaged tradeoff

Fly Postgres is closer to "Postgres on a VM" than to RDS — there's no automated point-in-time recovery unless you wire it up. Fine for the reactive workload; just own the backup story.

Verify

[voltro:dev] sql dialect resolved: postgres — CDC: LISTEN/NOTIFY, RETURNING: native
[voltro:dev] read replicas: 0 configured (DB_REPLICA_URLS empty) — all queries → primary
[voltro:dev] workflow engine: cluster-sql, dialect=postgres

Confirm with voltro logs --tail 50.

See also