Core Concepts
New to database migrations? This page explains the mental model mongo-migrate-kit is built on. Five minutes here makes every other page click.
What is a migration?
A migration is a small, versioned script that makes a single change to your database — add an index, rename a field, backfill data — and knows how to undo that change.
You commit migrations alongside your code. When a teammate pulls your branch or a deploy runs, the same change is applied to their database, in the same order, exactly once. No more "works on my machine" schema drift.
Each migration has two halves:
up— apply the change (create the index).down— revert it (drop the index).
The changelog
mmk records every migration it has applied in a collection called _mmk_migrations (the changelog). Before running, it reads this collection to know what's already done, so a migration is never applied twice.
Each record stores an audit trail: when it ran, how long it took, its checksum, the environment, who ran it, and its batch.
History is never deleted
Rolling a migration back doesn't remove its record — it sets the record's status to reverted and stamps revertedAt. The full history is always preserved.
Pending vs. applied
At any moment, every migration file is in one of two states:
- Pending — the file exists on disk but isn't in the changelog yet.
- Applied — it's recorded in the changelog as run.
mmk up applies pending migrations; mmk status shows you the full picture.
Ordering
Migrations run in ascending filename order. That's why files are prefixed with a timestamp (20260605143021-add-users-index.js) — it guarantees a deterministic, chronological order across your whole team. Never reorder or rename an applied migration.
Batches
Every time you run mmk up, all the migrations that run together are tagged with the same batch number. Batches are how rollbacks know what "the last thing I did" was:
mmk downreverts the whole last batch (everything from the most recentmmk up).mmk down --batch 3reverts a specific batch.mmk down --steps 2ignores batches and reverts the last 2 migrations individually.mmk up --stepputs each file in its own batch, so you can peel them off one at a time later.
Think of a batch as "one deploy's worth of migrations."
Safety mechanisms
Two things protect you from common production mistakes:
- Lock — before writing,
mmkacquires an atomic lock in MongoDB so two deploys can't run migrations at the same time. It auto-expires and renews while a long migration runs. Seemmk unlock. - Checksum —
mmkstores a SHA-256 hash of each file when it runs. If a file is edited after it was applied,mmk statusflags it as a mismatch, and--strictmode will refuse to continue — catching accidental edits to history.
Putting it together
A typical run looks like this:
mmk up
├─ acquire lock
├─ read changelog → find pending files
├─ for each pending file (in order):
│ ├─ verify checksum
│ ├─ run up()
│ └─ record it in the changelog (batch N)
└─ release lockReady to do it for real? → Tutorial