Phase 0
Decide & Plan
Lock scope, ownership, compliance, and the cutover window before any work starts.
-
Risk if skipped: Undeclared tables surface mid-cutover and force unplanned schema work in the production environment.
-
Risk if skipped: An 'everything' scope inflates storage costs against Dataverse capacity entitlement and stretches the cutover window past the planned freeze.
-
Risk if skipped: Tenant-to-tenant moves of Dynamics 365 Sales cannot be self-served and require a FastTrack engagement that adds weeks of lead time.
-
Risk if skipped: Provisioning the environment in the wrong geography requires a full environment rebuild — there is no in-place region change.
-
Risk if skipped: Without written criteria, 'done' becomes a moving target and the project never formally closes.
-
Risk if skipped: Items not declared out of scope become implicit in-scope items that surface as defects during validation.
Phase 1
Pre-Migration Prep
Cleanse the source, build the Dataverse schema, and prepare users before any export.
1a. Source-system audit and cleansing
-
Risk if skipped: Without a baseline, you cannot prove the migration moved everything it was supposed to move.
-
Risk if skipped: Duplicates that survive into Dataverse trigger downstream duplicate-detection blocks on subsequent imports and pollute Copilot relationship analytics.
-
Risk if skipped: Records with null required fields fail row-by-row in the Import Data Wizard and partially during batch loads.
-
Risk if skipped: Active source automations firing during export create a moving target; active destination automations firing during import generate notification spam and bad downstream sends.
1b. Destination environment and schema setup
-
Risk if skipped: Sharing one Sandbox between migration loads and configuration testing causes data collisions that invalidate both efforts.
-
Risk if skipped: Changing base currency after Opportunity records exist requires environment rebuild; all multi-currency historical conversions get re-derived against the new base.
-
Risk if skipped: Without prvOverrideCreatedOnCreatedBy, every imported record stamps createdon at import time and original history is lost.
-
Risk if skipped: Customizations made outside a Solution cannot be moved cleanly from Dev to Sandbox to Production and force manual rebuild in each environment.
-
Risk if skipped: Each in-scope source field that has no destination column at import time results in lost source data that is hard to detect post-load.
-
Risk if skipped: Changing a Choice integer after data is loaded breaks every downstream view, chart, Power Automate flow, and report filter that referenced the old integer.
-
Risk if skipped: Without Alternate Keys, upserts cannot match existing rows and re-runs of failed batches create duplicate GUIDs.
-
Risk if skipped: Activating a Business Process Flow against bulk-imported Opportunities can stamp every record at the first stage and lose the original stage history.
-
Risk if skipped: Flows firing during import spam customers, mis-route ownership, and double-count metrics — sometimes irrecoverably.
-
Risk if skipped: Switching the choice after files are loaded means re-uploading every attachment via the other path.
-
Risk if skipped: Default duplicate detection blocks legitimate same-email imports across Contact and Lead and silently drops rows from the import job.
1c. People prep
Phase 2
Source Export
Get every byte you will need out of the source, in a form you can transform.
-
Risk if skipped: Closed Opportunities re-imported without statecode set return as Open in Dataverse and skew pipeline reports.
-
Risk if skipped: Loading Opportunity Products before the Product and Price List records exist orphans every line item.
-
Risk if skipped: Activities loaded without their regarding reference detach from the parent Account, Contact, or Opportunity and become orphaned in Timeline.
-
Risk if skipped: Without a watermark, the delta-pull duplicates records and a manual diff costs hours of cutover-window time.
Phase 3
Transform & Map
Reshape source exports into Dataverse-shaped files, table by table, column by column.
3a. Mapping spreadsheet
-
Risk if skipped: Loading the source label as a string into a Choice column drops the row with a type-mismatch error.
-
Risk if skipped: A required Dataverse column with no source value blocks the entire row at import; partial loads must be re-run from scratch.
3b. Data transformation
-
Risk if skipped: A money column without transactioncurrencyid defaults to base currency and silently mis-states multi-currency historical revenue.
-
Risk if skipped: Unescaped newlines split a single source row into multiple destination rows mid-load.
3c. Relationship and audit-trail decisions
-
Risk if skipped: Skipping this decision is the single biggest cause of post-migration confusion when sellers see 'created last Tuesday' on a five-year-old Opportunity.
-
Risk if skipped: Loading children before parents either fails with reference errors or silently nulls the lookup.
3d. Dynamics-specific transforms
-
Risk if skipped: Skipping BPF planning means imported Opportunities show no current stage and sellers cannot use Sales Hub's pipeline view.
-
Risk if skipped: Duplicate Alternate Key values cause the entire batch to fail with HTTP 412 — diagnosis requires parsing the full multipart response body.
-
Risk if skipped: Sending labels to a MultiSelectPicklist column either errors or silently writes the label into a separate text column if one accidentally exists with the same name.
-
Risk if skipped: A customer lookup populated as a plain string drops the row at parse time with a validation error.
-
Risk if skipped: Attempting to embed N:N relationships in the parent create call is one of the most common reasons bulk loads fail silently with the relationship missing.
-
Risk if skipped: Setting only statecode without statuscode leaves Sales Hub showing the Opportunity as in an inconsistent state that is not queryable from default views.
Phase 4
Sandbox Test Migration
Prove every transform, every load order, and every throughput assumption in the Sandbox environment.
-
Risk if skipped: Microsoft's documented recommendation is to limit Import Data Wizard imports to 20,000 rows; pushing more into the wizard exhausts memory and the job hangs.
-
Risk if skipped: Without update-only semantics, source GUIDs that have no Alternate Key match get created as new Dataverse rows with the source GUID, polluting the table.
-
Risk if skipped: Test failures here are easy to fix; production failures here are expensive to fix because every row must be re-stamped.
-
Risk if skipped: A first-time full-volume run in Production is the single most common reason cutover windows blow past their planned end time.
-
Risk if skipped: Proceeding to Production without sign-off leaves the team with no shared definition of 'tested' when a defect surfaces later.
Phase 5
Production Cutover
Execute the load against Production in tight sequence, idempotent at every step.
-
Risk if skipped: Writes during cutover create a delta that is impossible to fully reconcile after Phase 6.
-
Risk if skipped: A failed batch without a captured request ID cannot be diagnosed against the trace log.
-
Risk if skipped: Pushing past a row-count miss compounds the defect and makes root-cause analysis multiple orders of magnitude harder.
Phase 6
Validate
Prove the migration was correct before letting users in.
6a. Reconciliation
-
Risk if skipped: Even a 1% row variance can hide a 100% loss on a specific Business Unit, owner, or date range. Slice the comparison by every dimension you reported on in the source.
-
Risk if skipped: A custom column that imports as null on every row indicates the column was not in the Solution at load time and every row needs re-import.
6b. Relationship and attachment validation
-
Risk if skipped: Orphaned Activities are invisible in the parent's Timeline and seller adoption drops the day they notice.
6c. Audit, compliance, and process
6d. User-acceptance check
6e. Sign-off
-
Risk if skipped: Skipping sign-off leaves no defensible position when a defect surfaces post-cutover and someone asks why the team launched.
Phase 7
Post-Migration Cleanup
Land users on the new system and decommission the old one.
-
Risk if skipped: Without archived run logs, any future forensic question about a specific record's lineage is unanswerable.
Watch list
Risks to track throughout
These risks live across multiple phases — keep an eye on them from kickoff through cutover.
-
Dataverse service-protection limits under heavy load
Dataverse enforces a sliding 5-minute service-protection window per user. Test runs, mapping fixes, re-loads, and the cutover all compete for the same budget. Track cumulative request volume from Phase 4 onward, honor every back-off signal, and keep one elevated service user reserved for the cutover itself.
-
Original-timestamp drift on historical records
Dataverse stamps createdon at import time unless overriddencreatedon is set and the migration user holds the prvOverrideCreatedOnCreatedBy privilege. The decision must be made before any row loads — re-stamping every imported record post-cutover is expensive and rarely covers every Activity and Note.
-
Choice integer values drifting between environments
Choice columns store integers, not labels. If Sandbox and Production were built independently, the same label may carry different integers. Always promote Choice columns through the Solution from Dev to Sandbox to Production so the integers stay aligned, and never edit Choice values directly in Production after data is loaded.
-
Tenant-to-tenant moves require FastTrack
Dynamics 365 Sales cannot be self-served from one Microsoft 365 tenant to another. The supported path is a Microsoft FastTrack tenant-to-tenant migration request, which carries its own lead time and prerequisites. Confirm the destination tenant identity in Phase 0; pivoting later resets the timeline.
Pair this with the long-form guide
The complete Microsoft Dynamics 365 Sales migration guide
Same research, written as prose: data model, import mechanisms, mapping strategy, pitfalls, and partner landscape.