Voltro + Railway

Deploy Voltro on Railway with managed Postgres or MySQL — public vs private network connection strings, the DATABASE_URL variable, SSL, and full LISTEN/NOTIFY reactivity.

Railway offers managed Postgres and MySQL plugins, mapping to Voltro's postgres and mysql dialects respectively. Railway provisions a plain, single-instance database with no transaction pooler in front of it — so on Postgres you get the full reactive surface (LISTEN/NOTIFY CDC, advisory-lock workflows, JSONB) with no pooling caveat.

Connect

Railway injects a DATABASE_URL variable into services in the same project. Prefer the private network URL (*.railway.internal) for service-to-database traffic — it avoids public egress and the associated SSL requirement.

# Postgres — private network (recommended in-project)
DB_DIALECT=postgres
DB_URL=postgresql://postgres:[PASSWORD]@[SERVICE].railway.internal:5432/railway
# Postgres — public proxy (for connecting from outside Railway)
DB_DIALECT=postgres
DB_URL=postgresql://postgres:[PASSWORD]@[HOST].proxy.rlwy.net:[PORT]/railway?sslmode=require
# MySQL plugin
DB_DIALECT=mysql
DB_URL=mysql://root:[PASSWORD]@[SERVICE].railway.internal:3306/railway

For the MySQL dialect, note the cross-dialect differences the framework handles for you: no RETURNING (INSERT-then-SELECT), inline-only CDC (single-instance reactivity, not the native cross-instance LISTEN/NOTIFY), and 0/1 booleans. See the MySQL dialect page.

Enabling CDC

On Postgres, Voltro's change-data-capture is LISTEN/NOTIFY, on by default (CDC=1) — no extension, no flag. Railway runs a plain single-instance Postgres with no transaction pooler in front, so DB_URL already points at a session-mode connection and reactivity works the moment you connect. Nothing to configure. (On the MySQL plugin, CDC is inline-only / single-instance — see the dialect note below.)

Pooling / SSL

  • No pooler by default. Postgres reactivity works directly — nothing to configure for LISTEN/NOTIFY.
  • SSL: the private network URL runs over Railway's internal network and typically doesn't need sslmode=require. The public proxy URL does — append ?sslmode=require.
  • Connection limits: bounded by the plan's Postgres instance size; scale the instance up if you outgrow it. (The framework opens one pool per process; cap its size per process with DB_MAX_CONNECTIONS — maps to the postgres max, mysql connectionLimit, and mssql pool.max.)

Verify

Postgres:

[voltro:dev] sql dialect resolved: postgres — CDC: LISTEN/NOTIFY, RETURNING: native
[voltro:dev] workflow engine: cluster-sql, dialect=postgres

MySQL:

[voltro:dev] sql dialect resolved: mysql — CDC: inline only (no binlog CDC), RETURNING: INSERT/UPDATE/DELETE then SELECT (no RETURNING)
[voltro:dev] workflow engine: cluster-sql, dialect=mysql, runnerStorage=sql

Confirm with voltro logs --tail 50.

See also