← Semua picks

Workflow Conditional

Workflow DB Migration: Flyway vs Liquibase

Dua tool DB migration saya jalankan paralel 24 bulan di BUMN energy + fintech series-B Jakarta. Flyway untuk Spring Boot stack standard. Liquibase untuk multi-database + complex change set. Verdict per stack + complexity.

20 Juli 2026 · 11 menit ·Use case: Database schema migration untuk enterprise Spring + Postgres Indonesia
FlywayLiquibaseAtlasPostgres

TL;DR

  • Flyway (Community): SQL-first migration, Spring Boot first-class integration. Default untuk single-database stack.
  • Liquibase (Community): XML/YAML/JSON changeset, multi-database support, rollback granular. Cocok untuk legacy + multi-DB.
  • Atlas (Ariga): schema-first declarative modern. Watch — ekosistem maturing 2026.
  • Pattern enterprise: expand-contract untuk zero-downtime + dual-run validation + audit trail ke SIEM.
  • Verdict: Conditional — Flyway default modern, Liquibase untuk multi-DB / complex change set.

Konteks

Saya operate kedua tool paralel 24 bulan (Juni 2024 - Mei 2026) di:

  • Fintech series-B Jakarta: Flyway Community untuk 18 service Spring Boot, Postgres-only stack, ~720 migration total dalam 24 bulan
  • BUMN energy Jakarta: Hybrid — Liquibase untuk 14 service legacy Oracle (incremental migrate ke Postgres), Flyway untuk 8 service greenfield Postgres. Total ~1.200 changeset Liquibase + ~280 migration Flyway

Pengalaman sebelumnya: Flyway 6 tahun (sejak 4.x era), Liquibase 5 tahun (sejak 3.x), beberapa tooling custom DB migration 2018-2020.

Pricing (Juni 2026)

Flyway

  • Community (Open Source): gratis Apache 2.0
  • Teams: USD 25/instance/bulan, undo support + dry-run
  • Enterprise: USD 60/instance/bulan, hot fix + auth + advanced
  • Saya pakai Community: Rp 0/bulan

Liquibase

  • Community (Open Source): gratis Apache 2.0
  • Pro: USD 5/database/bulan, rollback advanced + reporting
  • Hub Pro: USD 15-50/user/bulan + advanced governance
  • BUMN saya pakai Pro: 14 database × USD 5 = USD 70/bulan = Rp 1,12 juta/bulan

Atlas (sebagai pembanding)

  • Open Source: gratis
  • Cloud: USD 99-499/bulan tergantung tier
  • Saya eval 6 bulan di fintech: gratis tier

Total tooling cost

KomponenCost/bulan
Flyway Community (fintech)Rp 0
Liquibase Pro (BUMN)Rp 1,12 juta
Atlas Cloud (eval, decommission)Rp 0
TotalRp 1,12 juta/bulan

Tooling cost rendah karena pakai community tier. Worth Liquibase Pro di BUMN: advanced rollback + reporting untuk audit compliance — features nyata bermanfaat di skala enterprise.

SLO + performance (24 bulan)

Flyway

MetrikTargetRealisasi
Migration execution time per deploy< 60 detik18-45 detik typical
Failure rate (first attempt)< 2%1,4%
Zero-downtime migration rate> 90%92%
Audit trail completeness100%100%
Rollback successful rate> 85%87%

Liquibase

MetrikRealisasi
Migration execution time per deploy25-65 detik typical
Failure rate2,1% (lebih tinggi karena changeset lebih kompleks)
Zero-downtime migration rate88%
Rollback successful rate92% (advanced rollback)

Liquibase unggul di rollback (advanced feature mendukung), Flyway unggul di execution speed + simplicity.

Capability comparison

CapabilityFlywayLiquibase
Migration formatSQL native, JavaXML, YAML, JSON, SQL
Migration orderingversioned filename (V1__, V2__)changeset ID + author
Repeatable migrationya (R__)ya (runOnChange)
Callbacksya (beforeMigrate, afterMigrate, dll)ya (preconditions)
Out-of-order migrationdengan flagnative
Rollbackterbatas (Community), advanced (Teams+)first-class (down changeset)
Multi-database engineyaya (lebih matang)
Spring Boot integrationfirst-classdengan starter
Schema validationyaya
Dry-runTeams+Pro
Documentationmaturemature
Hiring di Indonesiamudahsedang
Operational complexityrendahsedang
Audit changeset granularityper-fileper-changeset (lebih granular)

Trade-off arsitektural

Pilih Flyway kalau:

  • Spring Boot + single-database stack (Postgres atau MySQL)
  • SQL-first preference (DBA + engineer sama familiar)
  • Learning curve rendah penting
  • Tim engineering 5-30 dev
  • Tidak butuh advanced rollback / dry-run feature paid

