Skip to main content

Flyway Undo Alternative in Atlas

Flyway's undo feature allows you to revert applied migrations by running manually written undo scripts. While this sounds useful in theory, in practice these pre-written undo (down) files come with significant limitations: they must be written before the migration is applied, they assume the migration succeeded fully, and they're rarely tested in production scenarios.

Atlas takes a fundamentally different approach with its migrate down command. Instead of requiring pre-written undo files, Atlas computes rollback plans dynamically based on the actual state of your database. This means Atlas can handle partial failures, work across non-transactional DDL operations, and provide built-in safety checks - all automatically.

Quick Comparison

CapabilityFlyway UndoAtlas Migrate Down
Auto-generated undo scripts✅ Enterprise only (via Flyway Desktop / Redgate Compare)✅ Always, computed dynamically
Requires manual undo filesYesNo
Works after partial/failed migration❌ No✅ Yes
Handles non-transactional DDL⚠️ Limited✅ Yes
Built-in safety checks⚠️ Manual✅ Automatic
CI/CD friendly⚠️ Limited✅ Fully supported
Available in free tier❌ No✅ Yes

The Problem with Pre-written Undo (Down) Scripts

They Assume Perfect Success

Flyway's undo files are written before you know whether the migration will succeed. Consider this scenario:

V002__add_user_columns.sql
ALTER TABLE users ADD COLUMN email VARCHAR(255);
ALTER TABLE users ADD COLUMN phone VARCHAR(50);

The corresponding undo file would be:

U002__add_user_columns.sql
ALTER TABLE users DROP COLUMN phone;
ALTER TABLE users DROP COLUMN email;

But what if the migration fails after adding email but before adding phone? Running the undo script will fail because phone doesn't exist. Your database is now in an unknown state, and you need manual intervention to fix it.

Production Usage Limitations

Undo files are rarely used in production as-is, if ever. Teams often maintain thousands of them "just in case," but when failures occur, these files either don't work (due to partial application) or cause data loss that teams aren't willing to accept.

As detailed in our blog post The Myth of Down Migrations, even teams at companies like Meta with thousands of down files, they were virtually never used in production environments.

Incompatible with CD/GitOps Workflows

CD/GitOps workflows assume you can roll back to any previous version by deploying artifacts from an earlier commit. But those earlier commits don't contain the undo files needed to revert database changes - those files only exist in future commits.

This creates a mismatch between application rollbacks and database rollbacks, forcing teams to handle database reversions manually.

How Atlas Migrate Down Works

Atlas's migrate down command computes rollback plans based on your database's actual current state. Here's what makes it different:

State-Aware Planning

Instead of pre-written scripts, Atlas:

  1. Inspects your current database state
  2. Determines what migrations were applied (fully or partially)
  3. Computes the exact sequence of statements needed to reach the target version
  4. Validates the plan with automatic safety checks, and follows your team policies

Partial Failure Handling

For databases that support transactional DDLs (like PostgreSQL), Atlas wraps the entire rollback in a transaction. If anything fails, the database returns to its pre-rollback state.

For databases without transactional DDL support (like MySQL), Atlas reverts changes statement-by-statement, updating the revisions table after each successful step. If a failure occurs midway, you can simply re-run Atlas to continue from where it stopped.

Built-in Safety Checks

By default, Atlas runs pre-migration checks before executing any rollback. For example, before dropping a column, Atlas verifies that it contains no data:

-- checks before reverting version 20240305171146
-> SELECT NOT EXISTS (SELECT 1 FROM `logs`) AS `is_empty`
-- ok (50.472µs)

-- reverting version 20240305171146
-> DROP TABLE `logs`
-- ok (53.245µs)

If the check fails, the rollback is aborted, preventing unintended data loss.

Basic Usage

Reverting the Last Migration

To revert the most recently applied migration:

atlas migrate down \
--dir "file://migrations" \
--url "mysql://root:pass@localhost:3306/example" \
--dev-url "docker://mysql/8/dev"

Reverting Multiple Migrations

To revert a specific number of migrations:

atlas migrate down 3 \
--dir "file://migrations" \
--url "mysql://root:pass@localhost:3306/example" \
--dev-url "docker://mysql/8/dev"

Reverting to a Specific Version

To roll back to a particular version:

