Supported sources
Which Postgres providers CapyDB migrates from, how each one is identified, and what each needs before a near-zero-downtime import will work.
CapyDB imports from any PostgreSQL database it can reach. There is no allowlist of providers, and a source that is not listed below is not a problem - it just gets the generic advice instead of provider-specific advice.
What the list below is actually for is the one question a migration plan turns on: can this source stream its changes? If it can, capydb import --follow copies the database while your application keeps running against the old one, and the cutover is the time it takes to swap a connection string. If it cannot, the migration is a dump and restore inside a maintenance window that grows with the size of the data.
That question is not answered by the provider's documentation. wal_level is a setting, and plenty of people have already changed it in either direction. So CapyDB measures it - capydb migrate scan and the import preflight both read the running server - and uses the table below only to explain what to do about the measurement.
Identification
Providers are identified from the server's own catalogs, not from the hostname:
- Google Cloud SQL and AlloyDB publish no public hostname at all - you connect to an address or through the Cloud SQL Auth Proxy.
- Heroku Postgres answers on an ordinary EC2 name (
ec2-….compute.amazonaws.com). - Anything behind a bastion or a private link arrives as an address.
So the probe looks for provider-owned roles (rds_superuser, cloudsqladmin, azure_pg_admin, supabase_admin, neondb_owner), provider-owned schemas (heroku_ext, Supabase's auth/storage/realtime), provider extensions (neon, supabase_vault, google_columnar_engine), provider GUC namespaces (rds.*, cloudsql.*, alloydb.*, azure.*), and aurora_version(). The report tells you which signals decided the answer, so you can argue with it.
Order matters where providers nest: an Aurora cluster carries every RDS marker, an AlloyDB instance every Cloud SQL marker, and Heroku Postgres runs on RDS underneath. The more specific answer wins, because only the specific answer's remediation works.
The matrix
| Source | Streaming import | What it needs first |
|---|---|---|
| Supabase | Available by default | Dump from the direct endpoint or the session pooler on port 5432 - the transaction pooler on 6543 cannot serve a consistent dump. See Migrate from Supabase. |
| Neon | Opt-in | Enable logical replication for the project in the Neon console. Use the direct endpoint, not a -pooler hostname. See Migrate from Neon. |
| Amazon RDS for PostgreSQL | Opt-in | Set rds.logical_replication=1 in the instance parameter group, reboot, then GRANT rds_replication TO <migration role>. See Migrate from AWS RDS. |
| Amazon Aurora PostgreSQL | Opt-in | Set rds.logical_replication=1 in the cluster parameter group and reboot the writer. Point the migration at the writer endpoint - a reader cannot create a replication slot. |
| Google Cloud SQL | Opt-in | Set the cloudsql.logical_decoding flag to on and restart the instance. The source also has to be reachable from outside your VPC, via an authorized network or a proxy. |
| Google AlloyDB | Opt-in | Set the alloydb.logical_decoding flag to on and restart the primary - the flag name differs from Cloud SQL's. AlloyDB's columnar engine and google_* extensions have no equivalent on plain Postgres. |
| Azure Database for PostgreSQL | Opt-in | Set the wal_level server parameter to logical and restart, then ALTER ROLE <migration role> WITH REPLICATION and grant it azure_pg_admin. Flexible Server; Single Server is retired. |
| PlanetScale for Postgres | Opt-in | Confirm logical replication is enabled for the branch and connect on the direct port - PSBouncer on 6432 pools transactions and cannot serve a consistent dump. |
| Heroku Postgres | Not possible | Heroku offers neither logical replication nor superuser access. Migrate with a dump and restore inside a maintenance window. See Migrate from Heroku. |
| Render | Opt-in | Enable logical replication in the database's settings and restart. Use the external connection string. See Migrate from Render. |
| Railway | Opt-in | Set wal_level=logical on the Postgres service and redeploy. Use the public proxy connection string. See Migrate from Railway. |
| DigitalOcean, Crunchy Bridge, Aiven | Available by default | Dump from the primary connection details rather than a connection pool. |
| Timescale Cloud | Opt-in | Hypertables are a timescaledb construct and CapyDB does not offer that extension, so hypertables have to become ordinary or natively partitioned tables before the data moves. |
| Self-managed PostgreSQL | Depends on your config | wal_level=logical, at least one spare replication slot and WAL sender, and the REPLICATION attribute on the migration role. |
Only PostgreSQL sources are covered. A MySQL, MariaDB or Vitess database is a different migration - the storage engine, the type system and the SQL dialect all differ - and not one CapyDB performs.
Things that block a streaming import regardless of provider
Even on a source configured for logical replication, two shapes will stop a --follow import, and both are found by the assessment:
- Tables with neither a primary key nor a replica identity. Their
UPDATEs cannot be replicated. The failure arrives partway through the migration rather than at setup, which is the worst time to find it. Add a primary key, orALTER TABLE … REPLICA IDENTITY FULL(correct, but it sends the whole previous row per change). - No free replication slot.
max_replication_slotsminus the slots already in use has to leave at least one.
Find out for your database
capydb migrate scan --source-url "$OLD_DATABASE_URL"Read-only, no account needed, and the connection string never leaves your machine. It reports which provider the server says it is, whether it can stream as connected, and what to do if it cannot - plus the physical inventory that decides how long the copy takes.
Migration assessment
Grade a migration before you commit to it - one read-only command against your database and your repository, and a report you can read in a terminal, in CI, or on a page.
Near-zero-downtime migration (follow)
Stream a live source database into CapyDB and cut over with seconds of downtime instead of a full write freeze.