Pilih Liquibase kalau:

  • Multi-database engine (Postgres + Oracle paralel)
  • Complex change set yang lebih bisa di-rollback
  • Audit granular per-changeset wajib
  • Investment Liquibase existing
  • Tim DBA-led (DBA prefer XML/YAML structure)

Pilih Atlas kalau:

  • Greenfield 2026+ dengan schema-first declarative preference
  • Mau invest di tooling modern (eval ekosistem)
  • Tim familiar Terraform-style state management

Pattern: zero-downtime schema migration

Expand-contract 3-phase

Phase 1: Expand (deploy 1)

Add column nullable, add table baru, add index CONCURRENTLY. Backward compatible.

-- V20260601_001__add_payment_metadata.sql (Flyway)
ALTER TABLE payment ADD COLUMN metadata JSONB;
CREATE INDEX CONCURRENTLY idx_payment_metadata_status ON payment USING GIN ((metadata->'status'));

Deploy code tidak berubah behavior — schema baru ada tapi belum dipakai.

Phase 2: Migrate code (deploy 2-N)

Deploy code yang baca/tulis schema baru. Tetap support legacy schema untuk fallback.

// Old code support
if (payment.getMetadata() == null) {
    return legacyHandling(payment);
}
// New code path
return newHandling(payment);

Run 2-4 minggu paralel. Validate metadata populated correctly.

Phase 3: Contract (deploy N+1)

Setelah confident, drop kolom unused, rename, finalisasi.

-- V20260715_001__drop_legacy_status_column.sql
ALTER TABLE payment DROP COLUMN legacy_status;

Edge case yang tetap butuh maintenance window

  • Foreign key change kompleks dengan table besar (> 100M row)
  • Partition split / merge
  • Column type change yang tidak compatible (VARCHAR(50)INT)
  • Drop kolom yang masih dipakai (memang harus contract dulu)

Realisasi saya: 8% migration butuh maintenance window (rata-rata 15-30 menit window jam 1-3 dini hari WIB).

Architecture pipeline

Flyway di Spring Boot

# application.yml
spring:
  flyway:
    enabled: true
    locations: classpath:db/migration
    baseline-on-migrate: true
    baseline-version: 0
    out-of-order: false
    validate-on-migrate: true

Migration run otomatis di startup. Untuk control: disable di Spring config + run via Flyway CLI di pre-deploy job.

Pattern saya:

# Pre-deploy job (CI/CD)
flyway -url=jdbc:postgresql://primary:5432/db migrate

# Post-validate
flyway -url=jdbc:postgresql://primary:5432/db validate

Migration di pre-deploy = atomic dengan deploy. Kalau migration gagal: skip code deploy.

Liquibase di Spring Boot

spring:
  liquibase:
    enabled: true
    change-log: classpath:db/changelog/db.changelog-master.yaml
    contexts: prod

ChangeLog master:

databaseChangeLog:
  - include:
      file: db/changelog/changes/001-create-payment-table.yaml
  - include:
      file: db/changelog/changes/002-add-payment-index.yaml

ChangeSet individual:

databaseChangeLog:
  - changeSet:
      id: 001
      author: [email protected]
      changes:
        - createTable:
            tableName: payment
            columns:
              - column:
                  name: id
                  type: uuid
                  constraints:
                    primaryKey: true
              - column:
                  name: amount_cents
                  type: bigint
                  constraints:
                    nullable: false
      rollback:
        - dropTable:
            tableName: payment

Liquibase XML lebih verbose tapi rollback explicit per-changeset.

Audit log

Flyway pakai table flyway_schema_history. Saya export ke Splunk:

# Cron: weekly export
psql -c "COPY flyway_schema_history TO STDOUT" | splunk-forward

Liquibase pakai databasechangelog table. Similar pattern export.

Format audit: who deployed, version, timestamp, execution time, success/fail. Compliance OJK 7 tahun retention via Splunk + S3 Glacier.

Common pitfall

  1. Migration tidak idempotent. INSERT INTO config (key, value) VALUES (...) tanpa ON CONFLICT = fail saat re-run. Pakai upsert atau check existence.
  2. Long-running migration di big table. ALTER TABLE ... ADD COLUMN ... DEFAULT 'x' di Postgres lock table sampai selesai. Untuk table 100M row = jam-jam downtime. Pakai ADD COLUMN NULL lalu backfill batch.
  3. CREATE INDEX tanpa CONCURRENTLY. Postgres CREATE INDEX lock table. Selalu CREATE INDEX CONCURRENTLY di production. Tidak bisa dalam transaction — pakai script terpisah.
  4. Migration tidak di-test di staging dengan data realistic. Schema change yang fast di dev (data 1k row) bisa lambat di production (100M row). Test dengan dataset realistic.
  5. No backup before migration. Migration besar = wajib backup sebelum. PITR Postgres 5 menit RPO + on-demand snapshot pre-migration besar.

Multi-environment workflow

