mrkeyoor.com_
Thu 10 Sept 18:02 UTC
Dev Toolsevaluationupdated 10 Sept 2026

migrate review

golang-migrate/migrate applies ordered database changes from files, embedded assets, or remote storage. You can run it as a command-line program in any stack or import its version 4 Go library when migration control belongs inside an application.

trackingstars / 7d
Verdict

Our golang-migrate run installed 457 packages in 68 seconds and built in 174 seconds, but 18 of 68 Go package results failed. The released CLI remains a sensible choice for teams that already write and review explicit migrations and need broad driver coverage. Choose Atlas for generated plans and linting, or Goose when Go functions belong in the migration history.

We ran it

Lab card: what happened when we ran migrateScreenshot of migrate (github.com/golang-migrate/migrate)
Install✓ · 68s457 packages
Build✓ · 174s
Tests✗ · 48s50 passed · 18 failed of 68 (go test)
Repo405 files~23,476 lines of source · 0.8 MB · 2 CI workflows · Dockerfile

Answers from our run

Does migrate build from source?

Dependencies installed in 68 seconds (457 packages), and the build succeeded in 174 seconds. We cloned commit 504568a into a clean Debian container with 3 CPUs and no project-specific setup.

Do migrate's tests pass?

Not all of them: 50 of 68 passed and 18 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 migrate?

Teams that want a tool to inspect a desired schema and generate safe changes: migrate executes the migration files you write and does little checking of their contents.

What are the alternatives to migrate?

Goose, Atlas, Dbmate. Our golang-migrate run installed 457 packages in 68 seconds and built in 174 seconds, but 18 of 68 Go package results failed.

Setup3/5Binaries are easy; our 457-package checkout ended with 18 failed results
Docs4/5Core commands and failure recovery are clear; some install notes are old
Community4/518,906 stars and current releases, with 311 issues and 177 PRs open
Maturity4/5The v4 API is stable, but behavior still depends on each driver

Who it’s for

Teams that want plain migration files and explicit up, down, step, or target-version commands.
Go developers who want the same migration engine as an importable version 4 library.
Polyglot services that need one CLI across PostgreSQL, MySQL, SQLite, MongoDB, and other listed databases.
Operators who need migrations loaded from a filesystem, object storage, or a supported Git host.

Who it’s NOT for

Teams that want a tool to inspect a desired schema and generate safe changes: migrate executes the migration files you write and does little checking of their contents.
Applications that need several migration sources in one batch: the FAQ says sources cannot be mixed during a run.
Operators who expect automatic recovery after partial failure: a dirty database blocks later migrations until someone investigates the state and forces the correct version.
Deployments whose database driver lacks suitable locking for concurrent migrators: the getting-started guide warns multiple application instances can conflict.
Projects staying on the version 3 line: the README marks v3 unsupported and recommends v4.

Setup reality

Our sandbox installed 457 packages in 68 seconds, then built successfully in 174 seconds. The 48-second Go test step failed: 50 package results passed and 18 failed out of 68. The log tail showed several source packages passing before the suite ended with FAIL, without the errors that explain those 18 failures.

Using the released CLI requires a database URL and readable migration files; remote sources can add GitHub, GitLab, S3, or Google Cloud credentials. Source-built CLI binaries use build tags for the database and source drivers required. Full contributor tests need Docker and the database services covered by the selected test matrix.

Our image used Go 1.24, while the current README advertises Go 1.25 and 1.26. Driver behavior also matters: only some databases provide migration locking, transaction support differs, and a failed migration leaves a dirty version that an operator must inspect and correct with force.

Version 4 keeps migration execution explicit

Migrate has one focused job: read numbered migration files and apply them in order. The CLI supports up, down, goto, step, drop, and version repair, while the version 4 Go package puts the same engine inside an application. Drivers avoid correcting user input behind the scenes. That restraint makes deployment behavior easier to reason about, provided your team already knows how to write safe database changes.

The current README lists 21 database-driver entries, covering PostgreSQL and PGX, MySQL or MariaDB, SQLite, MongoDB, Cassandra or ScyllaDB, SQL Server, and several cloud or distributed systems. Ten source entries load migrations from local files, Go filesystems, embedded bundles, Git hosts, S3, or Google Cloud Storage. The CLI can therefore remain constant while storage and database choices differ across services.

Two files define each reversible migration

A logical migration normally has an up file and a down file with matching integer or timestamp versions. Migrate sends their contents to the selected database driver with little format checking, so there is no private migration language to learn. The same simplicity leaves SQL quality, reversibility, and destructive-operation review with the application team. Irreversible changes may use a comment-only down file, while a zero-byte file can cause trouble because the tool attempts an empty query.

