Every data migration horror story starts the same way: "we'll just export from the old system and import into the new one over the weekend." Then Monday comes, half the customer balances are wrong, the sales team can't find their open deals, and the old system is already turned off. Migrations go bad not because moving data is hard, but because people treat it as an afterthought to the shiny new software. The move itself deserves a plan, and the plan is not complicated. It just has to actually exist.
Here's the plan we use, whether it's moving a CRM, an accounting system, an inventory database, or years of files.
Step one: map every field
Before anything moves, build a mapping document: a spreadsheet with one row per field in the old system and where it lands in the new one. "Customer Name" maps to "Account Name." "Phone2" maps to "Mobile." Do this and three uncomfortable truths surface immediately:
- Fields with no destination. The old system tracked something the new one has no place for. Decide now: add a custom field, stuff it in a notes field, or consciously drop it. "We'll figure it out later" means losing it.
- Destinations with no source. The new system requires fields the old one never had. Somebody has to decide the default.
- Fields that don't quite match. Old system: one address field. New system: street, city, state, ZIP as separate fields. That's parsing work, and it's better discovered on paper than at midnight during cutover.
The mapping document becomes the contract for the whole migration. Every later argument gets settled by pointing at it.
Step two: clean before you move
Old systems accumulate garbage: duplicate customers, test records named "asdf," phone numbers in four formats, addresses in the name field, customers who went out of business in 2015. Migrating garbage means paying to move it and then living with it in the new system, where it makes everyone trust the new tool a little less.
Clean in the old system or in the export, before import. Deduplicate, standardize formats, archive dead records instead of migrating them. This is also the moment to decide how much history to bring. Seven years of closed invoices might belong in an archive export you keep on file, not in your new system's active database.
Step three: dry runs on copies, never on the real thing
This is the step that prevents the horror story. Take a full copy of the old system's data, run the entire migration into a test environment of the new system, and see what breaks. Something always breaks: an import that chokes on a stray comma, dates that come across in the wrong format, a required field that's blank in 300 records.
Fix the process, then run it again from scratch. Repeat until a dry run completes cleanly end to end. The whole point is that by cutover day, the migration is a rehearsed procedure, not an experiment. If your migration has never been run start to finish on a copy, it has never been tested at all.
Step four: validate with counts and spot checks
After each dry run (and the real one), prove the data arrived intact instead of assuming it:
- Record counts. 4,812 customers out of the old system should be 4,812 in the new one (minus whatever you intentionally archived, and you know that number from step two). Same for invoices, contacts, products, every table.
- Sum checks. Total accounts receivable in the old system should equal total AR in the new one, to the penny. Totals catch truncated imports and mangled numbers that counts miss.
- Spot checks by humans. Have the people who use the data daily pull up twenty records they know well: the biggest customer, the weird account, the one with the long history. They'll spot wrongness a query never would.
Write the expected numbers down before the migration and check them after. A validation you improvise afterward tends to confirm whatever happened.
Step five: plan the cutover, and the retreat
Cutover is the switch from old to new, and it needs a written runbook: who does what, in what order, starting when. Freeze changes in the old system first (anything entered after the final export is lost, so pick a quiet window and tell everyone). Run the rehearsed migration, run the validation checks, then have your spot-checkers sign off before anyone announces success.
And decide the rollback rule in advance: if validation fails past a certain point, everyone goes back to the old system and you try again another day. That is only possible if the old system stays intact and untouched. Keep it running, read-only if the software allows it, for at least a month or two after cutover. The old system is your rollback plan and your reference for "wait, what was this customer's setting before?" Do not cancel it, wipe it, or let the subscription lapse until the new system has survived a full business cycle, including a month-end close.
How to know it's done right
The counts matched, the totals matched to the penny, and the users signed off before go-live rather than filing surprises afterward. Cutover felt boring, because it was the fourth time the procedure ran, just the first time it counted. And weeks later, when someone asks about an old record, the answer comes from the new system, not from a scramble to resurrect the old one. Boring is the goal. The horror stories all start with a weekend and a hunch.
Stuck on this, or want it done for you? That's the job.
Email us →