← All playbooks
Databases migration

Supabase → Neon

Move the Supabase public schema to Neon with pg_dump. Leave auth, storage, realtime, and internal schemas behind unless you have a separate auth plan. Legacy Neon Auth could import bcrypt hashes. Managed Better Auth cannot. Remap user ids if you move auth at all.

Typical timeline10–22 business days40–85 hours active work
Statusneeds review
Source profileSupabase Postgres connection docs reviewed 2026-10-29
Destination profileNeon complete Supabase migration guide reviewed 2026-10-29
Documentation date
Review window
Evidence3 sources
This route needs review.Use it as a planning baseline, then verify the dated sources and test with representative data before production.
Before you migrate

Should you make this move?

Both platforms have a case. Compare what you gain with what you give up before scheduling the cutover.

Current platform

Supabase

Reasons to stay
  • PostgreSQL, authentication, storage, realtime, and edge functions offer an open backend stack
  • Managed infrastructure removes a large amount of operational work
Reasons to leave
  • Production scaling and service integration still demand database and infrastructure judgment
  • Platform-specific services can create architectural lock-in
New platform

Neon

What gets better
  • Serverless PostgreSQL with branching and scale-to-zero creates excellent developer workflows
  • A mature data model and query ecosystem supports serious production workloads
What gets worse
  • Platform-specific branching, compute behavior, and pricing require workload-aware design
  • Schema design, migration, tuning, and operations require specialist attention
Best of the move

Neon: Serverless PostgreSQL with branching and scale-to-zero creates excellent developer workflows. This removes a major source-side concern: Production scaling and service integration still demand database and infrastructure judgment.

Worst of the move

What you lose: PostgreSQL, authentication, storage, realtime, and edge functions offer an open backend stack. What you inherit: Platform-specific branching, compute behavior, and pricing require workload-aware design.

Jump to a section
01At a glance

Know the shape of the move.

Transfer outcome12 features audited
Transfer outcome distributionClean transfer: 0, Partial transfer: 2, Manual rebuild: 5, Not transferred: 5.
Clean0
Partial2
Manual5
Lost5
Mapping route9 of 9 fields have a destination path

This timeline assumes

  • You are moving application data in public (and other schemas you own). Neon says auth, storage, realtime, and internal schemas are not a straight copy.
  • Neon’s 2026 guide still documents legacy Neon Auth for password-hash import. New Neon projects use Managed Better Auth, which cannot import Supabase password hashes. Those users create new accounts or use OAuth.
  • Dump and restore use a direct Supabase connection on port 5432, not the transaction pooler on 6543.
  • If you migrate auth, Neon says user_id values are reassigned and you must remap foreign keys.
  • Supabase stays recoverable until Neon has passed one application cycle.
02What transfers

What survives the move.

“Partial” and “manual” are not footnotes. They are work that must be scheduled and verified.

ItemOutcomeImpactWhat happensMitigation
public schema datapartialcriticalTables, indexes, constraints, sequences, views, and functions in public can dump and restore. That is the part Neon treats as portable.Dump only the schemas you own. Restore to Neon. Compare counts and foreign keys.
auth schema and usersmanualcriticalauth.users does not become Neon Auth by restore. Legacy Neon Auth could import email plus bcrypt hashes. Managed Better Auth cannot import those hashes.Decide auth before cutover. If you stay on Better Auth, plan password resets or OAuth. If you still have legacy Neon Auth, follow Neon’s hash import and then remap ids.
User id remappingmanualcriticalNeon says auth import assigns new user_id values. Rows in public that store Supabase user ids will point at the wrong person until you remap.Build a map from old id to new id and rewrite every user-keyed table before you open writes.
RLS policiespartialcriticalPolicies that call auth.uid() or Supabase roles do not mean the same thing on Neon until roles and auth functions exist.Rewrite policies against the Neon auth model you actually use. Test as a normal user, not as the restore role.
Storage objectslosthighstorage.objects metadata is not your files. Buckets stay in Supabase until you copy bytes to Neon-compatible storage or another bucket.Inventory buckets and copy objects with a tool that preserves paths you still reference.
Realtime, Edge Functions, and cronlosthighThose products do not restore from pg_dump.Replace them with Neon-side jobs, workers, or a separate queue before cutover.
Supabase roles and Data APImanualcriticalanon, authenticated, and the Data API are Supabase. Neon has its own roles and, if you enable it, a Data API.Create the roles your policies need and do not expose a wide API until RLS is rewritten.
Internal Supabase schemaslostmediumDumping everything including auth, storage, and realtime internals usually breaks a restore on Neon.Exclude those schemas from the production dump.
Transaction pooler dumpsmanualhighpg_dump over port 6543 is a common failure.Use the direct 5432 connection for dump and restore.
Password hashes on Better AuthlostcriticalNeon states Managed Better Auth cannot import Supabase password hashes.Tell users they will reset passwords or sign in with OAuth. Do not claim silent password reuse.
Supabase backups and PITRlostmediumThose backups stay in Supabase.Keep your own pg_dump and turn on Neon backups before traffic moves.
Connection strings and clientsmanualcriticalEvery server, edge function, and local .env still pointing at Supabase will split writes.Inventory every URL and switch them in one change window.
03Field and feature mapping

