DEV Community

fejc
fejc

Posted on AI-assisted

How to slice a migration into waves (and what wave 1 should actually be)

Nobody argues for a big-bang migration any more. Everyone says "we'll do it in waves", and then the waves get drawn by whoever is in the room, usually along the lines of the org chart or the source system's table list — and the programme spends the next year discovering that those lines were wrong in a way that's expensive to undo.

I run cloud and data migrations as a delivery manager. The slicing decision is made in the first few weeks, by people who have the least information they will ever have, and it constrains everything afterwards: the sequence, the coexistence costs, the test strategy, what you can decommission and when. It's worth more care than it usually gets.

Here's how I cut them now.

Slice by consumer, not by source structure

The most common bad cut is by technical layer or by source object: wave 1 is the staging layer, wave 2 the transformations, wave 3 the reporting. It's tidy on a slide and it has one fatal property — no wave delivers anything anyone can use. You can't validate it against business numbers, you can't decommission anything, and you can't stop halfway without being worse off than when you started.

The cut that works is by consumer: a group of downstream users or systems whose outputs can be produced end to end on the target platform, validated against the legacy, and then switched over.

That means a wave includes a vertical slice of everything — ingestion, transformation, orchestration, access, and the reports or feeds at the end. It feels like duplicated effort in the plan ("we'll build orchestration in every wave?") and it isn't: you build it once in wave 1 and extend it afterwards. What repeats is not the engineering, it's the validation and the cutover, and those have to repeat anyway.

A good test for a proposed wave: can we decommission something when it's done? If no part of the legacy platform can be switched off, read-only'd or stopped from being fed when a wave completes, you haven't cut a wave — you've cut a project phase and called it a wave.

What wave 1 should be

Wave 1 is not the smallest thing you can find, and it's not the hardest thing you're most afraid of. Both are common choices and both are wrong for the same reason: wave 1's job is to prove the full path, end to end, while you still have room to be wrong.

The criteria I use, in order:

  1. It exercises every component of the target architecture. Ingestion, transformation, orchestration, security model, monitoring, access layer. If wave 1 skips the hardest component, you'll meet it in wave 3 with the schedule already committed.
  2. The outputs are verifiable against something. There exist reports or feeds with numbers the business already knows and trusts, so reconciliation means something. Migrating a dataset nobody checks proves nothing.
  3. The owner is a forgiving one. You want a business owner who can handle a rough edge in week 2 and will tell you about it rather than escalate it. This is a political criterion and it's as important as the technical ones.
  4. It's small enough to redo. Not small in value — small in blast radius. You will change your mind about something structural during wave 1, and you want that change to cost weeks, not quarters.

Say it out loud at kickoff: wave 1 is as much about the method as the data. Its deliverables include the runbook, the reconciliation approach, the cutover checklist and the real timings — the things every later wave inherits.

Plan wave 1 at twice the duration you think

Every multi-wave plan I've seen drawn by committee has waves of equal length. They are never equal. Wave 1 carries all the first-time cost: environment issues, access approvals that nobody knew were needed, the first argument about tolerances, the first dress rehearsal that runs long.

Rule of thumb: wave 1 takes about twice as long as the same scope would in wave 3, and waves 2 onward get faster but flatten out — you don't keep halving. If your plan shows a steadily accelerating programme, it's a wish, not a schedule.

Plan it honestly and say why. A plan that shows wave 1 as long and explains that it's building the machine is much easier to defend than a plan of equal waves that starts slipping in month two.

The dependency that will bite you: shared reference data

Waves are only independent if their data is. The thing that breaks independence most often is shared reference data — the lookups, hierarchies, mappings and master data that several consumers use.

If reference data is migrated inside wave 1 because wave 1 needed it, then wave 2 inherits an invisible dependency: a change to those structures for wave 2's needs can silently alter wave 1's already-signed-off outputs. I've watched this cause a reconciliation failure on a dataset that had been live and correct for four months.

Two ways out, and you should pick one explicitly rather than drifting into neither: treat reference data as wave 0, migrated and frozen under change control before any consumer wave; or make it a permanent workstream that runs across all waves with its own owner, its own regression tests, and a rule that every change is re-validated against every live wave. The first is cleaner; the second is often the only realistic one. What doesn't work is reference data as a side effect of whichever wave needed it first.

Map the other cross-wave dependencies the same way, at the same time: shared ingestion from a single source, a security or entitlement model, and the orchestration layer itself. These are the things that make "wave 3 is independent" false.

Budget for coexistence, because it's the line nobody puts in

Between the first wave going live and the last one decommissioning, you run two platforms. Both cost money. Both need support. Some data flows into both and has to stay consistent, which is its own engineering effort — dual-running isn't free, and it is almost never in the business case.

The number of wave boundaries determines how long that period lasts, so this is where slicing becomes a financial decision and not just a technical one. More waves means lower risk per cutover and a longer, more expensive coexistence. Fewer waves means the opposite. There's no universally right answer, but there is a wrong one: choosing the number of waves without anyone pricing the coexistence period.

When you present the wave plan, present the coexistence cost with it. It changes the conversation from "how do we de-risk this" to "how much de-risking are we buying", which is the conversation the sponsor is actually equipped to have.

Measure in scope items, not percentages

Track each wave's progress as a count of migrated objects against the planned count — datasets, feeds, reports, whatever your unit is — and burn it down. Percentages hide the thing you need to see, which is whether the rate is enough to finish on the committed date.

Two numbers per wave are enough for the programme view: items done vs. planned, and the date forecast from the current rate. Add them up for the programme and you have the only slide the steering committee needs about progress.

One caveat worth stating in the plan: the objects are not of equal size, so the burndown lies locally and tells the truth in aggregate. If you want it to lie less, weight the items — roughly, by a three-point scale decided when the wave is scoped, not retrofitted when the numbers look bad.

Each wave gets its own Go/No-Go, and its own lessons learned

A wave is a mini go-live: readiness, validation, rehearsal, cutover, hypercare, closure. It gets its own Go/No-Go decision against criteria written a week before, and one person owns the call.

And it gets a lessons-learned session that happens before the next wave is planned, not at the end of the programme. This is the single biggest advantage waves have over big-bang, and the one most often wasted: the whole point of doing it five times is that the fifth one is better than the first. If lessons learned is a programme-closure activity, you've paid the cost of waves without collecting the benefit.

The useful version is short. What took longer than planned and by how much. What we validated that didn't need validating. What we didn't validate and should have. What we'll change in the runbook for next time — with the runbook actually edited before the next wave starts.

The short version

Cut by consumer, so each wave switches something off. Make wave 1 the one that proves the whole path and can be redone. Plan it at double. Decide where reference data lives before it decides for you. Price the coexistence. Burn down objects, not percentages. And rewrite the runbook after each wave, while it still hurts.


I keep the wave plan in a single Excel: waves and their scope, a burndown per wave and a programme dashboard that rolls them up, plus the cross-wave dependency view. It's USD 12 on its own: https://deliverykit.gumroad.com/l/migration-roadmap-template

If you want to see how the templates are built first, the weekly status report one is free, pay what you want including zero: https://deliverykit.gumroad.com/l/status-report-template

How did your programme cut its waves — and if you'd cut them again, what would you move?

Top comments (0)