Open-source enterprise-class CDC for MySQL ↔ Postgres — plus SQLite & Cloudflare D1

Migrate and continuously sync databases between MySQL and Postgres in all four directions — initial snapshot, CDC catch-up, and operator-driven cutover in one tool, opinionated about correctness. SQLite files and live Cloudflare D1 databases import into Postgres or MySQL too, and SQLite is also a migrate target.

$ go install sluicesync.dev/sluice/cmd/sluice@latest

sluice sync start — MySQL → Postgres, live. See every command in action →

What you get

Schema-evolution, cutover-priming, and slot-health capabilities usually found only in commercial/enterprise CDC tools — Apache 2.0, a single static binary, no daemon, no SaaS dependency.

🔄 Bidirectional

MySQL → Postgres, Postgres → MySQL, and same-engine in both directions. PlanetScale and self-hosted Vitess flavors included.

🗃️ SQLite & Cloudflare D1

Import a SQLite file or a wrangler d1 export .sql dump (--source-driver sqlite), or read a live D1 over its HTTP query API (--source-driver d1), into Postgres or MySQL — big integers above 253 round-trip exactly. SQLite is also a migrate target; sqlite-trigger / d1-trigger add trigger-based continuous sync.

🗂️ Multi-database / multi-schema

Move a whole MySQL server's databases or a Postgres source's schemas in one run with --all-databases / --all-schemas (each to a same-named, auto-created target namespace), or fan into one schema with --target-schema — on both migrate and sync start.

🌐 WAN-fast MySQL apply

Cross-region / PlanetScale-MySQL CDC apply folds consecutive same-shape INSERTs into one multi-row statement and coalesces UPDATE / DELETE batches, turning N round trips into one so high-latency apply keeps up.

🔌 Slot-less Postgres sources

Managed Postgres that blocks logical replication (e.g. Heroku) still streams via a trigger-based CDC engine — no replication slot or REPLICATION role required.

🪶 Schema evolution

ADD COLUMN forwards automatically; every other shape refuses loudly with a structured drift diff naming the column that changed.

🩺 Operational telemetry

Pre-emptive slot-health warnings, a source-side heartbeat writer, and a Prometheus /metrics + /readyz endpoint for k8s health checks.

🔁 One-command cutover

sluice cutover primes sequences so the first post-cutover INSERT can't collide on the primary key.

🛑 Loud failure by default

Every silent-loss class has a structured refuse-loudly message with an operator-action recovery hint. Paste it into Slack and the on-call DBA knows what to fix.

Quick start

Install the binary, then run a one-shot migration or start a resumable continuous sync.

# Install
go install sluicesync.dev/sluice/cmd/sluice@latest

# One-shot migration: MySQL → Postgres
sluice migrate \
    --source-driver mysql    --source 'root:rootpw@tcp(localhost:3306)/app' \
    --target-driver postgres --target 'postgres://postgres:pgpw@localhost:5432/app?sslmode=disable'

# Continuous sync: snapshot + CDC catch-up, resumable on restart
sluice sync start \
    --source-driver mysql    --source ... \
    --target-driver postgres --target ... \
    --stream-id myapp-prod

# Cutover-time sequence priming (post-snapshot, pre-traffic-switch)
sluice cutover --config sluice.yaml --cutover-sequence-margin=1000

# Import a SQLite file (or a `wrangler d1 export` .sql dump) → Postgres
sluice migrate \
    --source-driver sqlite   --source ./app.db \
    --target-driver postgres --target 'postgres://...?sslmode=disable'

# Import a LIVE Cloudflare D1 → Postgres (token via CLOUDFLARE_API_TOKEN)
sluice migrate \
    --source-driver d1       --source 'd1://<account_id>/<database_id>' \
    --target-driver postgres --target 'postgres://...?sslmode=disable'

Three surfaces, independently runnable

sluice is built around three product surfaces — use one, or all three end to end.

Migrate

Schema & data

Read source schema, create target tables, bulk-copy rows, then build indexes and constraints — deferred for fast copy, resumable per-table. Many databases / schemas in one run, including SQLite files and live Cloudflare D1.

Sync

Change data capture

Snapshot → CDC handoff with resumable checkpoints, schema-drift detection, and slot-health telemetry against quiet sources.

Operate

Run as a service

Long-running sync behind /healthz, /readyz, and /metrics, or one-shot jobs in CI and CronJobs via the container image.