Cosmovex Tools

Compare two pg_dump schema files and get the migration between them

Compare pg_dump files with Schema Diff Studio

Two pg_dump --schema-only files are loaded: production and a staging database that has drifted. Both are full dumps with SET lines, OWNER TO and GRANT statements, sequences and separately added constraints. The comparison runs on load, sets the dump boilerplate aside in a visible list, and shows every real difference per table with the migration that brings production to staging, verified in Postgres in your tab.

  1. Dump the schema of each database: pg_dump --schema-only --no-owner --no-privileges -d prod_db > prod.sql, and the same for staging. Without those two flags the output works too; the extra lines are just set aside.
  2. Paste prod.sql into Before and staging.sql into After, or use the Open file button above each editor to load the .sql files.
  3. Press Compare. Above the results, a note lists what was set aside (SET, OWNER TO, GRANT, psql commands) so you can see nothing was silently ignored.
  4. Read the Changes tab per table: here a changed default, two new columns, a CHECK constraint, a partial index, a foreign key whose ON DELETE changed, and a new view.
  5. Open Migration for the script that brings Before to After, check Verified, and copy it. Downloading it as .sql and the full rollback script are Pro.
compare two postgres schemas pg_dump schema diffcompare pg_dumppostgres schema compare toolcompare staging and production database schemapostgres schema diff online
Open Schema Diff Studio Free · Pro $29 one-time · no account

What to know

A plain diff -u of two pg_dump files is noisy. pg_dump prints objects in a stable order, but a column added in one database appears in the middle of a CREATE TABLE, constraints are added in separate ALTER TABLE ONLY statements far from their table, and a different pg_dump version changes the header, the SET lines and sometimes the formatting of expressions. A line diff tells you that text differs; it does not tell you that tasks.priority's default went from 2 to 3 or that a foreign key now cascades.

Here each dump is executed in a fresh Postgres in your tab and compared through the catalog. Expressions are compared as Postgres normalises them, so CHECK (priority >= 1 AND priority <= 5) and the double-parenthesised version pg_dump prints are the same constraint. Serial-style columns made of a sequence plus a SET DEFAULT nextval(...) are recognised as one column default. Ownership and privileges are not part of the comparison; if you need GRANT drift, compare the \dp output separately.

pg_dump releases from August 2025 onwards (17.6, 16.10 and the other branches of that update) write \restrict and \unrestrict lines with a random key into plain-format dumps. Those are psql meta-commands, so two dumps of the same schema never match as text. Like every other psql line, they are set aside and listed here, so they do not affect the comparison.

The usual uses are drift checks (staging against production before a release, or a replica built by hand against its source) and reviewing what a framework's migrations actually did: dump before, run the migrations, dump after, compare. Only the schema is involved. --schema-only output has no rows, and nothing you paste leaves the browser.

Updated · Cosmovex

Questions

How do I compare two Postgres database schemas?

Dump each one with pg_dump --schema-only (add -n public to limit it to a schema), paste the two files into Before and After, and press Compare. You get the differences per table and the ALTER script that turns the first schema into the second, verified by running it.

Why does diff show differences between two dumps of identical schemas?

Different pg_dump versions write different headers and SET lines, recent versions add a random \restrict key, and owners or privileges may differ. This tool sets all of that aside and compares the schema objects themselves, so identical schemas report "No changes".

Is this an alternative to apgdiff or migra?

It does the same job of turning two schemas into an ALTER script, without installing anything: the dumps run in Postgres compiled to WebAssembly in your browser. It also runs the generated migration against your Before schema and confirms it produces After. It compares pasted DDL, not live database connections.

Can I compare against a live database instead of a dump?

Not directly; the tool never connects to a database. Run pg_dump --schema-only against the live database and paste the output. That keeps credentials and data off the page entirely.

Are extensions like PostGIS supported?

The in-browser Postgres cannot load every extension. If a dump creates something that needs one it does not have, the error names the statement, and you can remove that object from both dumps to compare the rest.

The free plan covers everything on this page. Schema Diff Studio Pro ($29, paid once) is described on the Schema Diff Studio page.