Migrate a Legacy ERP to the Cloud Without Freezing Operations
For: COO of a 200–800 person manufacturing or distribution company whose on-premise ERP is end-of-life, who has been handed the migration project and is terrified of the moment the old system goes dark while orders, inventory, and payroll are still running through it
The way you migrate a live ERP to the cloud without freezing operations is not by picking a better weekend for the cutover. It is by designing, from day one, a delta capture and reconciliation mechanism that runs in parallel with the migration itself — so that when the old system takes its last transaction and the new system takes its first, the gap between them is measured in seconds, logged, and provably reconciled. Everything else in this playbook exists to serve that one design decision.
This is for the COO of a 200–800 person manufacturer or distributor whose on-prem ERP (Dynamics GP, older SAP Business One, JD Edwards, Sage 300, an aging Epicor install, or something custom that four people still understand) has been declared end-of-life. You cannot pause fulfillment. You cannot pause payroll. You cannot pause procurement. And every vendor deck you have read assumes you can.
Why most ERP cutovers fail in the last 72 hours
Here is the pattern we see. A migration team spends months doing the honest work: cleaning master data, mapping chart of accounts, rewriting integrations, running three mock cutovers. Historical records move cleanly. UAT signs off. Then the real cutover starts on Friday night.
By Saturday afternoon, the warehouse has taken twelve emergency phone orders that were entered on paper because the old system was frozen and the new one wasn't accepting inbound EDI yet. Payroll ran a partial batch. A customer paid an invoice that exists in the old AR but not the new AR. By Monday, the finance team is maintaining two spreadsheets to track "things that happened during the gap" — and those spreadsheets never fully close. Six months later, the auditor finds it.
The failure is almost never technical. It is that no one owned the delta — the set of business events that occur between the old system's last live write and the new system's first live write — as a first-class design problem. This playbook fixes that.
The playbook
Step 1: Freeze the scope by drawing a transaction boundary, not a module boundary
Before anyone touches infrastructure, get the executive team in a room and agree on exactly which transactions — not modules — move in wave one. Not "Finance goes first." Instead: "Sales orders, shipments, AR invoicing, and cash application move. GL consolidation stays on the old system for one quarter-end."
Why transaction-level, not module-level? Because modules bleed into each other. If you migrate Inventory but leave Purchasing on the old system, every PO receipt becomes a cross-system reconciliation. If you draw the boundary at the transaction level, you can build integrations that keep the two systems consistent for the transactions that cross the boundary, and leave everything else alone.
Anti-pattern: Big-bang cutover of every module in one weekend because the license on the old system expires Monday. Renegotiate the license. The vendor will extend for a fee. Pay it.
You'll know this step is done when you have a one-page document listing every transaction type in the business, marked wave 1 / wave 2 / wave 3, and the CFO and VP Operations have both signed it.
Step 2: Build the delta capture layer before you build anything else
This is the step everyone skips. Before you configure a single screen in the new cloud ERP, build the mechanism that will capture every business event written to the old ERP during the final cutover window and replay it into the new one.
Concretely, this usually means one of three approaches:
- Change data capture (CDC) on the old ERP's database — Debezium, Qlik Replicate, or the native SQL Server CDC if you're on Dynamics/Sage. Every INSERT/UPDATE on the transaction tables lands on a Kafka topic or an equivalent queue.
- Application-level event sourcing — if the old ERP has a decent API or hooks, wrap the transaction endpoints and publish an event for each one. Slower to build, cleaner semantics.
- Trigger-based journaling into a shadow table — ugly, but works when you cannot install anything on the old server. Read from the shadow table on a five-second poll.
Whichever you pick, the output is the same: an ordered, replayable log of business events with idempotency keys. You will use this log twice — first during parallel run (step 4), and again during the final cutover (step 6) to close the delta.
Anti-pattern: Assuming the new ERP's import tools will handle this. They won't. Vendor import tools are designed for one-time bulk loads, not continuous streaming reconciliation.
You'll know this step is done when you can point at a running pipeline that has captured the last 24 hours of transactions from the old system, replayed them into a sandbox of the new system, and produced a reconciliation report showing zero variance.
Step 3: Migrate history in three tiers, not one
Do not try to move ten years of transactional history into the new cloud ERP. It will slow the new system down, complicate the data model, and force you to answer "how do we handle a 2016 credit memo" questions that don't matter to operations.
Split history into three tiers:
- Live tier — open transactions (unfulfilled orders, open POs, unpaid AR/AP, WIP inventory, active BOMs). This moves into the new ERP. It has to.
- Reference tier — closed transactions from the current and prior fiscal year, plus master data history (price changes, customer changes). This goes into the new ERP as read-only history or into a data warehouse (Snowflake, BigQuery, Redshift) that the new ERP can query.
- Archive tier — everything older. This goes to cold storage (S3, Azure Blob) with a searchable index. When the auditor asks for a 2019 invoice, you produce the PDF from archive. You do not load it into the new ERP.
Anti-pattern: "We need everything in the new system for reporting." No, you need everything queryable. Reporting belongs in a warehouse, not the ERP.
You'll know this step is done when the live tier fits in the new ERP with acceptable performance under load test, and finance has signed off on the query paths for the reference and archive tiers.
Step 4: Run a real parallel period, not a mock cutover
Mock cutovers are theater. They prove the migration scripts run. They do not prove the business runs.
Instead, run a genuine parallel period: for a defined window (two to four weeks, depending on your transaction volume and your team's tolerance), every transaction that hits the old ERP is also replayed into the new ERP through the delta pipeline you built in step 2. Both systems are live. Only the old one is authoritative. The new one is shadowing.
During this period, three things happen:
- You measure the reconciliation variance daily. Sales order counts, inventory positions, AR balances, GL trial balance — the new system's numbers should match the old system's numbers within a tight tolerance every morning. If they don't, you find out why before cutover.
- You let the operations team use the new system in read-only mode for their real work — pulling reports, checking inventory, quoting customers — even though the system of record is still the old one. This surfaces UX and data-quality problems that UAT never catches.
- You harden the delta pipeline under real load. Whatever bug is going to bite you at cutover is probably going to appear in parallel run. That's the point.
Anti-pattern: Skipping parallel run because "we already did UAT." UAT tests features. Parallel run tests the business.
You'll know this step is done when you have produced at least five consecutive business days of end-of-day reconciliation reports with variance inside your tolerance, and the operations leads have logged fewer than a defined threshold of new defects per day.
Step 5: Design the cutover window as a sequence of reversible steps
The cutover itself should not be a single "go live" moment. It should be a sequence of small, reversible steps, each with an explicit rollback criterion. Something like:
- T-24h: Freeze master data changes on the old system. Any new customer, item, or vendor from this point is entered directly in the new system and replicated back to the old one via the delta pipeline running in reverse.
- T-4h: Stop accepting new inbound EDI on the old system. Queue inbound EDI at the gateway. Complete in-flight shipments.
- T-0: Old system goes read-only. Delta pipeline drains — every captured event is replayed into the new system. Reconciliation report runs.
- T+0 to T+2h: Reconciliation checkpoint. If variance is inside tolerance, cut EDI, integrations, and user access to the new system. If not, rollback: unfreeze old system, drain reverse delta.
- T+2h to T+24h: Hypercare. Old system stays read-only and reachable. Every user question gets a real human answer within minutes.
The critical detail: the delta pipeline has to be bidirectional-capable, even if you only run it one direction most of the time. If you have to roll back at T+2h, you need to replay everything the new system captured back into the old one. Design for it. You probably won't use it. But if you don't have it, you cannot roll back — and a cutover you cannot roll back is not a plan, it is a hope.
Anti-pattern: A cutover runbook that says "go live" as a single step. If you can't roll it back, you can't do it safely.
You'll know this step is done when the runbook has been walked through by every function lead, each step has a named owner, each step has a rollback trigger, and you have executed a full dress rehearsal against production-scale data.
Step 6: Reconcile the delta explicitly, then close it in writing
After the cutover, do not declare victory when the new system is accepting orders. Declare victory when the CFO has signed a document stating that every transaction written to the old system between the last full backup and the final cutover has been accounted for in the new system, with a reconciliation report attached.
This is the step that makes the auditor happy a year later. It is also the step that forces you, on day one, to actually verify that the delta pipeline did its job — instead of hoping it did.
You'll know this step is done when there is a signed reconciliation certificate in the project folder, and the finance team has moved off their "gap tracking" spreadsheets (because there isn't one).
Step 7: Keep the old system alive, read-only, for one full close cycle
Do not decommission the old ERP the week after cutover. Keep it running, read-only, through at least one month-end close and preferably one quarter-end. It costs you a month of extra license and a bit of infrastructure. It buys you the ability to answer any "wait, what was this transaction on the old system" question instantly, without restoring from backup.
When you do decommission, take a final full database export and store it in cold storage alongside your archive tier. Document the schema. Someone will ask a question about it in three years.
You'll know this step is done when the old system has been shut down, the export is in cold storage with a documented restore procedure, and the archive query path has been tested by someone who wasn't on the migration team.
Failure modes we have seen
The silent integration. A shipping label printer, a tax engine, a bank file drop — some integration nobody documented, running on a scheduled task on an old Windows box under someone's desk. It writes to the old ERP. Nobody knows until day three post-cutover when the bank rejects a file. Fix: run a network capture on the old ERP server for two weeks and log every inbound connection. You will find at least two integrations you didn't know about.
The custom field graveyard. Ten years of "just add a field for this" has produced 400 custom fields, of which 60 are actually used. Migrating all 400 wastes months. Migrating only the used 60 breaks a report someone runs quarterly. Fix: instrument the old system to log field reads for 90 days before you plan the migration. Migrate what is read, archive the rest.
The heroic power user. One person in the business knows how the old ERP actually works. They are not on the migration team because they are too busy running operations. They find out about the new system two weeks before cutover and produce a list of 200 things it doesn't do. Fix: put them on the project from week one, and pay for their backfill.
The reporting shock. Users log into the new system and their favorite report is gone or looks different. Adoption collapses. Fix: rebuild the top 20 reports in the new system before cutover, and have the top 20 report consumers sign off during parallel run.
The reconciliation-that-never-closes. The one this whole playbook exists to prevent. If you get to day 10 post-cutover and finance is still tracking a growing spreadsheet of "gap items," stop. Something in the delta pipeline missed. Find it now, not at quarter-end.
How CodeNicely can help
Most ERP migration work we get pulled into looks like this: the vendor has sold the customer a new cloud ERP, the vendor's SI partner handles the configuration, and the customer's team is stuck owning everything around the ERP — the integrations, the delta pipeline, the reconciliation tooling, the legacy connectors, the reporting layer, and the change-data-capture plumbing that the vendor doesn't sell.
That is exactly the layer we build. The engagement that maps most closely is our work with Vahak, India's largest trucking marketplace. The core problem there was not "build a new system" — it was keeping a high-volume transactional platform consistent across multiple services, event streams, and legacy integrations while the business kept running at scale. The same discipline — CDC pipelines, idempotent replay, reconciliation dashboards, staged cutovers with rollback — is what an ERP migration needs.
If you're scoping a migration and want a second opinion on your cutover design, or you need a team to own the delta pipeline and integration layer while your ERP partner handles configuration, that's a conversation worth having. See our approach to legacy modernization and integration engineering, or how we work with mid-market and enterprise operations teams.
Frequently Asked Questions
Can we really migrate a live ERP to the cloud with zero downtime?
Not zero — but small enough that operations don't notice. A well-designed cutover with a delta pipeline typically produces a write freeze on the old system measured in minutes, not hours, and no interruption to read access. Inbound integrations queue at the gateway during the freeze and drain into the new system on the other side. "Zero downtime" is marketing; "unnoticeable downtime" is achievable.
Should we migrate to the vendor's cloud version of our current ERP, or switch platforms entirely?Default to staying on the same platform if a viable cloud version exists. Data model continuity dramatically reduces migration risk, integration rework, and user retraining. Switch platforms only if the current vendor's cloud offering is genuinely deficient or the license economics have become untenable. "We want new features" is rarely a strong enough reason to accept the risk of a platform change during a cloud migration — do the migration first, then evaluate platform change as a separate project.
How long will an ERP cloud migration take, and what will it cost?
Both depend heavily on transaction volume, integration count, master data quality, and how much history you insist on bringing forward. Rather than quote a number that will be wrong, we'd rather look at your specific environment. Contact CodeNicely for a personalized assessment and we'll give you a scoped estimate based on your actual system, not a benchmark.
Do we need to clean master data before migration, or can we do it during?
Before. Every day you spend cleaning master data before the migration saves you a week of reconciliation work after. Duplicate customers, orphaned items, stale vendors, and inconsistent unit-of-measure conventions do not get better when you move them to the cloud — they get worse, because the new system's validation rules are usually stricter. Budget a dedicated data cleansing phase and staff it with people who know the business, not just people who know SQL.
What happens to our custom reports and dashboards?
Assume you will rebuild them, and plan for it. Custom reports rarely migrate cleanly because they depend on the old system's specific schema, custom fields, and often undocumented business logic. The right approach is to identify the top 20 reports by actual usage (not by what people say they use), rebuild those in the new system or in a modern BI tool sitting on top of it, and rebuild the long tail on demand as users ask for them. Most of the long tail turns out not to matter.
Building something in Digital Transformation?
CodeNicely partners with founders and tech teams to ship AI-native products that move metrics. Tell us about the problem you're solving.
Talk to our team_1751731246795-BygAaJJK.png)