mrkeyoor.com_
Tue 01 Sept 17:40 UTC
Dataevaluationupdated 30 Aug 2026

dbmate review

Dbmate is a standalone database migration command that lets teams keep schema changes in timestamped plain SQL files. It gives services written in different languages one shared way to create databases, apply or roll back migrations, track status, and save a schema dump.

+24 / 2dstars / 7d
Verdict

Our Dbmate build succeeded in 83 seconds, but 5 of 17 test groups failed and the log tail identified SQLite dump and FTS5 cases, so SQLite teams should reproduce the suite before adopting it. Dbmate remains a good fit for polyglot teams that want plain SQL, one small CLI, and Git-visible schema dumps. Avoid it when you need generated rollbacks, declarative schema planning, or nontransactional multi-step migrations with stronger recovery semantics.

We ran it

Lab card: what happened when we ran dbmateScreenshot of dbmate (github.com/amacneil/dbmate)
Install✓ · 59s356 packages
Build✓ · 83s
Tests✗ · 16s12 passed · 5 failed of 17 (go test)
Repo88 files~8,622 lines of source · 0.6 MB · 4 CI workflows · Dockerfile

Answers from our run

Does dbmate build from source?

Dependencies installed in 59 seconds (356 packages), and the build succeeded in 83 seconds. We cloned commit b735560 into a clean Debian container with 3 CPUs and no project-specific setup.

Do dbmate's tests pass?

Not all of them: 12 of 17 passed and 5 failed when we ran the project's own test command (go test). Some failures need services or credentials a bare container does not have.

Who should not use dbmate?

Teams requiring a green source test run in a fresh Debian environment: our run ended with 12 passed and 5 failed test groups, including two named SQLite failures.

What are the alternatives to dbmate?

golang-migrate, Goose, Atlas. Our Dbmate build succeeded in 83 seconds, but 5 of 17 test groups failed and the log tail identified SQLite dump and FTS5 cases, so SQLite teams should reproduce the suite before adopting it.

Setup4/5Many install routes, but source setup resolved 356 packages
Docs5/5Commands, drivers, transactions, dumps, and limits are explicit
Community4/57,267 stars and active August 2026 issue and PR work
Maturity3/5v2.35.1 is current, but our source tests were not green

Discussed on

  1. hnDbmate: A lightweight, framework-agnostic database migration tool79 points
  2. hnShow HN: A lightweight, framework-agnostic database migration tool3 points

Who it’s for

Polyglot teams that want one migration format across Go, Node.js, Python, Ruby, PHP, Rust, or C++ services.
Developers who prefer plain SQL over a framework-specific schema language.
Projects using PostgreSQL, MySQL, MariaDB, SQLite, ClickHouse, BigQuery, or PostgreSQL-dialect Spanner.
Go applications that want to call the library directly or embed migration files in the application binary.

Who it’s NOT for

Teams requiring a green source test run in a fresh Debian environment: our run ended with 12 passed and 5 failed test groups, including two named SQLite failures.
Users who assume rollback SQL is generated automatically: the README says Dbmate cannot roll back unless each migration supplies a migrate:down section.
Spanner projects using GoogleSQL or requiring schema dumps: the documented support is PostgreSQL dialect only, and schema dumping is unavailable.
Operators who cannot install pg_dump, mysqldump, or sqlite3: Dbmate can silently skip automatic schema dumps when the matching client is absent.
ClickHouse users relying on atomic multi-section migrations: open issue 675 reports partial application and rollback-order problems on a nontransactional path.

Setup reality

Our sandbox install succeeded in 59 seconds and resolved 356 packages. The build succeeded in 83 seconds. Tests failed with exit code 1 after 16 seconds: Go test reported 12 passed and 5 failed out of 17. The log tail named TestSQLiteDumpSchema and TestSQLiteFTS5Available.

Using Dbmate needs a database URL, usually through DATABASE_URL or a .env file. BigQuery needs Google application credentials, while Spanner needs PGAdapter. Schema export also needs the matching pg_dump, mysqldump, or sqlite3 executable in PATH.

Prebuilt binaries, npm, Homebrew, Scoop, and a container image avoid the 83-second source build. Database-specific transaction rules still apply. The repository has a Dockerfile, a compose file, 4 CI workflows, and no top-level tests directory.

Plain SQL gives polyglot teams one migration format

Dbmate keeps database changes in timestamped SQL files instead of tying them to an application framework. A Go service and a Python service can use the same command, directory layout, and schema history. The tool creates migrations, applies pending files in numeric order, records their versions, reports status, rolls back the latest change, waits for a server, and writes a complete schema.sql file for review or fast test setup.

Our checkout had 88 files, about 8,622 lines of source, and occupied 0.6 MB. That compact source tree supports PostgreSQL, MySQL, MariaDB, SQLite, ClickHouse, BigQuery, and PostgreSQL-dialect Spanner paths described in the README. Dbmate is also a Go library, and Go's embed package can place migration files inside an application binary. The command remains the simpler choice when several application languages share a database workflow.

Timestamp versions reduce branch collisions but do not prevent them

