Voltro + DigitalOcean Managed Databases

Run Voltro on DigitalOcean Managed Postgres or MySQL — the connection pool gotcha for LISTEN/NOTIFY, sslmode=require, trusted sources, and connection strings.

DigitalOcean Managed Databases offer Postgres and MySQL, mapping to Voltro's postgres and mysql dialects. Postgres gives you the full reactive surface — LISTEN/NOTIFY CDC, advisory-lock workflows, read replicas, JSONB — with one pooling caveat.

Connect

DigitalOcean gives you a direct connection (port 25060) and, if you create one, a connection pool (a separate host/port).

# Direct connection — session-mode, supports LISTEN/NOTIFY.
DB_DIALECT=postgres
DB_URL=postgresql://[USER]:[PASSWORD]@[CLUSTER]-do-user-[ID].[REGION].db.ondigitalocean.com:25060/[DB]?sslmode=require
# MySQL cluster
DB_DIALECT=mysql
DB_URL=mysql://[USER]:[PASSWORD]@[CLUSTER]-do-user-[ID].[REGION].db.ondigitalocean.com:25060/[DB]?ssl-mode=REQUIRED

sslmode=require (Postgres) / ssl-mode=REQUIRED (MySQL) is mandatory — DO clusters reject unencrypted connections.

Enabling CDC

On Postgres, Voltro's change-data-capture is LISTEN/NOTIFY, on by default (CDC=1) — no extension, no flag. The one requirement on DigitalOcean is to point DB_URL (or at least the CDC listener) at the direct connection (port 25060), which is session-mode — not the built-in connection pool in its default transaction mode, which breaks LISTEN/NOTIFY (below). On the MySQL cluster, CDC is inline-only / single-instance — nothing to enable, no cross-instance fan-out.

Connection pool gotcha (Postgres)

DigitalOcean's built-in connection pool can run in transaction, session, or statement mode. The default transaction mode breaks LISTEN/NOTIFY — same mechanism as every other transaction-mode pooler: the framework's listener registers on a connection that gets recycled.

  • Need reactivity → connect the framework to the direct connection (25060), or create the pool in session mode and use that.
  • High connection churn → query bulk app queries through a transaction-mode pool and keep the single CDC listener on a direct connection.

Trusted sources / firewall

DO clusters default to a firewall. Add your app's droplet / k8s cluster / app-platform component to the cluster's trusted sources, or connections time out before SSL even negotiates.

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. Snapshot-but-no-updates means you're on the transaction-mode pool — move the listener to the direct connection.

See also