Skip to content
Latchkey

Alembic vs Flyway: Database Migrations Compared

Alembic is the Python/SQLAlchemy migration tool with autogeneration; Flyway is a language-agnostic, SQL-versioned migration runner used widely in JVM and polyglot shops.

Alembic integrates tightly with SQLAlchemy, can autogenerate migrations from model diffs, and is the standard for Python projects. Flyway runs versioned SQL (and optionally Java) migrations in order, is language-agnostic, and is popular in Java and polyglot teams for its simple, repeatable apply model.

AlembicFlyway
EcosystemPython / SQLAlchemyLanguage-agnostic (JVM roots)
Migration formatPython scriptsVersioned SQL (+ Java)
AutogenerateYes (from models)No (write SQL)
Apply modelRevision graphOrdered versions
Best forPython appsPolyglot / JVM, SQL-first

In CI

Both apply migrations against a database in CI - Alembic via its upgrade command, Flyway via flyway migrate. Alembic fits Python pipelines and can diff models; Flyway drops cleanly into any pipeline as a CLI or container. Run migrations against a disposable DB service to validate them on every PR.

Speed it up

Cache dependencies (or pull the Flyway image) and migrate against a throwaway DB. Both run on CI runners; faster managed runners shorten install and migration apply.

Decide with your own numbers, not a feature table

Feature comparisons age badly and rarely decide anything, because both tools in a mature category can do the job. What differs is how each behaves on your repository, and that takes one afternoon to measure.

Terminal
# time a cold install with each candidate, cache cleared
hyperfine --prepare "rm -rf node_modules" --warmup 1 \
  "<tool-a> install" "<tool-b> install"

# and the thing CI actually pays for: a cold run with no local cache
docker run --rm -v "$(pwd):/w" -w /w node:22 sh -c "<tool> install"

What actually changes when you switch

  • Lockfile format. A switch is a one-way door for anyone still on the old tool until everyone migrates, so plan it as a single coordinated change.
  • Resolution strictness. Tools differ on whether an undeclared transitive import works, and the stricter one will surface latent bugs as new failures.
  • CI cache configuration. The cache path and key differ per tool; carrying over the old ones silently disables caching.
  • Everyone on the team and every runner must move together. Pin the version so they cannot drift.

The verdict

Python/SQLAlchemy project wanting autogenerated migrations: Alembic. Polyglot or JVM team wanting language-agnostic, SQL-versioned migrations: Flyway. Choose by ecosystem and whether you prefer code or raw SQL migrations.

Frequently asked questions

Alembic vs Flyway: Database Migrations Compared?
Alembic integrates tightly with SQLAlchemy, can autogenerate migrations from model diffs, and is the standard for Python projects. Flyway runs versioned SQL (and optionally Java) migrations in order, is language-agnostic, and is popular in Java and polyglot teams for its simple, repeatable apply model.
In CI?
Both apply migrations against a database in CI - Alembic via its upgrade command, Flyway via flyway migrate. Alembic fits Python pipelines and can diff models; Flyway drops cleanly into any pipeline as a CLI or container. Run migrations against a disposable DB service to validate them on every PR.
Speed it up?
Cache dependencies (or pull the Flyway image) and migrate against a throwaway DB. Both run on CI runners; faster managed runners shorten install and migration apply.
Which should I choose?
Python/SQLAlchemy project wanting autogenerated migrations: Alembic. Polyglot or JVM team wanting language-agnostic, SQL-versioned migrations: Flyway. Choose by ecosystem and whether you prefer code or raw SQL migrations.

Related guides

References

Run this faster and cheaper on Latchkey managed runners - self-healing included. Start free → 30-day trial · No credit card