[object Object]

Source Assessment

A 20-year-old CRM has 20 years of bad data; you do not migrate all of it. Inventory every source: the primary CRM (Salesforce, Dynamics 365, HubSpot, Sugar, Siebel), the spreadsheets the regional VPs maintain, the marketing automation tool, the support ticketing system, and the dead Lotus Notes database that one person still updates. For each, capture row count, last-modified distribution, and an honest data-quality score on the top 20 fields. The discovery typically reveals that 30-50% of records have not been touched in three years and another 10% are duplicates by email or domain. Decision criterion: only records with activity in the last 24 months and at least one populated revenue or support indicator are migration candidates by default; the rest get archived to S3 or Azure Blob with a query layer for compliance.

Mapping

Source field maps to target field, with explicit transformations and defaults for missing data documented in a sheet that becomes the migration contract. Use a tool — Salesforce Data Loader for simple cases, dbt + a staging warehouse for anything substantial, or a dedicated platform like Syncari, Hightouch, or OWNData. Capture the mapping in code, not just in a spreadsheet, so the transformations are reproducible. Picklist values nearly always need cleaning; the legacy CRM’s “Industry” field with 117 free-text variations becomes 22 standardized picklist options through a deterministic map plus a manual review of the long tail.

source.account.industry     -> target.Industry__c
  WHERE source = 'Tech'      -> 'Technology'
  WHERE source = 'IT Svcs'   -> 'Technology'
  WHERE source IS NULL       -> 'Unknown' (and flag for review)

Cleanup

Fix duplicates, missing required fields, and invalid data in the source whenever possible — migrating clean is the only way the new CRM does not inherit the mess. Deduplication on Accounts and Contacts is the single biggest lift; use fuzzy matching on company name + domain for Accounts and on email + last name for Contacts. Tools like RingLead, Cloudingo, or Salesforce’s native Duplicate Rules handle the deterministic pass; the fuzzy pass usually requires Python (rapidfuzz, dedupe library) or a managed service. Plan two weeks of cleanup per million records as a planning baseline.

Testing

Migrate to a full sandbox or test environment first, validate samples against source-of-truth queries, and run UAT with real users on real records. The validation should be both row-count (does target have the same count of post-2024 Accounts as source?) and field-level (do the top 50 Accounts by ARR show identical owner, industry, and renewal date?). User acceptance must be done by the people who will own the data — a sales ops admin signing off does not catch the field that the regional CSM relied on but no one knew about.

Cutover

Pick a low-traffic window (Friday evening for most B2B teams), freeze writes on the source, run the final delta migration, re-point integrations, and monitor for 48 hours. Plan rollback explicitly: the source stays frozen but readable for 30 days, and a documented procedure exists to flip back if something catastrophic appears. Communication during cutover matters: a status page, a pinned Slack message, and an on-call rotation for the first week.

Common Failure Modes

The dominant failures are: trying to migrate everything (paralysis), discovering on day 2 of UAT that a critical custom object was undocumented, assuming the integration vendor will handle re-pointing (they will not without explicit ticket), and not freezing the source during the final delta (creating a permanent reconciliation problem). Skipping the rollback plan is the most expensive of these.

What to do this week

Run a row-count and last-modified-date histogram on every source object. Bring the histogram to the steering committee with a simple proposal: archive everything older than 24 months unless someone names a specific business reason. The decisions you get on archiving will halve your migration scope.

[object Object]
Share