Where each thing goes.

SourceDestinationMethodNotes
public tablesNeon public tablestransformDump only owned schemas.
auth.usersNeon Auth or a new auth storemanualBetter Auth cannot take bcrypt hashes.
Supabase user idRemapped Neon user idtransformRewrite every FK after auth import.
RLS policy using auth.uid()Rewritten Neon policymanualTest as a normal user.
storage bucketNew object storemanualCopy bytes, not only metadata.
Direct 5432 URLpg_dump sourcetransformDo not use 6543.
SequencesRestored sequencestransformInsert a row and check the next value.
Edge Functions / cronReplacement workersmanualNothing in the dump starts them.
Application DATABASE_URLNeon URL after verificationmanualSwitch every consumer.
04Before you begin

Make the move recoverable.

Backup procedure

Create the source-of-truth backup

Keep a schema-scoped dump and an auth decision before you touch Neon.

  1. List public tables, user-keyed foreign keys, buckets, functions, and cron jobs.
  2. Decide legacy Neon Auth versus Managed Better Auth versus an external IdP.
  3. Dump owned schemas from the direct 5432 endpoint.
  4. If you still use legacy Neon Auth, export emails and bcrypt hashes with the function Neon publishes.
  5. Hash the dump and store it read-only.

Proof to capture: A dated manifest lists schemas, dump hash, auth path, and bucket inventory.

Transformation · pg_dump with -n public (and other owned schemas)

Schema-only dump

Avoid restoring Supabase internals onto Neon.

  1. Use the direct URL.
  2. Exclude auth, storage, and realtime unless you have a written exception.
  3. Restore into an empty Neon database.

Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.

Transformation · A mapping table plus UPDATE statements

Auth remap

Stop user-keyed rows from pointing at new random ids.

  1. Import users only on the auth product that can accept them.
  2. Build old_id → new_id.
  3. Rewrite every user-keyed table and then drop the map from production if you do not need it.

Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.

05Handle with care

The things most likely to hurt.

These are operating limits. Treat every “Stop if” condition as a blocked migration, not a suggestion.

Cutover

User ids are not remapped

criticalpossible likelihood

Auth import succeeded and public rows still store Supabase uuids.

Consequence
Users see the wrong data or none.
Mitigation
Remap every user-keyed table before you open writes.

Stop if: A production row still points at a Supabase user id after auth import.

Planning

Better Auth cannot take hashes

criticalpossible likelihood

The Neon project is on Managed Better Auth and the plan assumed silent password import.

Consequence
Nobody can sign in with their old password.
Mitigation
Plan resets or OAuth, or keep an IdP that already holds the users.

Stop if: Password login is required and hashes cannot be imported.

Backup

Dump used the transaction pooler

highpossible likelihood

pg_dump points at port 6543.

Consequence
The dump is incomplete or fails.
Mitigation
Use port 5432 for dump and restore.

Stop if: The dump was taken through the transaction pooler.

06Precise timeline

Do the work in this order.

Estimate forOne Supabase project moving public data to Neon, with auth handled as a separate signed decision
Total elapsed10–22 business days
Active work40–85 hours
BufferAdd time for auth remaps, storage copies, or many Edge Functions.
01
Days 1–4Inventory and auth decision2–4 days
02
Days 3–6Dump1–3 days
03
Days 6–14Restore and remap5–9 days
04
Days 14–18Freeze and switch1–3 days
05
Days 17–22Observe and close4–6 days
  1. Days 1–4 · inventory

    Inventory and auth decision

    8–14 hours active2–4 days elapsedAuth and storage owners waiting
    • List schemas, user FKs, buckets, and jobs.
    • Sign the auth path.
    • Pick dump schemas.

    Depends on: Supabase and Neon admin access

    Stop / go checkpoint

    Dump?

    Go when: Auth path and schema list are signed.

    Stop when: Password login is required and no hash path exists.

  2. Days 3–6 · backup

    Dump

    4–8 hours active1–3 days elapsedDump runtime waiting
    • Dump owned schemas from 5432.
    • Export hashes only if legacy Neon Auth is in play.
    • Hash files.

    Depends on: Approved inventory

    Stop / go checkpoint

    Restore?

    Go when: Dump hashes and counts look complete.

    Stop when: The dump includes internals you cannot restore.

  3. Days 6–14 · pilot

    Restore and remap

    16–36 hours active5–9 days elapsedAuth import waiting
    • Restore to a Neon branch.
    • Import users if the auth product allows it.
    • Remap ids, rewrite RLS, copy a storage sample.

    Depends on: Verified dump

    Stop / go checkpoint

    Cut over?

    Go when: Counts, logins, and RLS pass.

    Stop when: A user-keyed table is unmapped.

  4. Days 14–18 · cutover

    Freeze and switch

    6–16 hours active1–3 days elapsedWrite freeze waiting
    • Pause Supabase writes.
    • Dump and restore production.
    • Remap ids and switch URLs.

    Depends on: Passed pilot

    Stop / go checkpoint

    Open writes?

    Go when: Neon is the only writer and logins work as planned.

    Stop when: A FK still stores a Supabase user id.

  5. Days 17–22 · observe

    Observe and close

    6–11 hours active4–6 days elapsedApplication cycle waiting
    • Watch auth, RLS, and jobs.
    • Keep the Supabase project.

    Depends on: Verified cutover

    Stop / go checkpoint

    Close rollback?

    Go when: No trigger fires through one cycle.

    Stop when: Auth or data access regresses.

