Database Engineering

Database Schema Version Control: Liquibase vs Flyway for Production Databases

Compare Liquibase and Flyway for production database schema management. Learn changelog formats, rollback strategies, team workflows, and CI/CD integration patterns.

JusDB Team
December 19, 2025
9 min read
198 views

Why Schema Version Control Matters

Application code lives in Git — every change is tracked, reviewed, and reversible. Database schema changes often don't get the same treatment. Ad-hoc ALTER TABLE commands applied manually leave databases in unknown states across environments. Schema version control tools fix this.

Flyway vs Liquibase: Quick Comparison

FeatureFlywayLiquibase
Changelog formatSQL or Java migrationsSQL, XML, YAML, JSON
RollbackManual undo scripts (Community); auto in Teams/EnterpriseBuilt-in rollback support
Learning curveSimple, convention-basedMore complex, more features
Database supportAll major databasesAll major databases
Best forTeams wanting simplicityTeams needing advanced rollback and multi-database

Flyway in Practice

text
-- Migrations are SQL files named with versions:
-- V1__Create_orders_table.sql
-- V2__Add_status_index.sql
-- V3__Add_shipping_address.sql

-- V3__Add_shipping_address.sql
ALTER TABLE orders
  ADD COLUMN shipping_address_line1 VARCHAR(255),
  ADD COLUMN shipping_address_line2 VARCHAR(255),
  ADD COLUMN shipping_city VARCHAR(100),
  ADD COLUMN shipping_zip VARCHAR(20);
text
-- Flyway tracks applied migrations in flyway_schema_history
SELECT installed_rank, version, description, type, installed_on, success
FROM flyway_schema_history
ORDER BY installed_rank;
text
# CI/CD: apply pending migrations
flyway -url=jdbc:postgresql://localhost/mydb \
       -user=myapp -password=${DB_PASS} \
       migrate

# Validate that migrations haven't been changed
flyway validate

# See what's pending
flyway info

Liquibase in Practice

text
# changelog.yaml
databaseChangeLog:
  - changeSet:
      id: 3
      author: alice
      changes:
        - addColumn:
            tableName: orders
            columns:
              - column:
                  name: shipping_address_line1
                  type: VARCHAR(255)
      rollback:
        - dropColumn:
            tableName: orders
            columnName: shipping_address_line1
text
# Apply changes
liquibase update

# Roll back last 1 changeset
liquibase rollback-count 1

# Roll back to a tag
liquibase tag pre-v2.0
liquibase rollback pre-v2.0

Zero-Downtime Migration Patterns

The expand-contract pattern enables schema changes without downtime:

text
-- Phase 1 (Expand): Add new column, keep old
ALTER TABLE users ADD COLUMN email_normalized VARCHAR(255);

-- Deploy app that writes to BOTH old and new columns

-- Phase 2 (Backfill): Populate new column
UPDATE users
SET email_normalized = LOWER(TRIM(email))
WHERE email_normalized IS NULL
LIMIT 10000;  -- Run in batches

-- Phase 3 (Switch): App reads from new column only

-- Phase 4 (Contract): Drop old column
ALTER TABLE users DROP COLUMN email;

CI/CD Integration

text
# GitHub Actions workflow
jobs:
  migrate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run Flyway migrations
        uses: flyway/flyway-github-action@v1
        with:
          url: jdbc:postgresql://${{ secrets.DB_HOST }}/${{ secrets.DB_NAME }}
          user: ${{ secrets.DB_USER }}
          password: ${{ secrets.DB_PASS }}
          command: migrate

Team Workflow Best Practices

  • Never modify an applied migration — create a new one instead. Both tools validate checksums and will fail if you modify history.
  • Test rollbacks in staging before production for every migration
  • Use repeatable migrations (R__ prefix in Flyway) for views, stored procedures, and functions
  • Review migrations in PR as carefully as application code
  • Tag database state before major releases for easy rollback points

Key Takeaways

  • Flyway is simpler; Liquibase has better built-in rollback support
  • Never modify applied migrations — always add new changesets
  • Use expand-contract for zero-downtime schema changes
  • Integrate schema migrations into CI/CD alongside application deployments
  • Test rollback procedures in staging before every production deployment

Share this article

JusDB Team

Official JusDB content team