Twenty years of customers, stuck in software you hate.
An illustration of what I build, not a client project. The data is usually the most valuable thing a small business owns, and fear of losing it is the single most common reason people stay on a system they complain about weekly.
If you asked me to do this
- Who it fits
- Anyone leaving legacy software, a spreadsheet estate, or a system being retired
- Scale I have handled
- Tens of thousands of customer records, with their history
- Time
- 1–3 weeks, depending on how messy it is
- Typical range
- $600 – $3,000
Nothing is committed to the new system until you have read a report and said yes to it.
Nobody is afraid of the new software. They are afraid of the move.
The old system holds every customer, every past job and every price ever agreed. It also holds the same person entered four ways, records with no email, and duplicates created by two people on the same afternoon in 2011.
A bad migration is the one mistake you cannot undo by hand. That is why it deserves more care than the software it is feeding, and why the answer is never a single import button. It is also why the cheapest quote you get for this is usually the most expensive one you will pay.
The same loop, until the report is boring.
Export
Whatever the old system will give up — CSV, a database dump, a printed report somebody has to retype. I have worked with all three.
Agree what "the same customer" means
Same email? Same phone? Same name at the same address? Same name only — which is how you end up merging two unrelated businesses. Half an hour on this decides the whole job.
Dry run
The import runs against a copy. Nothing is committed. Out comes a report: imported, merged, needs review, and the exact rows in each pile.
You read the report
You will find things in it that surprise you about your own data. That is normal, and it is the point of doing this before anything is live.
Repeat
Rules adjusted, dry run again, report again. As many times as it takes until nothing in the report is a surprise to anybody. Three rounds is normal; one round means somebody is not reading it.
Commit, with a way back
The real import runs. Rollback stays available until you sign it off, and the whole thing can be re-run from scratch rather than patched.
The import is written to be repeatable on purpose. A migration you can only run once is a migration you cannot fix.
The parts that matter
- Merged, not deleted
- Duplicates are combined and the original rows kept, so a wrong merge is reversible
- Reported first
- Counts for imported, merged and needs-review, reviewed before anything is committed
- Needs-review queue
- Ambiguous cases go to a person instead of being guessed at by a rule
- History preserved
- Past jobs, invoices and notes stay attached to the right customer
- Repeatable
- The import can be run again from scratch, so a fix means re-running rather than hand-editing
- Rollback
- Available until you sign it off
What comes out of an old system, and what it is for.


If the old system still does the job and the only complaint is that it looks dated, moving the data is an expensive way to buy a new interface.
Migrate when the old system is being switched off, when it cannot talk to anything else, or when it is stopping you doing something you need to do. Not because it is ugly.
Is your data the thing keeping you on old software?
Tell me what system it is in and roughly how many records. I will tell you in writing whether the move is straightforward, awkward or genuinely risky — free.