The getting-started guide recommends running every change up, down, and up again before committing it. Several commands within one migration need an explicit transaction when the database supports one. That advice is more than ceremony: database engines disagree about transactional schema changes, and migrate does not flatten those differences into a universal promise. Teams should test against the same database family and version they deploy, especially for changes that rewrite data or lock large tables.

What happened when we ran it

Our run installed 457 packages in 68 seconds and completed the build in 174 seconds. The measurement used commit 504568a in a fresh unprivileged Debian container with 3 CPUs, 8 GB of RAM, and Go 1.24. The checkout had 405 files, roughly 23,476 source lines, and occupied 0.8 MB before dependency installation. Those numbers describe the repository build, not the much simpler download of a released binary.

The test command failed with exit code 1 after 48 seconds. Go test produced 50 passing package results and 18 failures out of 68. The supplied log tail showed GitHub, GitLab, Google Cloud Storage, HTTP filesystem, embedded-source, and other source packages passing, then ended with FAIL. It did not include the earlier error messages for the 18 failed packages, so we cannot name a cause from that tail.

The repository had 2 CI workflow files and a Dockerfile. It had no top-level tests directory, which is normal for a Go project whose test files can live beside packages. Our Go 1.24 image is also older than the Go 1.25 and 1.26 versions named by the current README badge. That mismatch is relevant when reproducing the run, but the available log does not establish that it caused any failure.

A dirty version needs manual repair before work can continue

Migrate marks a database dirty before it executes a change. If execution fails, later migrations stop until an operator determines whether the change was applied fully, partly, or not at all. The force command then records the version that matches reality without rerunning migration SQL. This is a sound safety stop, though it requires a person who can inspect the database instead of treating deployment as a retry loop.

Concurrent execution also depends on the selected driver. The FAQ names MySQL GET_LOCK and PostgreSQL advisory locks as examples, while the getting-started guide warns that only some drivers supply locking. A deployment with 2 or more application instances should nominate one migrator or verify the driver's lock behavior. Migrate can stop gracefully on SIGINT, but process control does not replace database-level exclusion.

One batch cannot combine 2 migration sources

The source abstraction is broad but deliberately singular for a run. The FAQ says a batch cannot mix multiple sources, so a release cannot draw some migrations from an embedded filesystem and the rest from S3 in one ordered sequence. Teams with split ownership need to consolidate the files or run separate, carefully ordered migration jobs. A source URL may also carry credentials, which means command construction and log redaction deserve review.

Version 4.20.1 fixed release delivery the same day

GitHub shows v4.20.1 published on September 9, 2026, minutes after v4.20.0. The earlier tag's release workflow failed to publish artifacts to Docker and other registries, so maintainers issued v4.20.1 with a corrected GoReleaser matrix instead of moving the existing tag. The repository was also pushed that day. This is current maintenance and a transparent repair, even though consumers had to skip the broken distribution tag.

Issue search on September 10 returned 311 open issues and 177 open pull requests. The queue includes items updated that week, and one PR was updated on September 10, so the large total is active rather than an abandoned archive. It is still a lot for users to search when a driver behaves unexpectedly. The 18,906 stars show reach, while the backlog argues for reading issues for the exact database and source combination you plan to use.

Choose Migrate when the SQL already belongs to your team

Our 174-second build and 18 failed package results keep this checkout from earning an unconditional recommendation for contributors. Binary users should trial v4.20.1 against a disposable copy of their actual database, including an intentional failed migration and recovery with force. If the team expects the tool to design or lint schema changes, Atlas is the closer match; if it needs Go migration functions, Goose is easier to justify.

Alternatives

ProjectWhat it isPick it when
GooseA Go migration CLI and library that accepts both SQL files and Go functions.pick this instead when migrations need executable Go code, out-of-order application, or built-in data seeding.
AtlasA schema-management tool that can inspect, plan, lint, and apply database changes.pick this instead when you want schema diffing and migration planning rather than writing every change by hand.
Dbmate gh↗A language-neutral migration CLI centered on plain SQL and a small set of databases.pick this instead when a self-contained binary, environment-file support, and schema dumps matter more than driver breadth.

What people are saying

  1. [github-trending] golang-migrate/migrate

Sources

  1. golang-migrate README
  2. Getting started and dirty-version recovery
  3. Migration file format and reversibility
  4. golang-migrate FAQ
  5. migrate CLI installation and usage
  6. v4.20.1 release notes

More dev tools reviews

unleashed-firmware · elixir · metasploit-framework · ast-grep · ai-usagebar · herdr-reviewr · the whole board →