Who we build for — ERP & CRM data owners
The software is the easy half. The records are the project
Every new system arrives with a question nobody enjoys: what happens to fifteen years of customers, items, orders and documents that are already in the old one, spread across three spellings of the same company name and two identifiers that were never reconciled.
KodDelta handles both halves of that problem: one-time migration of ERP and CRM records — extract, clean, map, load, reconcile — and the permanent bridges that keep the remaining systems in step afterwards. Reconciliation is on counts and totals, cutover is rehearsed with a rollback, and a contained migration runs in 2–4 weeks.
Two different jobs that get confused
Almost every project that starts as "we need our data moved" turns out to be two projects wearing one name, and separating them early is the cheapest decision available.
Migration is a one-time move. Records leave a system that is being retired and arrive in one that is taking over. The risk is concentrated at a single moment and the question is always completeness: is everything here, is it the same, and can we prove it.
Integration is a permanent arrangement between systems that both continue to live. The risk is spread across years and the questions are different: who owns each record, what happens when both sides change the same field, and how a failure is noticed rather than discovered at month-end. The architecture for that side is on integrations, which covers the bridge patterns and failure modes in depth.
Most companies need both. What they must not do is run them as one workstream, because migration wants a freeze and integration wants continuity, and a plan that pretends otherwise fails at the cutover.
How much history to move
This is the first commercial decision, and it changes cost more than record volume does. The useful rule is to move what will be acted on and archive what will only be read.
| Record group | Usual decision | Reason |
|---|---|---|
| Master data — customers, suppliers, items, price lists, bills of materials | Move in full, cleaned | Everything else references it; a duplicate here becomes a duplicate everywhere downstream |
| Open transactions — unfulfilled orders, open invoices, stock balances | Move in full, reconciled to the penny | The business cannot operate on a partial copy of what is currently owed and owing |
| Recent closed history | Move a defined window, commonly two to three years | Enough for comparison, trend and customer conversations without carrying the whole archive |
| Old closed history | Read-only archive, searchable | Retention and audit obligations are satisfied without the cost of transforming records nobody will edit |
| Attachments and documents | Decide explicitly, test extraction early | Frequently missing from vendor exports and usually the slowest part to retrieve |
The five passes of a migration
Every migration we run goes through the same five passes, in the same order, and every pass produces an artefact somebody can review.
-
Extract
Prove the route out of the source before anything else: API, vendor export, direct database read, reporting interface, or structured extraction from generated output. Take a real sample, time it, and calculate the full extract from the measurement rather than from optimism. Attachments are tested separately. The source system is never edited to make extraction easier, so the pass can always be repeated from an unchanged original.
-
Profile and clean
In a staging area, not in the source and not in the target. Count records per type, find nulls where the target requires a value, find the duplicate customers and items, normalise units, currencies, country codes and tax identifiers. Every rule is code, so it can be re-run and reviewed. Records that fail validation go to a quarantine list that a person from the business decides on; nothing is dropped quietly.
-
Map
A written field-by-field mapping from source to target, including what happens to fields with no destination and where default values come from. This is also where the business key per entity is declared — the field combination that decides whether two rows are the same real thing — and where the identifier mapping table is created so every source key keeps a permanent link to its target key.
-
Load
Idempotent and restartable, in dependency order: master data first, then transactions that reference it. Because the load reads the identifier mapping table, running it twice updates records rather than creating second copies. A load that cannot be re-run safely cannot be rehearsed, and a migration that cannot be rehearsed is a migration performed for the first time in production.
-
Reconcile
Counts per record type and sums on the amount fields, taken from the source before the load and from the target after it, compared line by line. Every difference is explained, not tolerated. The reconciliation report is the deliverable the business signs, and it is the only honest answer to whether the data arrived.
Identifiers, duplicates and the source of truth
Three technical decisions cause most of the pain that appears months later, and all three are cheap to get right at the start.
The business key. For each entity, what makes two records the same real-world thing: a tax number for a company, a code for an item, an email plus a name for a contact. Declared up front, it prevents duplicates during the load and again during years of integration afterwards. Declared late, it becomes a deduplication project.
The identifier map. A permanent table linking every source identifier to its target identifier. It makes loads repeatable, it makes support questions answerable a year later, and it is what allows a record to be traced back to the system it came from when somebody disputes a figure.
The source of truth per entity. After the move, exactly one system owns each entity and the others receive it. Customers might be owned by the CRM, items by the ERP, invoices by the accounting package. Where two systems both write the same entity, the conflict rule is written down before the bridge is built, because a bridge without a declared owner produces month-end arguments that nobody can settle from the data.
Cutover, and the rollback that makes it safe
A cutover is a rehearsed procedure, not an event, and the rehearsal is not optional.
The full migration is run at least once against a copy of production, timed from beginning to end, with the reconciliation report reviewed by the people who know what the numbers should say. That rehearsal produces the real duration, which is what the cutover window is planned from. On the day, the source is frozen for the entities being moved, the final delta is extracted and loaded, reconciliation is re-run and signed off, and only then are users pointed at the new path. If reconciliation does not pass, the freeze is lifted and the company carries on in the old system, having lost a weekend rather than its records.
Where a freeze is genuinely impossible, the alternative is a parallel period with a declared source of truth per entity and a bridge carrying changes one way, retiring the old path per entity once the two agree. That is slower and it is the correct answer for operations that cannot stop. The staged version of this, including the accounting boundary, is described on the migration guide.
After the move: making failure visible
The bridges that remain need three properties, and their absence is what makes integrations fail silently for weeks. Retry with backoff, so a temporary outage on either side does not lose a record. Idempotency, so a retried message does not create a duplicate document. And monitoring that is a real alert to a real person rather than a log file nobody opens, with a reconciliation job that compares both sides on a schedule and reports drift while it is still small. The full set of failure modes is on integrations.
When you should not migrate
- The old system still fits. If the package does the job, a migration is expense without benefit. The decision framework is on packaged vs custom.
- The data is not trusted in the first place. If nobody believes the current figures, moving them produces distrusted data in a new schema. Clean first, then decide.
- Nobody will sign the reconciliation. A migration needs a person from the business who can say the numbers are right. Without that person, the project has no definition of done.
- Only one entity is really involved. Sometimes the answer is a single bridge rather than a move; that is a smaller and cheaper project and we will say so.
What a built system looks like on the other side of the move is described on custom software, and the published bands and timelines are on pricing.
Frequently Asked Questions
What is the difference between data migration and integration?
Migration is a one-time move: records leave an old system and arrive in a new one, and the old system is then retired or frozen. Integration is permanent: two systems both stay alive and exchange records continuously, each owning the entities it is the source of truth for. The risks differ. Migration risk is concentrated at the cutover and is about completeness; integration risk is spread over years and is about conflicts, retries and silent failure. Most projects need both, planned together and executed separately.
How much history should we move?
Move what you will act on, archive what you will only ever read. Open transactions and current master data must move in full because the business runs on them. Closed history is a judgement: many companies move two or three years into the live system and keep the rest as a read-only archive that can still be searched. That decision changes the cost and duration of the whole project, so it is made deliberately at the start rather than by default. Moving everything because it feels safer usually means migrating years of records that nobody has opened since they were created.
How do you make sure nothing is lost or duplicated?
By reconciling on counts and totals rather than on impressions. Before the load, the source is counted per record type and summed on the amount fields that matter. After the load, the same counts and sums are run against the target and compared line by line, with every difference explained rather than accepted. Duplicates are prevented by defining a business key per entity before anything moves, and by keeping a mapping table from every source identifier to every target identifier, so a re-run updates records instead of creating second copies. A migration that cannot be re-run safely is a migration that cannot be rehearsed.
What if the old system has no proper export or API?
There is almost always a route, and the route decides the schedule, so it is tested in the first week. In order of preference: a documented API, a vendor export, direct read access to the underlying database, a reporting or ODBC interface, and, as a last resort, structured extraction from generated reports. Attachments and documents are checked separately because they are frequently absent from exports and are usually the slowest thing to retrieve. What matters is proving the route with a real sample before any plan is committed to.
How is master data cleaned without inventing new problems?
Cleaning happens between extraction and load, in a staging area, and every rule is written down and applied by code rather than by hand. Duplicate customers, suppliers and items are merged against a declared business key, and inconsistent units, currencies, country codes and tax numbers are normalised. Records that fail validation are quarantined for a person from the business to review, not silently dropped. The source system is never edited to fit the migration, so extraction can always be repeated from an unchanged original.
How is the cutover run?
As a rehearsed procedure with a stated rollback, not as an event. The full migration is run at least once against a copy, timed end to end, and the reconciliation report is reviewed. At the real cutover, the old system is frozen for the entity being moved, the final delta is extracted and loaded, reconciliation is re-run and signed off, and only then is the new path opened to users. If reconciliation fails, the old system is unfrozen and nothing is lost. Where a freeze is impossible, the two systems run in parallel for a period with a defined source of truth per entity.
What does this cost and how long does it take?
A single bridge or a contained migration falls in the $3,000 to $6,000 band and takes 4 to 6 weeks. A programme covering several entities, a full history load and continuous integration between two or more systems is $8,000 to $15,000 over 2 to 4 months. Enterprise platform work involving many systems is $20,000 and above over 4 to 8 months. The variable that moves the number most is not volume; it is how many source systems disagree about the same record and how much cleaning that disagreement requires.
Send us a record count and a sample export.
Entities, volumes, the systems involved and how much history you want to keep live. We come back with an extraction plan, a reconciliation approach and a fixed price.