07The point of change

Cut over with a way back.

Go live

Cutover

Make Neon the only writable application database after a frozen, remapped restore.

Recommended window: A write freeze long enough for dump, restore, and remap.

  1. Pause Supabase writes and cron.
  2. Dump owned schemas from port 5432.
  3. Restore to Neon and remap user ids if auth moved.
  4. Rewrite RLS and switch every DATABASE_URL.
  5. Keep Supabase recoverable.

Proof to capture: Neon serves the app. Counts match. Logins follow the signed auth path. No writer remains on Supabase.

Return to safety

Rollback

Return writes and login to Supabase without losing reviewed Neon-era rows.

Deadline: Before you delete the Supabase project or its backups.

  1. Stop writes to Neon.
  2. Point the app and auth at Supabase.
  3. Export Neon rows written after cutover.
  4. Apply only reviewed rows to Supabase.
  5. Run the same login and data checks on Supabase.

Proof to capture: Supabase is writable again and Neon is not receiving production writes.

Rollback immediately when
  • Unmapped user id
  • Password login broken
  • RLS failure
  • Dump taken through 6543
  • Missing public table
08Verification report

Prove the migration worked.

Every blocking check must pass. Capture the evidence before cleanup begins.

0%
Interactive report preview0 / 8 checks passed
PassIDCheckMethodExpected resultEvidence
V-01BlockingOwned schemas onlyInspect pg_dump args and the archive TOC.auth, storage, and realtime internals are absent unless signed.Dump TOC.
V-02BlockingRow counts and FKsCompare public counts and foreign-key totals.Every scoped table matches or has a signed exception.Count sheet.
V-03BlockingSigned login pathSign in with password and OAuth for a seed user.The result matches the Better Auth, legacy, or external plan.Login log.
V-04BlockingUser id remapJoin a user-keyed table to the mapping table.No production row still stores a Supabase user id after auth import.Remap query.
V-05BlockingRLSQuery as a normal user and as a denied user.Policies match the Neon auth model.Policy test.
V-06BlockingStorage sampleOpen representative objects from the new store.Required bytes exist at the referenced paths.Object manifest.
V-07BlockingPort 5432Inspect dump and restore URLs.No transaction pooler 6543 on dump/restore.Config audit.
V-08BlockingSupabase still upPoint a staging app at Supabase.The old URL still works.Rollback note.
09Post-migration cleanup

Remove the scaffolding safely.

Safe after: One application cycle, Neon backups on, and seven stable days.

  1. Archive the dump, hash file, and remap SQL.
  2. Revoke temporary Supabase dump roles.
  3. Keep Supabase until billing and rollback close.
  4. Remove unused Data API keys.
  5. Document the Neon URL and auth product.
  6. Schedule the next backup and RLS review.
10Experiences from the field

When the plan met reality.

First-hand accounts are preferred. Vendor case studies are labeled, and every note below is an editorial paraphrase—follow the link for the full context.

First-person accountShreyash Raj · Medium

How I Migrated Quaslation's Database from Supabase to Neon2025

Shreyash Raj moved Quaslation from Supabase Postgres to Neon for branching, serverless cost, and hosting control. He documented tables first, exported each table to JSON in foreign-key order, imported with session_replication_role = replica, reset sequences, and verified counts. A pg_dump of Supabase sat behind hot, staged, and partial rollback plans. The final npm run db:migrate:full export, import, and verify step is what he ran after a staging rehearsal.

What they recommend
  • Export tables in dependency order and disable triggers during import, then reset sequences before you open writes.
  • Rehearse on a Neon branch and keep a Supabase pg_dump so a hot rollback is a connection-string change.
Worth noticing
  • Same-engine Postgres still needs an ordered import. Foreign keys will stop a naive load.
  • The destination win was Neon branching and cost, not a different SQL dialect.
Sources and evidence

Verify against the primary material.

Platform behavior changes. Check these sources and the review dates above before executing a production migration.

  1. Neon: migrate Supabase database and authAccessed 2026-10-29
  2. Supabase: connecting to PostgresAccessed 2026-10-29
  3. PostgreSQL: SQL dumpAccessed 2026-10-29