dbmate is a free, open source databases project written in Go and released under MIT. It has 7,391 GitHub stars, 379 forks and 34 open issues, and was last pushed 27 hours ago. On this registry it ranks #99 of 143 tracked projects in Databases, with 5 head-to-head comparisons available.

What is dbmate?

Dbmate is a standalone, MIT-licensed command line database migration tool written in Go that keeps database schema in sync across multiple developers and production servers, aimed at teams building database-backed applications in any language or framework.

What it is

Dbmate lives in the Infrastructure and Operations / Databases space as a single self-contained binary rather than a library bound to one application framework. It is a standalone command line tool used with Go, Node.js, Python, Ruby, PHP, Rust, C++, or any other language used to write database-backed applications. The README positions it as especially useful when several services are written in different languages and the team wants consistent development tooling rather than one migration runner per stack.

The concrete problem it solves is schema drift. Migration files are timestamp-versioned, which avoids version number conflicts when multiple developers create migrations at the same time, and the tool can export a schema.sql file so schema changes appear as reviewable diffs in git. What it replaces is framework-tied migration tooling: because dbmate is framework-agnostic and driven by plain SQL, a polyglot repository can run one migration tool instead of one per language runtime.

Key capabilities

  • Migrations written in plain SQL, not a DSL or an ORM model definition.
  • Timestamp-versioned migration files that avoid version number conflicts between developers.
  • Migrations run atomically inside a transaction.
  • dbmate new generates a migration file and dbmate up applies pending migrations; dbmate --help prints usage.
  • Database connection URL is supplied through an environment variable, DATABASE_URL by default, or on the command line, with built-in support for reading variables from a .env file.
  • Exports a schema.sql file so schema changes can be diffed in git.
  • Supports creating and dropping databases, which is handy in development and test environments.
  • Documented connection sections cover PostgreSQL, MySQL, MariaDB, SQLite, ClickHouse, BigQuery, and Spanner.
  • Usable as a library at github.com/amacneil/dbmate/v2/pkg/dbmate, including embedding migrations.

Who uses it and how

  • Polyglot teams running services in Go, Node.js, Python, Ruby, PHP, and C++ who want one consistent migration workflow across all of them.
  • Developers who review schema evolution through schema.sql diffs in pull requests rather than inspecting a live database.
  • Local development and test setups that need databases created and dropped as part of the workflow.
  • Container-based workflows using the published image ghcr.io/amacneil/dbmate, typically with --network=host for docker networking and a bind mount such as -v "$(pwd)/db:/db" to reach local migration files.
  • Teams waiting on a database to become reachable before applying migrations, and teams that need rollback of applied migrations.

Getting started

Install via npm install --save-dev dbmate, brew install dbmate, scoop install dbmate, a direct binary download to /usr/local/bin/dbmate, or run the Docker image ghcr.io/amacneil/dbmate. Set DATABASE_URL and run dbmate up to apply pending migrations.

How it compares

The facts provided name no competing migration tools and no list of paid products this project replaces, so it stands alone in this registry entry. The README does carry an Alternatives section comparing dbmate with other popular database schema migration tools, which is the place to look for that comparison. On the axes the facts do support, dbmate is MIT-licensed, self-hosted, and explicitly does not try to upsell a SaaS service, so the schema and the migration history stay in the operator's own database and repository.

When to use it โ€” and when not to

A self-hoster must operate the target database and supply a working connection URL, either through DATABASE_URL or on the command line, plus a .env file if environment variables are read that way; container users also have to handle Docker networking and bind mounts. Teams that want migrations generated from application models, or that expect a hosted migration service with a dashboard, should look elsewhere, because dbmate is a CLI and a library with no SaaS component. The trade-off is that migrations are hand-written SQL, which gives full control but no autogeneration, and the README excerpt available here documents commands only up to dbmate up, so the rest of the command surface has to be read from the full repository documentation.

project readme (upstream, from github) โ€” read inline

Dbmate

Release Go Report Reference

Dbmate is a database migration tool that will keep your database schema in sync across multiple developers and your production servers.

It is a standalone command line tool that can be used with Go, Node.js, Python, Ruby, PHP, Rust, C++, or any other language or framework you are using to write database-backed applications. This is especially helpful if you are writing multiple services in different languages, and want to maintain some sanity with consistent development tools.

For a comparison between dbmate and other popular database schema migration tools, please see Alternatives.

Table of Contents

Features

  • Supports MySQL, MariaDB, PostgreSQL, SQLite, and ClickHouse
  • Uses plain SQL for writing schema migrations
  • Migrations are timestamp-versioned, to avoid version number conflicts with multiple developers
  • Migrations are run atomically inside a transaction
  • Supports creating and dropping databases (handy in development/test)
  • Supports saving a schema.sql file to easily diff schema changes in git
  • Database connection URL is defined using an environment variable (DATABASE_URL by default), or specified on the command line
  • Built-in support for reading environment variables from your .env file
  • Easy to distribute, single self-contained binary
  • Doesn't try to upsell you on a SaaS service

Installation

NPM

Install using NPM:

npm install --save-dev dbmate
npx dbmate --help

macOS

Install using Homebrew:

brew install dbmate
dbmate --help

Linux

Install the binary directly:

sudo curl -fsSL -o /usr/local/bin/dbmate https://github.com/amacneil/dbmate/releases/latest/download/dbmate-linux-amd64
sudo chmod +x /usr/local/bin/dbmate
/usr/local/bin/dbmate --help

