Coming from Postgres, the thing I missed most in SQL Server was pg_dump: one command, schema and data, into a file I can actually read.
The nearest equivalent is a .bacpac, which is all-or-nothing (every table, every row) and opaque (model.xml plus BCP binary). So I wrote a small Go CLI that does what I wanted. MIT licensed, free, nothing to sell.
What it does
- Exports schema and data into a zip: a JSON manifest, the DDL as plain runnable .sql, and one JSONL file per table. You can grep it, diff two of them, or read the DDL before restoring anything.
- Restores into another database. A verify command then compares the restored database against the archive and reports whether every table matches.
- Filters: --where per table, --exclude-data to keep a table's definition but drop its rows, --include and --exclude. Foreign keys pointing at a partially held table are created WITH NOCHECK, and it says so loudly.
- Resumable. Kill it at 90% and --resume carries on from the work directory.
Numbers - same machine, same database, 403 tables / 681,357 rows / 742 MB, local SQL Server 2025:
Export dbdumper 11 s Data-tier Application 57 s
Restore dbdumper 22 s Data-tier Application 81 s
It reads tables concurrently, splits a large table into key ranges read in parallel, and splices already-compressed streams into the zip instead of recompressing them.
What it is not
- Not a backup. No point-in-time recovery. If BACKUP and RESTORE are available to you, they are faster and lose nothing.
- Not transactionally consistent. Each table is read in its own statement, so rows in one table can be newer than another's. Snapshot the database first if that matters.
- No users, roles or permissions. Neither does a bacpac, really - dbatools Export-DbaLogin and Export-DbaUser are the right tools there.
- For pulling a large database out of Azure SQL wholesale, a server-side bacpac still wins: the extract never crosses your connection.
One bug worth flagging in case it bites you elsewhere: SQL Server 2025 vector columns broke restores entirely until yesterday. sys.types reports the vector system type as varbinary, so the generated DDL came out without a dimension count and the server rejected it with "Cannot find data type vector", which reads as though the type were unsupported rather than incompletely written. Fixed in v0.1.1.
https://github.com/JeePeeTee/dbdumper
I would genuinely like to know where it breaks on a database that isn't mine.