River
Y CombinatorBacked by Y Combinator
FREE TEMPLATE

System Migration Plan Template

Four documents and four sheets that size the freeze window from the target platform's own import ceilings before anyone agrees a date.

Free download  ·  No account needed

Migration Plan

1. The window, computed

The business has agreed a freeze of   hours, from   to  , with   as the first hour of real use.

Three inputs decide whether it can hold the load, and all three are knowable weeks out.

Record counts per objectfrom the source, on the reconciliation’s own scope filter
Published ingest ceilingsrows per file, rows per rolling day, concurrency, the API path
Measured throughputone large file loaded end to end, including post-upload processing

The critical path

PhaseObjectsRowsFilesHours
1
2
3
4
5

A phase is not a team

A child object cannot load before the parent it references exists in the target, because the reference is resolved by lookup at load time. Only objects inside one phase run together, and the concurrency ceiling caps even that.

2. The decision that number forces

Filled in once the phase table has a total. If the critical path exceeds the window, name the object carrying most of it before proposing anything else.

Every cutover plan you can download is a task table: task, dependency, team, owner, planned start, status. The dependency column is free text and the window length is a number somebody chose. So the two facts that decide whether the plan is possible get discovered in a rehearsal that costs a weekend, or at three in the morning on the Saturday. Both are arithmetic. Record counts per object, the target platform's published ingest ceilings, and the dependency order among the objects give you a critical path in hours.

Norwood Filtration had a 36 hour freeze and 22,377,200 rows across six objects. Its target caps one import at 1,048,576 rows, the whole day at 10,000,000, and concurrency at two large loads whatever the size of the team. Phased on real references that is 55.28 hours, and activity history is 51.94 of them. It is 96.5% of the rows and none of the configuration, which is why it never came up in a design session. Loading it after go-live leaves 3.34 hours.

The second half is the gate. Counts reconciled at 100.0% on all six objects while pipeline was short by 1,438,760 dollars, because 2,140 opportunities held in euros, pounds and Canadian dollars loaded at face value in the corporate currency. A two-pass field mapping shows why: the currency column had no target row. So every object reconciles on a count, a sum and a completeness rate.

The window this data supports, and the gate that caught what the counts missed

The Load Order, the Data Validation sheet, and the Issue Log the window produces.

Load Order

Norwood Filtration, legacy on-premise CRM to a cloud CRM.

PhObjectRecordsFilesDepends onHours
1Accounts41,8001nothing0.20
2Contacts268,4001Accounts1.25
3Opportunities62,1001Accts, Contacts0.29
3Cases190,3001Accts, Contacts0.89
4Order lines214,6001Opportunities1.00
5Activity history21,600,00021all of the above51.94
Critical path, everything in the freeze55.28 h
Rolling daily ceiling floor, independent of throughput53.71 h
Window the business agreed36.00 h
Phases 1 to 4 only, activity history deferred3.34 h

Phase 3 costs 0.89 hours, not 1.18. Two objects, two lanes, so the phase costs the longer of the two rather than the sum. Phase 5 is 100.93 hours of load listed onto 2 lanes, which is 51.94 hours of wall clock and the entire reason the window failed.

Activity history is 96.5% of the rows and none of the configuration, so it never comes up in a design meeting.

Data Validation

Three measures per object. Every count passed on the first attempt.

ObjectMeasureSourceTargetVarVerdict
AccountsCount41,80041,8000.000%Pass
ContactsCount268,400268,4000.000%Pass
OpportunitiesCount62,10062,1000.000%Pass
OpportunitiesSum, pipeline184,214,320182,775,5600.781%FAIL
OpportunitiesFill, Currency62,1000100.0%FAIL
CasesFill, Source190,300185,1822.689%FAIL
Order linesSum, ext price47,318,90447,318,9040.000%Pass
OpportunitiesSum, re-run184,214,320184,214,3200.000%Pass

1,438,760 dollars. 2,140 of 62,100 opportunities, which is 3.45% of the records, were held in euros, pounds and Canadian dollars. The currency column had no target field, so every one of them loaded at face value. The tolerance was 0.5% and the variance was 0.781%.

Cases at 97.31% filled is the same failure on a smaller field: three source origin values had no target option, so 5,118 cases imported with it blank. The record arrived. One field in it did not.

A count is evidence that rows arrived. It is not evidence that anything in them is right.

Issue Log

One row per event, raised as it happens, keyed to the runbook row.

