All guidesCheck your own repo
On this page

Supabase question

Supabase

Do my Supabase migrations match what is live in production?

By Ohad Krispin, founder of VibeRaven · LinkedIn

Link the repo to the production project and run supabase migration list --linked, which shows each migration timestamp in a LOCAL and a REMOTE column, then supabase db diff --linked, which diffs your local migration files against the linked project. A migration missing from REMOTE was never applied, and a non-empty diff means the live schema was changed outside your migrations, for example in the dashboard.

Compare the migration history

Supabase's CLI reference says migration list shows the history of local and remote databases side by side, reading the remote side from supabase_migrations.schema_migrations, and compares timestamps only. A timestamp in LOCAL with an empty REMOTE was never applied; one in REMOTE with an empty LOCAL was applied from a file your repo does not have.

supabase link --project-ref <project-ref>
supabase migration list --linked

Find schema changes made outside migrations

Matching timestamps do not prove matching schemas: a table or policy added in the SQL editor leaves no history row. db diff builds a shadow database from supabase/migrations in a separate container and compares it with the linked project, so Docker must be running. The -f flag saves the difference as a new migration file you can review and commit.

supabase db diff --linked

# save the live changes as a migration to review
supabase db diff --linked -f capture_live_changes

Compare the policies by hand

Policies decide who reads what, so compare them on their own. Run this in the SQL editor of the production project and check each row against a create policy statement in supabase/migrations.

select tablename, policyname, roles, cmd, qual, with_check
from pg_policies
where schemaname = 'public'
order by tablename, policyname;

Fix a history that is out of sync

When a migration was applied by hand and the history table does not know it, mark it applied; when a history row has no matching change, mark it reverted. migration repair edits only the history table, not the schema.

supabase migration repair 20261001000000 --status applied
supabase migration repair 20261001000000 --status reverted

Checklist

Check migrations against production

  1. 01Link the repo to the production project with supabase link.
  2. 02Run supabase migration list --linked and note each row with one side empty.
  3. 03Run supabase db diff --linked and read every statement it prints.
  4. 04Save live-only changes you want to keep with -f, review the file, and commit it.
  5. 05Repair the history rows that are wrong with supabase migration repair.
  6. 06Run the pg_policies query and compare it with the policies in your migrations.

Related

Sources

Official docs behind this checklist

FAQ

FAQ for builders before launch

Does supabase db pull do the same thing?

It pulls the live schema changes into a new migration file under supabase/migrations, which also needs a linked project and Docker. Use diff first to see what would change, and pull when you want to adopt the live schema.

Can a repo-only check tell me what is live?

No. Reading supabase/migrations shows what the repo will create, not what the project runs. Only the linked project, through the CLI or the dashboard, shows what is live.