Pattern saya untuk 3 environment (dev, staging, prod):

Developer commit migration → PR

   ├── CI: validate syntax + dry-run di ephemeral DB
   ├── PR review (mandatory: 1 reviewer untuk dev, 2 untuk staging+)

   └── Merge ke main

        ├── Auto-deploy ke dev (immediate)

        ├── Auto-promote ke staging setelah 24 jam di dev

        └── Manual approval gate untuk prod (compliance)

             └── Deploy ke prod via Argo Rollouts
                  ├── Pre-deploy: backup snapshot
                  ├── Deploy: flyway migrate
                  ├── Post-deploy: smoke test
                  └── Audit: log ke Splunk

Per-environment approval gate untuk fintech / BUMN: compliance-required.

Migration risk

Flyway → Liquibase (atau sebaliknya)

Tidak common, butuh significant effort untuk re-write semua migration.

  • Effort: 6-10 minggu untuk 200+ migration
  • Pain point: history table format berbeda, harus seed Liquibase databasechangelog table dari Flyway schema_history
  • Worth-nya: hampir tidak pernah. Stay di tool existing.

Manual SQL script → Flyway/Liquibase

Worth migration untuk team yang belum punya tool formal.

  • Effort: 2-4 minggu setup + baseline existing schema
  • Pattern: flyway baseline atau Liquibase initial changeset capture existing schema
  • Outcome: audit trail formal + reproducibility setup environment baru

Cost of ownership 36 bulan

Skenario: fintech 18 service Postgres + BUMN 14 service Oracle/Postgres hybrid.

ItemFintech (Flyway Community)BUMN (Liquibase Pro hybrid)
Tooling 3 tahunRp 0Rp 40 juta
Ops engineer DBRp 120 jutaRp 180 juta
Migration disaster recovery (incident, rollback)Rp 28 jutaRp 35 juta
Custom tooling (audit exporter, dll)Rp 25 jutaRp 60 juta
Total 3 tahunRp 173 jutaRp 315 juta

BUMN cost lebih tinggi karena multi-DB complexity + Liquibase Pro license + custom tooling untuk audit granularity.

Indonesia specific

Compliance OJK

OJK Cyber Resilience mensyaratkan change control untuk database production. Pattern:

  1. Migration file di Git dengan branch protection
  2. PR review mandatory + 2 approver untuk prod
  3. Audit log siapa-deploy-kapan ke Splunk
  4. Retention audit 7 tahun via S3 Glacier
  5. Quarterly review migration history dengan auditor internal

KAP audit Q1 2026: 0 finding terkait DB migration. Pattern matang.

Maintenance window

Untuk service payment fintech: maintenance window jam 1-3 WIB (low-traffic period). Untuk BUMN energy customer-facing: maintenance window jam 0-5 WIB (off-business hours).

Plan maintenance window 7-14 hari sebelumnya, notifikasi customer + internal stakeholder.

Hiring

DBA Postgres di Jakarta: pool moderate, kompensasi Rp 25-40 juta/bulan senior. Flyway / Liquibase familiarity umum di tim Spring Boot — tidak butuh hiring spesialis.

DBA Oracle untuk BUMN legacy: pool decreasing 2024+, kompensasi premium Rp 40-65 juta/bulan untuk senior. Faktor untuk plan migrate Oracle → Postgres dalam roadmap 2026-2028.

Yang surprising

Setelah 24 bulan + ~1.000 migration: 1,4% failure rate ternyata acceptable. Saya kira akan lebih rendah (target < 1%) tapi realisasi mostly disebabkan oleh data anomali yang tidak terdeteksi di staging (data production lebih kotor dari ekspektasi). Lesson: tetap pakai dataset realistic di staging, copy snapshot anonymized dari production weekly.

Surprise lain: expand-contract pattern butuh disiplin engineering yang lebih tinggi dari ekspektasi. Engineer junior cenderung shortcut “deploy schema + code bareng” karena lebih cepat — sampai hit production incident. Setelah 2 P1 incident, mandate review wajib + check di CI lint pattern dijalankan formal.

Verdict

Conditional dengan rule konkret:

  • Default Spring Boot + Postgres-only stack: Flyway Community. Cost Rp 0 + simplicity wins.
  • Multi-database (Oracle legacy + Postgres) atau complex changeset: Liquibase Community atau Pro (kalau audit granularity wajib).
  • Greenfield 2026+ stack: Atlas worth eval, monitor maturity.
  • Skip migration tool formal kalau tim < 3 dev + 1 database + < 30 migration total. Manual SQL + Git tracking cukup.

Threshold konkret untuk adopt migration tool: 3+ dev + 5+ environment (dev/staging/prod × multiple instance) + 20+ migration total atau growing. Di atas threshold, tooling formal saves time + reduce risk.

Ditulis oleh Asti Larasati

// Pick Workflow lain


← Semua picks RSS feed