RowWhat happenedFound byRecsBlocks go
C10Pipeline short 1,438,760Sum gate2,140Yes
C11Multi-currency enabled, 3 rates setFix3Yes
C13Re-run reconciles at 100.000%Sum gate2,140Closed
C19Case Source 97.31% filledFill gate5,118Accepted
C1917 address lines truncated at 60 charsLength check17Accepted
A241 writes landed after the freeze startedAudit sweep41No

Rows C11 to C13 took 1 hour 50 minutes out of the 2 hour 20 minute buffer that sits before the go decision. Buffer at the end of a window protects nothing: by the time you reach it the decision is already made.

Row A2 is not on the Monday. 12 of those 41 writes arrived more than 24 hours after the freeze started, because a sender retrying a failed delivery does not stop when an endpoint is disabled.

Every accepted exception carries an owner and a date. An exception with neither is a defect wearing a decision.

What's in the pack

01

Load Order

Records, files, dependency, phase and hours per object, with the phase makespan computed from the concurrency lanes rather than summed.

02

Field Mapping

A row per source column including the ones with no target, each carrying its failure mode and the post-load check that would catch it.

03

Data Validation

Count, sum and field completeness per object, each with its scope filter, because a variance only means something when both sides used the same one.

04

Issue Log

One row per event with the runbook row it happened on, and a Found By column that tells the next cutover which gate earned its place.

05

Migration Plan

The window arithmetic, the scope with its deliberate exclusions, the gate thresholds and who signs each one, and the roles for the window.

06

Cutover Runbook

Every step with an id, an owner and a predecessor, a gate after every load rather than one at the end, and the buffer sitting before the go decision. A live sync that fails after go-live gets reconciled separately.

07

Rollback Plan

The three windows rollback means different things in, what each one costs in hours and re-entered records, and the row where it becomes a merge.

08

Comms Plan

Every message with a send time and a drafted body, including the fallback announcement nobody writes in advance and the all-clear that names what is missing.

How to use it

  1. 1

    Open in River, or take it blank

    Open the pack in River and hand it your counts and field export, or download the Word documents and CSV sheets and do the arithmetic yourself.

  2. 2

    Send three things

    Record counts per object with the in-scope filter, the target platform and edition, and the source system's field export. A measured load rate too, if a rehearsal produced one.

  3. 3

    Size the window before anything else

    The ceilings and the dependency graph turn the counts into a critical path in hours. If it exceeds the window, the object carrying most of it gets named first.

  4. 4

    Set the gates, then run them

    Every object gets a count, a sum and a completeness rate with a named signer. Failures land in the Issue Log with a records-affected count, an owner and a date.

Frequently asked questions

Is this template free?

Yes. The zip is Word documents and CSV sheets, no account and no card. Edit with AI reads your counts and field export, computes the window and fills the sheets. Only need the Comms Plan, timed against a runbook you already have? A standalone tool builds just that. Everything else sits in the template library.

What format are the downloaded files?

Word (.docx) for the four documents, CSV (.csv) for the four sheets, zipped together. Excel, Numbers and Google Sheets open the sheets straight off the download, and the plan and runbook open in Word or Pages. There is nothing to convert.

Does it work for a target platform other than a CRM?

Yes. The arithmetic needs a per-object record count, published ingest ceilings and a dependency graph, and an ERP, a helpdesk or a billing system all have those. Designing the target's object model is separate work, covered by the CRM implementation plan. This pack assumes the target already exists.

What if I have no measured load rate yet?

The window gets computed on a stated assumption and re-run once a rate exists, which is the honest version. Everything else holds: the file counts, the dependency phases and the rolling-daily-ceiling floor are all read off documents rather than measured, and the floor alone often settles the question.

Why does the validation sheet ask for a sum as well as a count?

Because the load failures that lose data mostly complete. An unmapped column imports empty, an unrecognised picklist value imports blank, and an amount whose currency never mapped imports at face value. All three reconcile at 100.0% on a count, and only a sum finds the third.

The source data is a mess. Should I clean it first?

Clean before the freeze or not at all, and size it before committing. Cleaning inside a window is unreviewed data entry by a tired person, which is why the pack quarantines rejected rows instead. A scoped CRM audit prices that work first.

What does 'Edit with AI' actually do?

It signs you up, installs this pack as a private workspace, and puts the agent in front of the sheets with nothing in them. Then you send the counts, the field export and the target edition, and the first thing it returns is hours needed against hours agreed.

Find out whether your freeze window can hold the load

Take the Word documents and CSV sheets blank, or open this exact pack in River and get the critical path in hours first.

Edit with AI