Windows

Install using Scoop

scoop install dbmate
dbmate --help

Docker

Docker images are published to GitHub Container Registry (ghcr.io/amacneil/dbmate).

Remember to set --network=host or see this comment for more tips on using dbmate with docker networking):

docker run --rm -it --network=host ghcr.io/amacneil/dbmate --help

If you wish to create or apply migrations, you will need to use Docker's bind mount feature to make your local working directory (pwd) available inside the dbmate container:

docker run --rm -it --network=host -v "$(pwd)/db:/db" ghcr.io/amacneil/dbmate new create_users_table

Commands

dbmate --help         # print usage help
dbmate new            # generate a new migration file
dbmate up             # create the database (if it does not already exist) and run any pending migrations
dbmate create         # create the database
dbmate drop           # drop the database
dbmate migrate        # run any pending migrations
dbmate rollback       # roll back the most recent migration
dbmate down           # alias for rollback
dbmate status         # show the status of all migrations (supports --exit-code and --quiet)
dbmate dump           # write the database schema.sql file
dbmate dump -- [...]  # optionally pass additional arguments directly to mysqldump or pg_dump
dbmate load           # load schema.sql file to the database
dbmate wait           # wait for the database server to become available

Command Line Options

The following options are available with all commands. You must use command line arguments in the order dbmate [global options] command [command options]. Most options can also be configured via environment variables (and loaded from your .env file, which is helpful to share configuration between team members).

  • --url, -u "protocol://host:port/dbname" - specify the database url directly. (env: DATABASE_URL)
  • --driver "driver_name" - specify the driver to use (if empty, the driver is derived from database URL scheme). (env: DBMATE_DRIVER)
  • --env, -e "DATABASE_URL" - specify an environment variable to read the database connection URL from.
  • --env-file ".env" - specify an alternate environment variables file(s) to load.
  • --migrations-dir, -d "./db/migrations" - where to keep the migration files. (env: DBMATE_MIGRATIONS_DIR)
  • --migrations-table "schema_migrations" - database table to record migrations in. (env: DBMATE_MIGRATIONS_TABLE)
  • --schema-file, -s "./db/schema.sql" - a path to keep the schema.sql file. (env: DBMATE_SCHEMA_FILE)
  • --no-dump-schema - don't auto-update the schema.sql file on migrate/rollback (env: DBMATE_NO_DUMP_SCHEMA)
  • --strict - fail if migrations would be applied out of order (env: DBMATE_STRICT)
  • --wait - wait for the db to become available before executing the subsequent command (env: DBMATE_WAIT)
  • --wait-timeout 60s - timeout for --wait flag (env: DBMATE_WAIT_TIMEOUT)
  • --wait-interval 1s - time to wait between connection attempts for --wait flag (env: DBMATE_WAIT_INTERVAL)

Usage

Environment Variables

Most dbmate settings can be configured with environment variables in addition to command line flags. This is useful for twelve-factor style deployments and for sharing local configuration via a .env file.

Which settings use which environment variables
Setting Environment variable Notes
Database URL DATABASE_URL (default) Overridden by --url / -u. Use --env / -e to read the URL from a different variable (for example TEST_DATABASE_URL).
Driver DBMATE_DRIVER Used when --driver is not set.
Migrations directory DBMATE_MIGRATIONS_DIR Corresponds to --migrations-dir / -d.
Migrations table DBMATE_MIGRATIONS_TABLE Corresponds to --migrations-table.
Schema file DBMATE_SCHEMA_FILE Corresponds to --schema-file / -s.
Disable schema dump DBMATE_NO_DUMP_SCHEMA Corresponds to --no-dump-schema.
Wait for database DBMATE_WAIT Corresponds to --wait.
Wait timeout DBMATE_WAIT_TIMEOUT Corresponds to --wait-timeout.
Wait interval DBMATE_WAIT_INTERVAL Corresponds to --wait-interval.
Strict migrations DBMATE_STRICT Corresponds to --strict on up / migrate.
Verbose SQL output DBMATE_VERBOSE Corresponds to --verbose / -v on up / migrate / rollback.

--env and --env-file are CLI-only options (they are not themselves read from environment variables).

Loading .env files

By default, dbmate loads environment variables from a .env file in the current working directory (if present). Missing files are ignored; an invalid dotenv file causes dbmate to exit with an error.

To load one or more alternate dotenv files, pass --env-file (repeatable). When any --env-file is given, only the listed files are loaded - the default .env is not included unless you specify it:

dbmate --env-file .env.development up
dbmate --env-file .env --env-file .env.local up

Files are loaded in the order given.

Variable precedence

From highest to lowest priority:

  1. Command line flags (for example --url, --driver, --migrations-dir)
  2. Environment variables already set in the calling process
  3. Values from dotenv files (.env or files passed with --env-file)
  4. Built-in defaults

Dotenv files n

readme truncated โ€” read the full docs on github

Frequently asked questions

Is dbmate free to use?

dbmate is open source under the MIT licence. There is no licence fee and no seat count โ€” you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does dbmate do?

๐Ÿš€ A lightweight, framework-agnostic database migration tool.

What is dbmate written in?

dbmate is primarily written in Go. Its source is publicly available at https://github.com/amacneil/dbmate, and it has 7,391 GitHub stars.