Voltro + CockroachDB
CockroachDB is Postgres-wire-compatible but not 100% feature-compatible — what works, what may not pass Voltro's pg DDL, and how to test before you commit.
CockroachDB speaks the Postgres wire protocol, so you set DB_DIALECT=postgres and the driver connects. But wire-compatible is not feature-compatible — Cockroach implements a subset of Postgres semantics with some deliberate differences. Treat this as supported with caveats, not a drop-in like RDS or Supabase.
Connect
DB_DIALECT=postgres
DB_URL=postgresql://[USER]:[PASSWORD]@[CLUSTER].[REGION].cockroachlabs.cloud:26257/[DB]?sslmode=verify-fullCockroachDB Cloud uses port 26257 and requires TLS (sslmode=verify-full with the cluster CA, or require as a weaker baseline).
Reactivity — no native CDC, cross-instance via the broadcast bus
Be blunt up front: CockroachDB does not support LISTEN/NOTIFY at all, and Voltro's native Postgres CDC is built on LISTEN/NOTIFY. So there is no native cross-instance path on CockroachDB — you can't "enable" the LISTEN/NOTIFY CDC here, because the mechanism doesn't exist on this backend.
What this means concretely:
- The SQL surface (schema DSL, queries, mutations,
ctx.store) works against Cockroach's Postgres-wire compatibility, modulo the DDL caveats below. - Within a single instance, reactivity works via inline emit: the writing process pushes its own writes to its subscribers.
- For cross-instance reactivity, add
@voltro/plugin-broadcast(Redis / NATS). The bus fans out each app-mutation change event to every replica — closing the gap LISTEN/NOTIFY can't fill on Cockroach. This is the right path when you want CockroachDB's distributed SQL AND multi-replica reactivity. - CockroachDB does have its own change feed (
CHANGEFEED), but Voltro does not consume it — there is no adapter wiring Cockroach CHANGEFEEDs into the dispatcher. The broadcast bus is the supported cross-instance mechanism.
// app.config.ts
import { broadcastPlugin } from '@voltro/plugin-broadcast'
export default { type: 'api' as const, name: 'api', plugins: [broadcastPlugin()] }
// BROADCAST_URL=redis://… (or nats://…)Caveat: the bus carries app-mutation changes (writes through ctx.store), not out-of-band DB writes — see Multi-replica reactivity. If you need out-of-band-write reactivity, a stock-Postgres provider (Supabase, Neon, AWS RDS) with native LISTEN/NOTIFY is the right choice.
What to verify before committing
Cockroach diverges from stock Postgres in ways that can affect Voltro's emitted DDL and runtime path. Test a full voltro migrate + a few subscriptions against a real cluster before you build on it:
LISTEN/NOTIFYis NOT supported (covered above) — the single biggest reason Cockroach is "supported with caveats" rather than a drop-in.- DDL differences. Cockroach's
CREATE TABLE/CREATE INDEX/ FK handling, sequence behavior (BIGSERIAL), and some constraint forms differ. Voltro's migrator targets stock Postgres DDL; some statements may need adjustment or may not apply cleanly. - Advisory locks. Cockroach's advisory-lock support differs from Postgres, which affects the cluster workflow runner's shard-ownership primitive.
- Transaction semantics. Cockroach is serializable-by-default with retry-on-contention; the framework's
transactional()retry filter is tuned for Postgres error codes (40001/40P01) — Cockroach uses40001too, so that part overlaps, but verify under load.
Recommendation
If you need CockroachDB's distributed/multi-region story specifically, run a spike: voltro migrate against a cluster, exercise your mutations + subscriptions, and watch voltro logs for DDL or CDC errors. If you primarily want a managed Postgres with Voltro's full reactive surface, a true Postgres provider (Supabase, Neon, AWS RDS) is the lower-risk choice.
Verify
A successful connect logs the postgres dialect — but note CDC:
[voltro:dev] sql dialect resolved: postgres — CDC: LISTEN/NOTIFY, RETURNING: nativeIf subscriptions never deliver updates, LISTEN/NOTIFY isn't available on this backend (expected on Cockroach) — run with CDC=0 for single-process inline emit, add @voltro/plugin-broadcast for cross-instance reactivity, or move to a stock-Postgres provider for native LISTEN/NOTIFY.
See also
- Postgres dialect — what "full Postgres" actually requires.
- Multi-replica reactivity — cross-instance change fan-out via
@voltro/plugin-broadcast.