In almost every project where we replace an existing system, the hard conversation is not about features. It is the day someone has to decide what happens to the nine years of information already inside.
That part rarely carries its real weight in a quote. It shows up as one line, "data migration", and everyone assumes it is a technical step at the end, something like copying files between folders. Then it turns out to be the work that determines whether the new system starts with the team's confidence or with a permanent suspicion that the numbers do not add up.
It is worth understanding before you sign, because it is also one of the biggest drivers of both price and schedule in a build. If you want the full picture of what moves a quote, we cover it in what custom software costs.
It is not copying, it is translating
The old system and the new one do not think alike. That is where the work is.
In the old one, a customer and a supplier may live in the same table because somebody had to solve something on a Tuesday. There is a notes field where people recorded, for years, things that are their own fields in the new system: payment terms, the alternate contact, the warning that this client gets invoiced under a different tax ID. There are dates stored as text in three formats because the form changed twice.
None of that is wrong. It is what happens to a system that served for a decade. But it means migration is not a transfer, it is a translation, and every translation requires decisions. Each decision needs somebody from the business to make it, not somebody from development to guess it.
What gets migrated, and what does not
This is a business decision, and it is the first one we ask to settle.
Not all history has to enter the new system. The useful question is not "how many years do we want", which is almost always answered with "all of them", but three narrower ones: what information is genuinely used in daily operations, what has to remain available because of record-keeping obligations, which your accountant or legal advisor defines and we do not, and what is only there for peace of mind.
The first two get migrated. The third is almost always better served another way: a queryable archive, a read-only copy of the old system, a complete documented export handed over. It costs a fraction and serves the same purpose, because nobody is going to operate on 2014 data.
One distinction helps organize this. Balances, catalogs and master data have to be exact and complete, because the new system will calculate on top of them. Historical transaction detail is reference: it needs to be faithful and queryable, not necessarily inside the same module.
Dirty data is the norm, not the exception
Every migration surfaces what was already there. Duplicates nobody had counted, customers spelled four different ways, free-form phone numbers, incomplete records the old system allowed and the new one, rightly, does not.
There is a boundary worth drawing early: a developer can detect and report duplicates, but cannot decide which of two records is the right one. The person who serves that customer knows. When that decision gets delegated to whoever writes the code, it gets resolved by automatic rule, and automatic rules over dirty data produce silent errors: the kind discovered six months later, when somebody notices a history split in two.
What can be done, and what we do, is turn that cleanup into a bounded, orderly task. A report of doubtful cases, in a format the team can review, with a deadline. It is not glamorous, and it is the difference between starting clean and dragging the mess into a newer, more expensive system.
How you know the migration went well
A migration without written acceptance criteria did not finish, it just stopped. What we ask to agree on before a single record moves:
Counts that reconcile. How many customers, how many invoices, how many records per year in the old system and in the new one, with an explanation for every difference. Differences will exist, because part of what was there was duplicates or junk; what cannot exist is a difference nobody can explain.
Control totals. The numbers the business already knows, balances by customer, sales by month, stock by product, compared against the old system. If the two agree, the team trusts the new one. If they do not, you know exactly where to look.
A sample reviewed by a person. A handful of records chosen by the business, including the odd cases everyone knows about, checked by hand on both screens.
And the migration runs more than once. A dry run with real data, weeks before the cutover, is what turns migration into a repeatable procedure measured in hours instead of a blind operation on go-live day. If you want to see how this fits into the rest of the project, it is in how we structure a project.
The cutover is an operating plan, not a date
The most underestimated part is not technical: it is the day of the switch.
Between the moment data is extracted from the old system and the moment the team starts working in the new one, the business does not stop. Someone will invoice, someone will receive stock. That has to be resolved in advance, and there are three ways: freeze operations for a short window, capture twice for a few days, or start from a cutoff date and leave the old system read-only for anything before it.
All three are valid and the choice depends on the business. What is not a plan is "we will do it over the weekend". A cutover plan says who does what, in what order, how long each step takes, who confirms the previous step succeeded, and what happens if something fails halfway. That last part, the way back, is what separates a calm launch from a bad Monday.
If you are evaluating a replacement and this is exactly the part that worries you, it is one of the things that can be sorted out in a thirty minute call.
When not migrating is the right answer
There are cases where migrating history means spending money to move a problem.
If the old system's data is not trustworthy and the team no longer uses it to decide, if the structure is so different that every record requires manual interpretation, or if the history actually consulted is the last few months, the honest option is different: start clean with master data and balances, keep the old system accessible read-only, and hand over a complete, documented export in case it is ever needed.
We say so when we see it, even if it means one line less in the proposal. Migrating data nobody will use is cost without return, and it also delays the launch of the system you were actually buying.
What to ask before you sign
Four questions that separate a proposal that has done this from one that will improvise it. Who decides what gets migrated, and when that decision is made. How many test runs are included before the cutover. What the written acceptance criteria are, naming the counts and totals that will be compared. And what happens to the old system after launch: who turns it off, when, and who keeps a copy.
If a proposal cannot answer them, the risk did not disappear: it is just unassigned. There are more questions of this kind in twelve questions before hiring an agency, and they all share the same logic.
How we work with this
In our projects migration is part of the build, not an annex: it is designed alongside the data model, rehearsed with real data before the cutover, and its acceptance criteria are agreed in writing up front. The same applies on the way out: the code, the data and the documentation are yours, with a complete export that does not depend on us. That and the rest of the scope is on custom systems.
If you have a system that no longer fits and the open question is what to do with what is inside it, the discovery call runs thirty minutes, it is free and carries no obligation. Leaving it with clarity on what gets migrated and what does not is already a useful outcome, even if you go on to do the work with somebody else. You can book it here.
Does this apply at your company?
30 minutes, no obligation, to review your case and decide whether there's anything to build.