Skip to content

Why Migrations Matter — Complete Guide

DodaTech Updated 2026-06-28 6 min read

In this tutorial, you will learn about Why Migrations Matter. We cover key concepts, practical examples, and best practices to help you master this topic.

Learn why database migrations matter: solve schema drift, enable team collaboration, support CI/CD pipelines, provide rollback capability, and ensure reproducible database states across environments.

What You Learn

You will understand the problems migrations solve: schema drift between environments, collaboration conflicts in team development, automated deployment requirements, rollback capability for failed releases, and reproducible database states for testing.

Why It Matters

Skipping migrations causes real production incidents. A developer adds a column locally, deploys to production without the column, and the application crashes. Another developer drops a column, and the reporting team's queries fail. Migrations prevent these issues.

Real-World Use

DodaTech experienced a production outage when a developer manually added a NOT NULL column to a table with existing NULL values. The Migration was never written, so staging worked but production crashed on deploy. After adopting migrations, zero schema-related production incidents occurred in 18 months.

Schema Drift

// Schema drift scenario
const environments = {
    development: {
        users_table: ['id', 'name', 'email', 'phone'],
        // Developer added phone locally, never committed migration
    },
    staging: {
        users_table: ['id', 'name', 'email'],
        // Staging does not have phone column
    },
    production: {
        users_table: ['id', 'name', 'email'],
        // Production also missing phone column
    },
};

// When the developer deploys code expecting 'phone' column
await db.query('SELECT phone FROM users WHERE id = $1', [userId]);
// Error: column "phone" does not exist

Expected output: Schema drift causes runtime errors. The application expects columns that do not exist in production. Manual schema changes are not propagated. Migrations ensure all environments have the same schema.

Team Collaboration

// Two developers making changes simultaneously
// Developer A: Adds 'phone' column
const migrationA = '001_add_phone_to_users';

// Developer B: Adds 'avatar_url' column
const migrationB = '001_add_avatar_to_users';

// Conflict! Both are migration 001

// With timestamp naming:
const migrationA_ts = '20260628_120000_add_phone';
const migrationB_ts = '20260628_130000_add_avatar';
// No conflict - different timestamps, applied in order

Expected output: Sequential migration numbering causes conflicts in team development. Timestamp-based naming avoids conflicts. Each migration is applied in chronological order regardless of creation time.

CI/CD Integration

# CI/CD pipeline with migrations
stages:
  - test
  - migrate
  - deploy

test:
  script:
    - npm test
    - # Tests run against migrated test database

migrate:
  script:
    - alembic upgrade head
  environment: production
  # Only runs migrations to production database

deploy:
  script:
    - kubectl apply -f deployment.yaml
  environment: production
  needs: [migrate]
  # Application starts after migrations complete

Expected output: CI/CD pipeline runs migrations as a separate stage before deployment. If migrations fail, the deployment is aborted. The application starts against the correct schema version.

Rollback Capability

-- Before migrations: rollback is painful
-- Step 1: Remember what changed this release
-- Step 2: Write reverse SQL manually
ALTER TABLE users DROP COLUMN phone;
-- Step 3: Hope it works under pressure

-- With migrations: rollback is one command
alembic downgrade -1
-- Reverts the last migration automatically

-- Rollback to a specific version
alembic downgrade abc123def456
-- Reverts to the specified migration version

Expected output: Without migrations, rollback requires manual reverse SQL written under stress. With migrations, rollback is a single command. The downgrade function in each migration knows exactly how to revert.

Reproducible Environments

# Fresh development environment setup
git clone repo
cp .env.example .env
docker-compose up -d db
alembic upgrade head
# Database is now at the exact same schema as production

# Fresh test environment
docker-compose -f test.yml up -d db
alembic upgrade head
# Test database matches production schema

# Reviewing a PR
git checkout feature-branch
alembic upgrade head
# Local database now has the feature's schema changes

Expected output: Any environment can be brought to the current schema by running all migrations. Fresh developer machines, CI runners, and staging environments get the exact same schema. Reproducible environments eliminate it-works-on-my-machine issues.

Without vs With Migrations

Aspect Without Migrations With Migrations
Schema changes Manual SQL in each environment Version-controlled migration files
Team collaboration Manual coordination, conflicts Timestamped files, auto-apply
Rollback Manual reverse engineering One-command downgrade
Fresh setup Manually recreate schema Automatically apply all migrations
Audit trail None Complete history of changes
CI/CD Cannot automate Seamless pipeline integration

Common Mistakes

1. Using Migrations Only for Production

Skipping migrations in development and staging causes those environments to drift. Run migrations everywhere. Automate them in CI/CD for test and staging environments too.

2. Ignoring Migration Failures

A migration that failed but was ignored leaves the schema in an unknown state. Always investigate and fix failed migrations immediately. Never apply additional migrations until the failure is resolved.

3. No Migration Review

Migrations change data structure. One wrong migration can delete data. Review migrations in pull requests like code changes. Check for: data loss, long-running queries, and missing down migrations.

4. Long-Running Migrations in Production

Migrations that lock tables for minutes cause downtime. Plan long migrations during maintenance Windows. Use online schema change tools (pt-online-schema-change, gh-ost) for zero-downtime migrations.

5. Not Checking Migration Order

Migrations must be applied in order. A migration that depends on a column created in a later migration fails. Number migrations sequentially. Review migration order in dependency chains.

Practice Questions

1. What is schema drift and why is it dangerous?

Schema drift occurs when environments have different schema versions. Code that works in development fails in production due to missing columns, tables, or constraints. Drift causes unexpected runtime errors.

2. How do migrations support CI/CD pipelines?

Migrations are executed as a pipeline stage before deployment. If migrations succeed, the application deploys against the correct schema. If migrations fail, the deployment is aborted.

3. Why is one-command rollback important?

Quick rollback minimizes downtime. In an incident, every minute counts. One-command rollback reverts the schema without manual investigation. The downgrade function is already written and tested.

4. How do migrations help with team collaboration?

Timestamp-based naming avoids conflicts. Each migration is a small, focused change. Migration PRs are reviewed like code. Applied migrations are never edited, ensuring consistency.

Challenge

Document your current projects database change Process. Identify: how schema changes are currently made, whether migrations are used, rollback procedure, fresh setup process, and CI/CD integration. Compare against the migration approach. Propose a migration adoption plan.

FAQ

Can I use migrations with an existing database?

Yes. Create an initial migration that captures the current schema. This is called bootstrapping. The migration tool marks this as already applied. New migrations are added normally.

Do migrations work with shared databases?

Shared databases (multiple services using the same DB) require coordination. Each service should own its schema. Use database schemas or table prefixes to separate ownership.

How often should I run migrations?

Run migrations on every deployment. Automated migration execution ensures schema and code are always in sync. Running less frequently creates drift between releases.

What if I need to revert a migration that already ran?

Use the down migration. Run the downgrade command. Create a new migration if the revert is temporary and you plan to re-apply later.

Can I have too many migrations?

Many migrations are normal for long-lived projects. Consider squashing old migrations into a single baseline to speed up fresh setups. Keep the last 50-100 migrations unsquashed.

Mini Project: Migration Adoption

Take an existing project without migrations: create a baseline migration capturing the current schema, set up a migration tool (Alembic, Flyway, or Knex), run the initial migration against a test database, create a new migration for a schema change, and set up CI/CD pipeline to run migrations before deployment.

What's Next

Now that you understand why migrations matter, learn about Migration File Structure to write clean, maintainable migration files.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro