S
SalesTap
Home · Blog · CRM & Tools
CRM & Tools

Salesforce to HubSpot migration without data loss

A Salesforce to HubSpot migration playbook for sales teams: how to audit, map, sequence, and reconcile the move without losing pipeline data.

How to migrate from Salesforce to HubSpot without losing data

Most failed CRM migrations don't fail at the import step. They fail six weeks later, when an AE pulls up a renewal account and discovers the original opportunity close date is gone, the previous champion is mislabeled as a current contact, and the email thread that justified the discount has vanished. By then, the Salesforce instance has been decommissioned and the backups are stale.

A clean Salesforce-to-HubSpot move is less about moving rows and more about preserving the evidence your reps need to keep selling. Here's how to do it without burning pipeline visibility.

Audit before you export

Before you touch HubSpot, run a structural audit of your Salesforce org. The migrations that go sideways are almost always the ones where teams treated Salesforce as if it were a clean relational database. It rarely is.

Pull a list of every custom object, every custom field on standard objects (Account, Contact, Lead, Opportunity, Task, Event), every record type, every validation rule, and every active workflow or Process Builder flow. Then categorise each one into three buckets:

  • Active and load-bearing — fields reps actually populate, used in reports or sequences
  • Legacy but referenced — fields nobody fills in anymore, but historical records depend on them
  • Dead — orphaned fields from a 2021 sales ops experiment

The dead bucket usually accounts for a surprising share of the schema. Don't migrate it. The legacy bucket is where you'll lose the most data if you're careless: a custom "Original Source Detail" picklist that hasn't been touched in two years may be the only field that tells you which accounts came from a specific partner channel.

Map every field in buckets one and two to a HubSpot equivalent before you export anything. Where no equivalent exists, create the custom property in HubSpot first. This sounds obvious. Teams skip it constantly.

The object model gotchas

Salesforce and HubSpot model the world differently, and the differences are where data quietly disappears.

Leads vs. Contacts. Salesforce separates Leads (unconverted) from Contacts (associated with an Account). HubSpot has one Contact object with a lifecycle stage property. When you migrate, every Salesforce Lead becomes a HubSpot Contact, and the conversion history (Lead → Contact → Account) collapses unless you explicitly preserve it. Create a custom property called something like "SF Lead Conversion Date" and "SF Original Lead ID" and populate them during the import. Otherwise your funnel reporting breaks the day after go-live.

Opportunities vs. Deals. Mostly a clean map, but stage histories don't transfer automatically. If you care about velocity reporting (how long deals sat in each stage), you need to extract the OpportunityHistory table from Salesforce separately and rebuild it in HubSpot using stage timestamp properties. The default migration tools won't do this.

Activities. Tasks and Events in Salesforce map to HubSpot's engagement objects, but logged emails are the real problem. If your reps used the Salesforce Outlook or Gmail integration, the email bodies live in Salesforce as EmailMessage records. HubSpot's standard migration paths don't always pull these. Test with a single account before you assume they came across.

Attachments and Notes. Salesforce's Files, Attachments, and Notes are three separate object types depending on when they were created. Each needs its own export path. A migration that pulls Files but skips legacy Attachments will leave half your account-level documentation behind.

Sequencing the migration

Don't do this in one weekend. The teams that try to cut over in a single window are the ones writing apology emails to their CRO on Monday.

Run it in four phases:

Phase 1: Sandbox load. Export a representative slice of production data (say, the 200 accounts with the most activity in the last 18 months, plus their related contacts, opportunities, and activities) and load it into a HubSpot sandbox. This will surface field-mapping errors, character-limit problems, and picklist values that don't match. Expect to find a few hundred issues. Fix them in your mapping spec, not by hand-editing records.

Phase 2: Historical bulk load. Migrate everything closed/won, closed/lost, or inactive for more than 90 days. These records don't need to be perfect; they need to be searchable. Reps querying "did we sell to Acme in 2024?" need a record to find. Load these with a freeze flag so reps don't accidentally reopen old deals.

Phase 3: Active pipeline. This is the dangerous one. Freeze writes in Salesforce, export open opportunities and their associated contacts/activities, validate the export against a record count from Salesforce, load into HubSpot, then reconcile. Have AEs spot-check their top five open deals before you unfreeze. Budget two full business days for this and do it midweek, not on a Friday.

Phase 4: Salesforce as read-only archive. Keep Salesforce live in read-only mode for at least 90 days post-cutover. The cost is trivial compared to the cost of discovering, in week six, that an EmailMessage record didn't migrate and you need the original.

The reconciliation that actually matters

Most migration checklists tell you to count records. Counting is necessary but nowhere near sufficient. A migration can show 100% record parity and still be broken.

The reconciliation that catches real problems works at the relationship level. Pick 20 active opportunities at random. For each one, in both systems, answer: who is the primary contact, what stage is it in, what was the last activity date, who owns it, what's the amount, and what's the close date. Then open the activity timeline and check that the last three logged emails or calls are present in both systems with the same timestamps.

If 18 of 20 match cleanly, you're in good shape. If only 14 match, you have a systemic mapping problem and you should not cut over. Find it before your reps do.

One more check that gets skipped: ownership. HubSpot users need to exist with the same email addresses as your Salesforce users before import, or every record will end up owned by the integration user. Fixing ownership after the fact is possible but tedious, and in the meantime your territory rules don't work.

The takeaway

  • Map fields before you export, not during. Build the HubSpot property schema first, then move data into it. Reverse order guarantees lost fields.
  • Migrate in four phases over weeks, not one weekend. Sandbox slice, historical bulk, active pipeline freeze-and-move, then a 90-day Salesforce read-only window.
  • Reconcile at the relationship level, not the record count. Twenty opportunities checked end-to-end will surface more problems than a million-record row count.
  • Preserve original Salesforce IDs as custom properties on every migrated object. When something breaks in month three, this is the only way to trace records back to source.

Put this into practice

Use our free AI tools to apply these tactics immediately.

Explore free sales tools ↗

Keep reading