Skip to main content

PLAYBOOK / 4 MIN READ

CRM data migration: reconcile counts, duplicates and ownership before cutover

By Alex Cinovoj, Founder & CTO, TechTide AI · CTO & Co-Founder, CPG Playbook

Published · September 2026 editorial collection

Moving to a new CRM usually starts with an export, a spreadsheet and a confident estimate. It ends, too often, with a sales team that does not trust the new system because a customer's history is missing, an owner is wrong, or the same company appears three times. The data moved. The meaning did not.

A CRM migration is a reconciliation project more than a transfer project. The work that keeps the team's trust is deciding what to bring, how records map, how duplicates are resolved, and how you will prove the result matches the old system before you switch.

The steps below are a general approach. Import tools and APIs differ between platforms and change over time, so check the current documentation for the systems you are moving between.

Decide what is worth migrating

Not everything in the old CRM should come across. Contacts with no activity for years, abandoned custom fields, test records and duplicate pipelines add noise. Agree with the sales and operations leads which objects, fields and history are needed, and what will be archived instead of migrated.

For each object, record why it is coming and who owns it in the new system. If nobody can say why a field matters, it probably does not need to move.

Map fields by meaning, not by name

Build a mapping from old fields to new ones and confirm the meaning of each. Picklist values need explicit mappings. Stages need careful attention, because two systems' pipeline stages rarely mean exactly the same thing. Dates need their time zone and format checked.

Where a field has no clean equivalent, decide whether to create a field, combine it with another, or archive it. Write down each decision. That mapping document is how the team will answer "where did this go?" after cutover.

Use stable identifiers to prevent duplicates

Duplicates are the most common migration failure. HubSpot's documentation on importing records explains that a unique identifier is required to match imported data to an existing record, and that in some multi-object imports identical data across rows is treated as one record when no unique identifier is provided. It also notes that some existing activity types cannot be updated through import.

Details like these shape the plan. I would carry the old system's record identifier into a field on every migrated record, use it to link related records, and use it for any reload. That makes it possible to rerun a load without creating copies, and to trace every new record back to its source.

Resolve duplicates before loading, with people

Most old CRMs already contain duplicates. Run a matching pass that proposes groups of likely duplicates by name, domain, email and address. A model can help score likely matches between records with inconsistent names, but merging should be a decision by someone who knows the accounts.

Agree which record survives in each group and which values win. Merging after loading is possible but usually harder, because the new system's automations may already have acted on the duplicates.

Load in rehearsals, not once

For larger volumes, platforms provide bulk tools. Salesforce describes Bulk API 2.0 as asynchronous and suited to operations on large sets of records, with jobs submitted and results collected later, and notes that it does not guarantee a service level for processing time. Plan the cutover window with that in mind.

I would run at least one full rehearsal load into a test environment. Check failures and rejected rows, fix the mapping or the data, and load again. Each rehearsal should produce a reconciliation report.

Reconcile counts and samples

The reconciliation report compares the old and new systems. Record counts per object should match the plan, with every difference explained by an agreed exclusion or a merge. Totals that matter, such as open pipeline value or the number of open deals per owner, should match too.

Counts are not enough. Pick a sample of real records, including large customers and known messy ones, and have the people who know them check each in the new system: owner, stage, key fields, related contacts and history. Record what they found.

Freeze, cut over and verify

Agree a freeze period when the old CRM stops accepting changes, or a method for capturing changes made during cutover. Run the final load, reconcile again, and turn off automations in the old system that might send messages or update other systems.

After cutover, keep the old system readable for an agreed period so people can check history. Track issues reported by users for the first weeks, and fix data problems at the source mapping where possible so a reload stays consistent.

Define done before you start

The acceptance condition I would agree with the team: every migrated record carries its source identifier, counts and key totals reconcile with explained differences, a sample checked by account owners matches, and the old system's outbound automations are off.

Bring the systems you are moving between, rough record counts and the problems your team already knows about.

About the author

Alex Cinovoj

AI & Infra Engineer. Building AI that survives outside the demo.

Founder & CTO, TechTide AI · CTO & Co-Founder, CPG Playbook

I spent 13 years in US enterprise IT, the last 2 focused entirely on AI implementation. I run TechTide AI, an implementation studio that takes stalled AI pilots into production. I write about the work in progress at alexcinovoj.com and on Substack.

Logs over vibes. Production over theater.

Related field notes

All field notes

Have a stalled build that needs to work?