Migration filenames begin with a numeric version, normally a timestamp, followed by a description. Dbmate stores only that leading number in its migrations table. Renaming the descriptive part is safe, but changing an already-applied migration is not: the README tells users to roll it back first. Pending files run in numerical order, and the optional strict mode fails when a migration would be applied out of sequence.

The default behavior permits an older pending migration to run after newer ones when branches land out of order. Timestamp versions reduce the chance of two developers choosing the same number, yet they cannot determine whether independently written SQL remains valid in a changed schema. Teams should enable strict mode in CI and settle migration conflicts during review. The tool supplies ordering and bookkeeping; it cannot prove that two branches made compatible database decisions.

What happened when we ran it

Our sandbox installed 356 packages in 59 seconds, then built Dbmate in 83 seconds. The test step exited with code 1 after 16 seconds. Go test reported 12 passed and 5 failed out of 17. The final log lines showed successful packages for dbutil, BigQuery, ClickHouse, MySQL, and PostgreSQL before failures in the SQLite driver.

The SQLite tail named TestSQLiteDumpSchema and TestSQLiteFTS5Available, and the driver package failed after 2.265 seconds. The supplied log does not show enough evidence to assign a cause, so we will not blame a missing system package or a code defect. The useful result is narrower: commit b735560 did not pass its full test command in our fresh unprivileged Debian container with 3 CPUs and 8 GB of RAM.

Schema dumps silently depend on external client programs

Running up, migrate, or rollback normally refreshes db/schema.sql. Dbmate recommends committing that file so reviewers can see the complete resulting schema and test environments can load it without replaying every migration. The dedicated dump command can also pass extra arguments to PostgreSQL or MySQL dump utilities. This is valuable, but it is not implemented entirely inside the standalone binary.

Schema export requires pg_dump, mysqldump, or sqlite3 in PATH. The README says automatic dump steps can be silently skipped when the required program is missing; running dbmate dump exposes the executable-not-found error. That deserves a CI assertion because a successful migration command does not guarantee that schema.sql was refreshed. Client versions should also be at least as new as the database server version, according to the setup guide.

Database URLs are simple until driver rules diverge

Most installations pass DATABASE_URL directly or load it from .env. Credentials with special characters must be URL encoded. PostgreSQL defaults to TLS and may need sslmode=disable for local development. SQLite paths are local files, while some PRAGMA changes require transaction:false. ClickHouse supports native TCP and HTTP variants, plus cluster-related URL settings. BigQuery uses application default credentials unless connected to an emulator.

Spanner is narrower than the database list suggests. Only its PostgreSQL dialect is supported, PGAdapter must be running, DDL migrations require transactions to be disabled, and schema dumps do not work. That is enough for a specific deployment, but not general Spanner coverage. With 356 packages resolved in our source install, driver breadth also has a visible contributor cost even though ordinary users can download a single binary.

Rollbacks and nontransactional databases need deliberate SQL

Dbmate cannot infer a rollback. Each migration needs a migrate:down block if developers expect rollback or down to reverse it. Transactions default to enabled when a database supports them, and multiple sections in one migration file are allowed. Database operations such as certain SQLite PRAGMAs or Spanner DDL require opting out, which also changes the failure model.

Open issue 675 describes a ClickHouse migration where later failure left earlier statements applied and status reporting misleading, followed by rollback-order trouble. A related August 2026 pull request addressed how one migration version is recorded across multiple sections. Teams using a nontransactional engine should prefer small files, test failure halfway through each sequence, and document manual recovery. A happy-path up check is not enough evidence for that case.

Active releases make the failed run worth investigating

Dbmate v2.35.1 was released on August 26, 2026, minutes after the repository's recorded last push. GitHub showed 7,267 stars and 50 combined open issues and pull requests. Recent work included database wait behavior, PostgreSQL environment handling, multi-section migration recording, dump processing, and dependency updates. The combined open count is a queue size, not a count of confirmed defects.

The current release and August issue activity point to maintained software, while our 5 failed test groups keep the verdict conditional. PostgreSQL or MySQL teams can trial the prebuilt binary quickly and test migrations against disposable databases. SQLite users should reproduce the two named failures first. Dbmate is at its best when plain SQL and a common CLI matter more than automatic rollback generation or declarative schema reconciliation.

Alternatives

ProjectWhat it isPick it when
golang-migrateA Go migration CLI and library with broad database driver support.pick this instead when database-driver breadth or its Go API fits your stack better than schema dumps.
GooseA Go migration tool supporting SQL migrations and Go migration functions.pick this instead when migrations need executable Go logic alongside SQL.
AtlasA schema management tool with declarative workflows, inspection, and migration planning.pick this instead when you want desired-state schema planning rather than a small plain-SQL runner.

What people are saying

  1. [github-trending] amacneil/dbmate

Sources

  1. Dbmate repository README
  2. Dbmate v2.35.1 release
  3. ClickHouse partial application issue
  4. Multi-section migration fix proposal
  5. Dbmate Go package reference

More data reviews

turso · TrackersListCollection · dash · getcontact-cli · awesome-zhuiju-free · iggy · the whole board →