ERP data migration guide: sequence, cleansing and cutover
ERP data migration guide: the object load sequence, cleansing before mapping, how many mock loads are realistic, reconciliation and cutover.
ERP data migration runs in dependency order: chart of accounts, then entities such as customers and vendors, then items, then bills of materials and routings, then open transactions, then historical balances. Cleanse before you map, not after. Plan three to four full mock load cycles, reconcile every object to a signed control total, and decide the parallel-run question early.
Key takeaways
- Load in dependency order. Every object needs its parents to exist first, so the chart of accounts comes before entities, entities before transactions, items before bills of materials.
- Cleanse in the source system before you map. Cleansing after mapping means fixing the same defect twice and re-running every downstream load.
- Three to four full mock load cycles is realistic. With one cycle, the live load is your test.
- Every object gets a control total, a named signer and a zero tolerance for financial objects. Sign-off is a document, not a conversation.
- Migrate balances and open items, not transaction history. Keep the legacy system readable instead — it is the cheapest decision available to you.
Data migration is where ERP implementations are actually decided. Configuration work is visible, planned and argued about in workshops. Migration is invisible until a mock load fails, and then it is suddenly the critical path, three weeks before a cutover date already announced to customers. Almost all of it is knowable in advance, because the dependencies are structural rather than situational.
- ERP data migration
- The process of extracting master and transactional data from legacy systems, transforming it to fit the target ERP's structures and validation rules, loading it in dependency order, and proving the result reconciles to the source. It ends with a signed reconciliation pack, not with a successful load.
ERP data migration sequence: which objects load first
Load order is not a preference. Each object references others, and the target system will reject a record whose parent does not exist. The sequence below is dependency-driven, and every migration follows some version of it.
| # | Object | Depends on | Control total to reconcile | The trap |
|---|---|---|---|---|
| 1 | Chart of accounts, subsidiaries, currencies, periods | Nothing — this is the foundation | Account count by type; entity list signed by the controller | Redesigning the chart during migration. Do the redesign before extraction or you map against a moving target. |
| 2 | Organisational structure — departments, classes, locations, warehouses | Subsidiaries | Count per dimension, and a mapping table from legacy codes | Legacy codes reused for two different meanings across sites. Find this now; it poisons every later report. |
| 3 | Entities — customers, vendors, employees, contacts | Chart, currencies, terms, tax codes | Active record count; total credit limit; count with a valid tax registration | Duplicates. A customer existing four times becomes four ageing lines and four wrong credit limits. |
| 4 | Items and units of measure | Item classes, accounts, locations | Active SKU count; count by item type; UOM conversion completeness | Items with no base unit of measure, or a conversion factor of zero. They load, then break every transaction touching them. |
| 5 | Pricing — price lists, customer-specific prices, discount rules | Items, entities | Line count per price list; 30 sample prices recalculated by hand | Legacy pricing living in spreadsheet exceptions. There is no source to extract from, so each one is a decision. |
| 6 | Bills of materials, routings, work centres | Items, locations | Component line count; rolled cost of 20 named finished items versus legacy | Phantom levels and alternate BOMs. A rollup matching on 20 items and not the 21st usually means a scrap or yield field was dropped. |
| 7 | Open transactions — open AR, open AP, open sales orders, open purchase orders | Entities, items, pricing, chart | Document count and value per object, plus the ageing profile | "Open" means something specific in each system. Agree the definition in writing before extraction. |
| 8 | Inventory on hand, lots, serials, bins | Items, locations | Quantity by item and location; valuation tied to the legacy valuation report | Costing method differences. Quantity can be right and value wrong, and only the value hits the general ledger. |
| 9 | Opening general ledger balances / trial balance | Everything above | Trial balance sums to zero; each control account ties to its subledger | AR and AP control accounts must equal step 7, inventory must equal step 8. Otherwise you have two versions of the truth on day one. |
| 10 | History — closed transactions, prior-period balances | Everything | Whatever you have chosen to prove | The step to argue hardest about. See below. |
Cleanse before you map
The order here is the single most useful thing in this guide. Cleansing after mapping means every fix has to be applied twice — once in the source and once in the transformed set — and every downstream load has to be re-run. Cleanse in the legacy system, where the people who own the data already work, and the fix propagates through every subsequent cycle for free.
Start with profiling rather than opinions. Extract a full copy and measure the actual damage per object:
- Duplicates. Fuzzy-match customer and vendor names plus tax registration. Every duplicate group is a merge decision, and every decision needs an owner.
- Completeness against target validation. Not "is this field empty" but "will the target reject this record". Run the target's required-field list against the source and count failures per field — that number predicts your mock load pass rate.
- Referential integrity. Open purchase orders pointing at inactive vendors, order lines referencing deleted items, stock in bins that no longer exist. Each is a decision, not a defect to fix in code.
- Domain validity. Free-text where the target expects a list value. Country codes in four formats. Units of measure entered as "EA", "Ea", "each" and "pcs".
- Staleness. Items with no transaction in three years, customers with no order in five. Exclusion is the cheapest cleansing there is.
Then set the bar. An object earns migration by having a named user with a named use. A useful and defensible rule: migrate items with on-hand stock, an open order line, or a transaction in the last 24 months. On a legacy item master of 41,200 records, that test typically leaves something like 14,860 — and the 26,340 records you leave behind are pure saved effort in mapping, loading, testing and reconciling, forever.
Size the work from your own record counts and cleansing complexity: person-days by object, cycle count, and calendar weeks at a given team size.
Mock loads: how many are realistic
Three to four full cycles. Fewer than three means the live load is your first real test of something you cannot repeat. Each cycle has a different purpose, and running one without knowing which purpose it serves is how teams burn a cycle and learn nothing.
| Cycle | Purpose | Success looks like | Typical duration |
|---|---|---|---|
| 1 | Prove the pipe. Small subset per object, end to end, extract through load. | Records land in the right objects with the right relationships. Pass rate is irrelevant here. | 1–2 weeks |
| 2 | Prove the mapping. Full field set, representative subset, every edge case you know about. | Field-level errors identified and assigned to owners. Rejections are understood, not just counted. | 2–3 weeks |
| 3 | Prove the volume and the reconciliation. Full record counts, full reconciliation pack produced. | Every control total ties, or every difference is explained in writing. Load window measured for real. | 2–4 weeks |
| 4 | Dress rehearsal. Frozen extract, real clock, real people, real runbook, in a production-like environment. | The runbook is executed by the people who will execute it at cutover, in the time the plan says. | 1 week plus the cutover window |
Reconciliation and sign-off
A load that completes is not a migration that succeeded. The deliverable is a reconciliation pack: per object, source count and value, target count and value, difference, and explanation of every difference. Tolerance for financial objects is zero — not "within 0.1%", zero. A $40 difference in open AR is not immaterial; it is evidence that something in the logic is wrong and you do not yet know what.
| Object | Reconcile to | Tolerance | Signer |
|---|---|---|---|
| Open AR and open AP | Legacy ageing: document count, total value, and value per ageing bucket | Zero | Controller |
| Inventory quantity | Legacy stock status report by item and location | Zero | Warehouse manager |
| Inventory value | Legacy valuation report and the inventory control account | Zero | Controller |
| Open sales and purchase orders | Legacy open order reports: line count, quantity, extended value | Zero on count; explained differences on value where pricing was re-derived | Sales ops and procurement |
| Customer, vendor and item master | Counts after the agreed merge list and migration criteria | Zero against the merge and criteria lists, not the raw source | Master data owner |
| Opening trial balance | Legacy trial balance, account by account; sums to zero | Zero | CFO or controller |
The AR reconciliation deserves particular care because it is the one that surfaces fastest after go-live, in front of customers. Rebuild the ageing buckets from the migrated data and compare bucket by bucket — the AR aging calculator is a quick way to check the profile from a list of amounts and days overdue, and AR aging buckets explained covers why a weighted average days-overdue figure catches errors a total never will.
Cutover and the parallel-run decision
Cutover is a timed sequence executed against a runbook, during a window in which the business is not transacting. Three things make or break it, and none of them is technical.
- The freeze. Nothing posts in the legacy system after the extract point. That means the warehouse stops shipping and the finance team stops posting, for real, for the length of the window. Negotiate the window with operations weeks in advance and publish it.
- Go/no-go criteria written before cutover weekend. Specific and binary: every reconciliation signed, zero open severity-1 defects, the dress rehearsal completed inside the window, the support rota staffed. Decided against a list, not against a mood at 2am.
- A rollback plan you have actually costed. Including the point of no return — the moment after which the legacy system can no longer be brought back as the system of record. Name that moment in the runbook and put a time against it.
Then the parallel-run question, which people ask about the wrong way round. Running both systems in parallel sounds like prudence, and for financial reporting over one period it can be genuinely valuable. For operations it is usually worse than the risk it is meant to manage: every transaction is entered twice, by the same team who are already learning a new system, and the two systems diverge within days. Once they diverge, nobody can tell which is right, so the comparison stops proving anything while still consuming double the effort.
| Approach | Where it works | Cost | Real risk |
|---|---|---|---|
| Full parallel run | Rarely — only where regulation requires it and volume is low | Double data entry across the whole team | Divergence within days, then two unreliable systems instead of one new one |
| Financial parallel — close one period in both | Common and worth doing. Proves the general ledger, tax and reporting logic | Finance team only, for one close cycle | Low. The main cost is a hard month for finance |
| Big bang with extended hypercare | Most mid-market implementations | Hypercare staffing and reduced throughput for two to four weeks | Concentrated. Everything rests on the reconciliation pack being genuine |
| Phased by site or entity | Multi-site groups where sites are operationally independent | Temporary interfaces between old and new, and a longer programme | The temporary interfaces become permanent, and the last site never goes |
The procedure
- 01
Inventory your objects and name an owner for each
Every object, its source system, its record count, its target structure, and the person who will sign its reconciliation. An object with no named owner will not be cleansed, because cleansing is a decision.
- 02
Set the migration bar in writing
Publish what earns a trip to the new system — for example items with on-hand stock, an open order line, or a transaction in the last 24 months — along with the resulting counts.
- 03
Extract a full profiling copy and measure the damage
Duplicates, completeness against the target's required fields, referential integrity, domain validity, staleness — counted per object, not described. This profile is what makes your effort estimate defensible.
- 04
Cleanse in the source system wherever you can
Merge duplicates, fill required fields, deactivate stale records, normalise units of measure and country codes. Source fixes flow through every later cycle for free; fixes in transformation code have to be maintained forever.
- 05
Map field by field against the target's validation rules
For each target field: source field, transformation rule, default when empty, behaviour on failure. The mapping document is the contract with the business, and "we will handle it in code" is not a mapping rule.
- 06
Build the load as repeatable, versioned code
Re-runnable from the raw extract with one command, per object, in sequence. If a step needs someone to open a spreadsheet, it will not survive cutover night.
- 07
Cycle 1 — prove the pipe
A small subset of every object, end to end. You are proving records land in the right places with relationships intact. Do not measure pass rates yet.
- 08
Cycle 2 — prove the mapping
Full field set on a representative subset, including every edge case profiling found. Classify each rejection as a source defect, a mapping error or a target configuration gap — three different fixes by three different people.
- 09
Cycle 3 — prove the volume and produce the reconciliation pack
Full record counts, load windows measured with a clock, and the complete pack per object: source count and value, target count and value, difference, explanation. The first cycle that produces something a controller can sign.
- 10
Cycle 4 — dress rehearsal on a frozen extract
Production-like environment, the real runbook, executed by the people who will run cutover, inside the real window. You are testing the runbook and the team, not the code. Update the runbook with actual timings.
- 11
Decide the parallel-run question and write go/no-go criteria
Before cutover weekend, not during it: reconciliations signed, severity-1 defects at zero, rehearsal completed inside the window, support rota staffed, rollback point named with a time against it.
- 12
Cut over, reconcile again, and sign
Execute the runbook, re-run every reconciliation against the live load, collect every signature, and keep the pack. It is your audit evidence and the document you will reach for the first time someone says the numbers look wrong.
After go-live: the first reconciliation that matters
The first month-end close on migrated data is where migration quality becomes visible to everyone. Inventory valuation is usually the first thing to disagree — the quantity migrated correctly and the value did not, because the costing method treats the opening layer differently. The mechanics of that gap are covered in the NetSuite inventory valuation report, and it is worth reading before your first close rather than during it.
Budget for it. Post-go-live data remediation is a real work stream with real days in it, and leaving it out is one of the reliable ways an implementation exceeds its budget — see what does an ERP implementation cost. Build the migration estimate and the implementation estimate together, from the same profiling numbers, using the implementation cost estimator alongside the migration model.
A practical note on the reconciliation itself: most of the effort is not analysis, it is extraction — pulling counts and values by object, by bucket, by location, from two systems, four times over. That is the kind of question answers directly against your own account — "open AR document count and total value by ageing bucket, as at the cutover date" — computed live, with the query shown underneath so the definition behind the number is visible rather than assumed. It does not cleanse your data. It shortens the loop between asking whether the load ties and knowing.
Frequently asked questions
What order should data be migrated to a new ERP?
Dependency order. Chart of accounts, subsidiaries and currencies first, then organisational dimensions, then entities such as customers and vendors, then items and units of measure, then pricing, then bills of materials and routings, then open transactions, then inventory on hand, then opening general ledger balances. History last, if at all.
How many mock data loads should an ERP migration have?
Three to four full cycles. Cycle one proves the pipe end to end, cycle two proves the field mapping, cycle three proves full volume and produces the reconciliation pack, cycle four is a dress rehearsal on a frozen extract with the real runbook and real clock. With only one cycle, the live load becomes your test.
Should you migrate historical transactions to a new ERP?
Usually not. Migrate open items and opening balances, then keep the legacy system readable in a read-only state for your retention period, or archive extracts to a queryable store. Historical transactions loaded into new structures carry old logic and rarely reconcile cleanly. If someone insists, ask which report they will run — a summary load by period and account normally satisfies it.
How do you reconcile data after an ERP migration?
Per object: source count and value, target count and value, difference, and a written explanation of every difference. Tolerance for financial objects is zero. Reconcile the ageing profile on AR and AP rather than just the total, tie inventory value to the control account, and confirm the opening trial balance sums to zero with each control account matching its subledger.
Should you run the old and new ERP in parallel?
Close one financial period in both systems — that is usually worth the effort and proves the general ledger, tax and reporting logic. A full operational parallel run usually is not: it doubles data entry for a team that is already learning a new system, the two systems diverge within days, and after that the comparison proves nothing.
What data should you clean before an ERP migration?
Duplicate customers and vendors, records missing fields the target requires, broken references such as open purchase orders pointing at inactive vendors, free-text values where the target expects a list, inconsistent units of measure and country codes, and stale records with no recent activity. Clean in the source system so the fix carries through every later load cycle.
Calculators for this
Data migration effort estimator: record counts by object and cleansing complexity give person-days, mock-load cycles and calendar weeks.
Estimate ERP implementation cost from licence, services, data migration, integrations, training and contingency, scaled by users, sites and complexity.
Paste your open invoices with days overdue to get AR aging buckets, percentage mix, weighted average days overdue and a suggested bad debt reserve.
Model 5-year ERP total cost of ownership: subscription or licence, implementation, internal FTE, infrastructure, upgrades and support. Cloud vs on-prem.
Keep reading
What drives ERP implementation cost: scope multipliers, services-to-licence ratios, the internal time nobody budgets, and what to ask an integrator.
Build an ERP ROI business case a CFO will approve: benefit categories with named owners, payback and NPV mechanics, and honest sensitivity analysis.
How the NetSuite inventory valuation report is built, how costing method changes the number, and why it won't tie to your inventory GL account.
ERP reporting tools compared: native reports, saved searches, a BI stack and conversational AI — with the real weaknesses of each, including ours.