Template · Sheet 4 of 6

Migration spec

For data and system migrations where failure is not an option. This template forces the two things migrations most often lack: a phased plan with exit criteria per phase, and a rollback procedure decided before anything moves.

When to use this

Schema changes on live data, database or queue migrations, provider switches, major version upgrades with data formats, and any cutover where "just revert the deploy" wouldn't undo the damage. If the migration touches production data, it gets a spec.

01 — Anatomy

Section-by-section, annotated

§1 Current state & target state

Exact diagrams of before and after: schemas, volumes, consumers. The delta between them is the migration's scope. Good looks like: a reviewer can point at any field and say where it lives before and after.

§2 Phased plan

The classic expand–migrate–contract sequence (or your equivalent), each phase with entry criteria, steps, and exit criteria. No phase starts until the previous phase's exit criteria are met. Good looks like: the migration can pause safely between any two phases.

§3 Backfill strategy

How existing data moves: batching, idempotency, rate limiting, resume behavior. Backfills fail halfway — the spec says what happens then. Good looks like: re-running the backfill is always safe.

§4 Dual-write / compatibility window

How old and new systems coexist during the transition, and for how long. The compatibility window is the migration's insurance policy. Good looks like: a dated plan for ending dual-write, not "we'll remove it later."

§5 Verification

Row counts, checksums, canary queries, and shadow-traffic comparisons that prove the migration worked — run per phase, not just at the end. Good looks like: automated checks with pass/fail thresholds, checked into the repo.

§6 Rollback plan

Exact rollback conditions, the procedure, who decides, and how long it takes. Written and rehearsed before the migration begins. Good looks like: a runbook someone half-asleep could follow at 3 a.m.

02 — The template

Copy it, phase it, verify it

migration-spec.md

# Migration Spec: [What is migrating, from → to]

| Field      | Value              |
|------------|--------------------|
| Owner      | [Name]             |
| Status     | Draft / In review / Approved / Migrating / Done |
| Risk level | [Low / Medium / High] |
| Created    | [YYYY-MM-DD]       |

## Revision block

| Rev | Date       | Author | Description            |
|-----|------------|--------|------------------------|
| 0.1 | [YYYY-MM-DD] | [Name] | Initial draft          |

## 1. Current state

[Schema / architecture as it exists today. Include volumes: rows,
requests/day, storage. Link diagrams.]

## 2. Target state

[Schema / architecture as it must exist after. Call out every delta
from section 1 — nothing migrates by accident.]

## 3. Goals and non-goals

- Goals: [e.g. zero-downtime cutover, no data loss]
- Non-goals: [e.g. performance optimization of the new system — separate spec]

## 4. Phased plan

### Phase 1 — Expand
- Entry criteria: [What must be true to start]
- Steps:
  1. [e.g. Add new columns/tables; deploy dual-write code]
- Exit criteria: [e.g. dual-write live for 7 days, error rate under X]

### Phase 2 — Migrate
- Entry criteria: [Phase 1 exit met]
- Steps:
  1. [e.g. Backfill historical data]
- Exit criteria: [e.g. checksums match, canary queries green]

### Phase 3 — Contract
- Entry criteria: [Phase 2 exit met + soak period]
- Steps:
  1. [e.g. Cut reads to new system; drop old columns]
- Exit criteria: [e.g. old path fully removed, monitors clean for 14 days]

## 5. Backfill strategy

- **Batching:** [Batch size, e.g. 10k rows]
- **Idempotency:** [How re-runs are safe — key on natural key, upsert, ...]
- **Rate limiting:** [Throttle to protect live traffic]
- **Resume:** [Checkpointing — where it resumes after failure]
- **Estimated duration:** [Based on volume and rate]

## 6. Dual-write / compatibility window

- **Window:** [Start date → planned end date]
- **Conflict resolution:** [Which system wins when they disagree]
- **Cleanup:** [What removes the old path, and when]

## 7. Verification

| Check | Phase | Pass threshold |
|-------|-------|----------------|
| [Row counts old vs new] | 2 | [Exact match] |
| [Checksum sample] | 2 | [100% of sampled rows] |
| [Canary query results] | 2, 3 | [Diff under X] |
| [Shadow traffic comparison] | 2 | [Error delta under X] |

## 8. Rollback plan

- **Rollback triggers:** [Metric thresholds or events that abort the migration]
- **Decision maker:** [Name — who calls it]
- **Procedure:**
  1. [Step one]
  2. [Step two]
- **Time to rollback:** [Estimated]
- **Point of no return:** [After which step rollback is no longer possible]

## 9. Comms and schedule

- **Migration window:** [Date/time, timezone]
- **Stakeholders notified:** [Who, when]
- **Status updates:** [Where progress is posted during the migration]
Template revision block
RevDateDescription
1.02026-09-20Initial publication.

← Prev: Bugfix spec · Gallery · Next: Refactor spec →