Skip to content

Migrate from Neon

Neon is “just Postgres”, so migrating into an AnvilBase project is a filtered pg_dump/restore into the project’s own database. AnvilBase gives you the Neon-style capabilities you came for — branching, read replicas, and scale-to-zero — on your own stack.

No inbound live replication. AnvilBase does not ship the subscriber side of logical replication (CREATE SUBSCRIPTION; see Logical Replication → Subscriptions), and runs no superuser. Plan a write-freeze window for cutover — this is dump/restore, not a zero-downtime live sync.

1. Create the target project

Terminal window
anvilbase projects create "My App"
# capture id, anon_key, service_role_key, jwt_secret

2. Move the schema

Neon uses its own bootstrap roles (neon_superuser, the project owner role) and may enable extensions AnvilBase does not bundle. Dump without owners/privileges and filter to the schemas you own:

Terminal window
pg_dump --schema-only --no-owner --no-privileges \
--schema=public \
"postgresql://<user>:<pw>@<endpoint>.neon.tech/<db>?sslmode=require" \
> 001_schema.sql
# Strip role grants / extensions the owned image does not ship; check the
# bundled set in docs/database/extensions.md
grep -vE '^(GRANT |ALTER .* OWNER TO |CREATE EXTENSION (pgsodium|pgjwt))' \
001_schema.sql > 001_schema.clean.sql
anvilbase db push --project <id> --path ./migrations --apply

Each file applies as the non-superuser anvilbase role in a single transaction — the first unsupported statement rolls the whole file back. Keep the dump to your own schemas + bundled extensions.

3. Move the data

Terminal window
pg_dump --data-only --no-owner --schema=public \
"postgresql://<user>:<pw>@<endpoint>.neon.tech/<db>?sslmode=require" \
> data.sql
# platform DB name strips the hyphens from the project UUID
psql "postgres://anvilbase:…@localhost:39432/platform_<project_id_without_hyphens>" \
--single-transaction -v ON_ERROR_STOP=1 -f data.sql

If your Neon app used Neon Auth / Stack Auth or another auth system with a users table referenced by your data, import those users first (see the Supabase guide’s lossless user import pattern — the same POST /api/v1/projects/{id}/users/import endpoint applies) so foreign keys resolve.

4. Repoint the client

Point your Postgres/HTTP client at the AnvilBase project (REST at /v1/<project_id>, direct SQL at platform_<project_id_without_hyphens>). Neon branches map to AnvilBase database branches.

5. Cut over

  1. Freeze writes on Neon (maintenance window).
  2. Re-dump changed tables (incremental) or rely on a pre-arranged dual-write.
  3. Verify health + a few reads/writes.
  4. Flip the client config / DNS.
  5. Keep the Neon project until confident, then decommission.

Checklist

  • Schema dump filtered + pruned + applied.
  • Referenced users imported first (if applicable).
  • Data loaded in a single transaction; row counts match.
  • Client repointed; branches remapped.
  • Cutover with a write-freeze window; smoke test passed.