Flyway and Liquibase solve the same problem (versioning and applying database schema changes reproducibly), but with philosophies different enough that choosing between them depends less on a feature-by-feature comparison than on a bet about how the team prefers to think about its migrations, a question already touched on in the article on database migrations in a CI/CD pipeline without ever settling between tools.
Flyway: versioned, immutable SQL, nothing more
Flyway builds every migration on a plain SQL file, named according to a strict version convention (V1__create_table.sql), applied exactly once and never modified afterward: once executed, a Flyway migration is immutable, any fix requiring a new migration rather than editing the existing one.
-- V2__add_email_column.sql
ALTER TABLE users ADD COLUMN email VARCHAR(255);
This deliberate simplicity means a SQL developer can read and write a Flyway migration without learning any additional abstraction, at the cost of SQL that’s generally specific to the target database engine, not very portable to a different one without a rewrite.
Liquibase: a declarative, DB-agnostic changelog
Liquibase describes each change in a structured format (XML, YAML, JSON, or SQL) called a changelog, an abstraction layer that Liquibase then translates into database-specific SQL at execution time.
# changelog.yaml
- changeSet:
id: add-email-column
author: team
changes:
- addColumn:
tableName: users
columns:
- column:
name: email
type: varchar(255)
This abstraction, in theory, lets the same changelog run against PostgreSQL or MySQL without a rewrite, a real advantage for anyone managing multiple database engines, but it adds a translation layer to understand and debug when the generated SQL doesn’t exactly match expectations.
Rollback: a promise worth qualifying on both sides
Liquibase offers a declarative rollback mechanism (rollback attached to each changeSet), a native feature Flyway (in its free edition) doesn’t directly provide, pointing instead toward writing a forward-fix migration. This difference is real, but it echoes the same nuance already raised in the migrations-in-pipeline article: a schema rollback stays risky the moment data has been written in the meantime into the affected columns, regardless of which tool executes it.
The actual deciding factor
The choice between the two doesn’t come down to “which has more features,” but to a simpler question: does the team prefer writing plain SQL directly understood by every SQL developer on the team (Flyway), or a declarative abstraction that eases multi-database portability and structured rollback at the cost of an extra layer to master (Liquibase)? A single-database team comfortable writing SQL naturally leans toward Flyway; a team managing several database engines or wanting structured rollback by default finds in Liquibase a compromise already built for that need.
Takeaway
Flyway enforces versioned, immutable SQL migrations, a simplicity that requires no extra abstraction but generally stays tied to the target database engine. Liquibase adds a declarative changelog layer translated into SQL at execution time, portable across several databases and equipped with structured rollback, at the cost of one more abstraction to understand. The deciding factor is neither popularity nor a feature list, but the team’s preference between directly readable raw SQL and a portable declarative changelog, a tooling decision best made upfront rather than corrected after migrations are already written in a given format.