atlas migrate down \
--to-version 20240301000000 \
--dir "file://migrations" \
--url "mysql://root:pass@localhost:3306/example" \
--dev-url "docker://mysql/8/dev"

Reverting to a Git Tag

If you're using Atlas Cloud's Schema Registry, you can tag migration directory states and revert to those tags:

atlas migrate down \
--to-tag "v1.2.0" \
--dir "file://migrations" \
--url "mysql://root:pass@localhost:3306/example" \
--dev-url "docker://mysql/8/dev"

Production Safety Features

Dry Run Mode

Preview what Atlas will do without executing any changes:

atlas migrate down --dry-run \
--dir "file://migrations" \
--url "mysql://root:pass@localhost:3306/example" \
--dev-url "docker://mysql/8/dev"

This shows the exact SQL statements that will be executed and which safety checks will run.

Approval Workflows

For production environments, Atlas Cloud supports approval workflows. When a migrate down operation is triggered (via CLI or GitHub Actions), it can be configured to wait for approval from designated reviewers before execution.

This ensures that potentially destructive operations are reviewed by multiple team members before being applied.

Review Required

CI/CD Integration

GitHub Actions

Atlas provides a dedicated GitHub Action for migrate down operations. This allows you to:

  1. Connect your migration directory to the Schema Registry
  2. Set up a workflow that can be triggered on-demand or by tagging a commit
  3. Require approval before execution
  4. Apply the rollback once approved
name: Rollback Database
on:
workflow_dispatch:
inputs:
tag:
description: 'Migration tag to roll back to'
required: true

jobs:
rollback:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ariga/atlas-action/migrate/down@v1
with:
url: ${{ secrets.DATABASE_URL }}
to-tag: ${{ github.event.inputs.tag }}
dir: migrations

See the Atlas Down Action documentation for details.

Comparison with Flyway Workflows

Flyway Undo Workflow

  1. Write your migration file: V001__add_table.sql
  2. Write the corresponding undo file: U001__add_table.sql
  3. Test the undo file separately (often skipped)
  4. Apply migration: flyway migrate
  5. If rollback needed: flyway undo (Teams/Enterprise only)
  6. Undo file assumes full success

Limitations:

  • Undo files must be written manually for every migration
  • No automatic safety checks
  • Doesn't handle partial failures
  • Undo feature requires Enterprise license
  • Rarely tested in production-like environments

Atlas Migrate Down Workflow

  1. Define your desired schema in code (HCL, SQL, or ORM)
  2. Generate migration: atlas migrate diff
  3. Apply migration: atlas migrate apply
  4. If rollback needed: atlas migrate down
  5. Atlas automatically computes the rollback based on database current state

Features:

  • No need for manual undo (down) files to maintain
  • Automatic safety checks prevent data loss
  • Handles partial failures gracefully
  • Works in both free and paid tiers
  • Integrates with approval workflows for production environments

Use Cases

Local Development

Iterate on schema changes without manually writing undo (down) scripts:

# Try a schema change
atlas migrate diff --edit

# Apply it
atlas migrate apply --env local

# Changed your mind? Revert it
atlas migrate down --env local

# Delete the migration file
atlas migrate rm 20240305171146

Staging/Test Environment Resets

Reset a test environment to a specific schema version for testing:

atlas migrate down --to-version 20240301000000 --env staging

Production Rollbacks

Roll back a production deployment that introduced database issues:

# Preview the rollback
atlas migrate down --dry-run --env production

# Execute with approval (via Atlas Cloud)
atlas migrate down --env production

Migration from Flyway

If you're currently using Flyway with undo files, migrating to Atlas is straightforward:

  1. Import your existing migrations using Atlas migration import:

    atlas migrate import \
    --from "file://migrations?format=flyway" \
    --to "file://atlas-migrations"

    Note: Undo files (U__ prefix) are not imported because Atlas computes them dynamically.

  2. Test migrate down on a development database:

    atlas migrate down --env dev
  3. Remove undo files from your repository - they're no longer needed!

For a complete migration guide, see Migrating from Flyway to Atlas.

Summary

Atlas's migrate down command provides an alternative to Flyway's undo scripts by:

  • Computing rollback plans dynamically based on current database state
  • Handling partial migration failures automatically
  • Running safety checks before executing destructive operations
  • Supporting both transactional and non-transactional DDL databases
  • Integrating with approval workflows and CI/CD pipelines
  • Working with GitOps workflows through version tagging

Read More