Salesforce to HubSpot migrations almost never fail on record counts. They fail twice over. First on the structures with no counterpart, led by the Lead object, which every guide covers. Then on the quieter failure nobody plans for: fields that transfer cleanly but lose the logic, the enforcement, or the definition that made them mean something. Picklists that import by label, ownership that silently reassigns, campaign membership that arrives without its status. Catch the second category during the audit or you find it in a board report.
The anxiety before a CRM migration is almost always about loss. Eight years of history, thousands of contacts, every note anyone ever wrote on an account. It is a reasonable fear and it is aimed at the wrong thing. Record migration is a solved problem. Objects move, associations hold, and a competent validation pass will tell you whether the counts reconcile.
What actually goes wrong is subtler and shows up later. A report that used to mean one thing now means something slightly different. A routing rule fires on a field that survived the move but lost the logic that used to populate it. Somebody asks for conversion rate by lead source in the second month and discovers the question is no longer answerable.
The structures with no equivalent
Start here, because these are the decisions that take the longest and they are the ones teams defer.
The Lead object is the big one. Salesforce keeps leads in a separate object and converts them into an account, a contact, and an opportunity. HubSpot does not work that way. It has contacts, and a lifecycle stage property that describes where each one sits. There is no conversion event, because there is nothing to convert from.
That single difference invalidates more reporting than anything else in a migration. Lead conversion rate, time to conversion, converted lead source, the whole family of metrics your marketing team reports on, all of it assumes an object that will not exist. You cannot map your way out of this. You have to decide what those metrics become, and then rebuild them from lifecycle stage transitions instead. Teams that leave this until after cutover spend the following quarter arguing about why the numbers moved.
Record types do not port. A Salesforce org that uses record types to run different sales processes, different page layouts, and different picklist values off one object is encoding a lot of behaviour in a place HubSpot has no direct answer for. In practice that usually decomposes into separate pipelines, a property that carries the old record type value for reporting continuity, and some rethinking of what genuinely needed to differ in the first place. It is often the moment somebody realises two of the four record types have been functionally identical for three years.
Cross-object formula fields and roll-up summaries need a new home. HubSpot has calculation properties, and they cover a good deal of ground, but they are not a like-for-like replacement for arbitrary Salesforce formulas reaching across relationships. Some become calculated properties. Some become workflow-written values, which means they update on a trigger rather than on read, and that difference matters for anything time-sensitive. A few turn out to exist only because a report needed them once in 2022.
Validation rules become somebody else's job. Salesforce validation rules are enforcement at the database layer. HubSpot's equivalents live in different places depending on what you are protecting: required properties, conditional logic on forms, workflow-based correction. Work out which rules are protecting revenue data and rebuild those deliberately. The rest are usually accumulated scar tissue from an incident nobody remembers.
Opportunity Contact Roles lose their roles. Salesforce lets you attach several contacts to an opportunity and say what each one is: economic buyer, champion, blocker. On the other side those become deal to contact associations, and unless somebody deliberately builds association labels to carry the role, a default import gives you the connection without the meaning. If anyone reports on buying committee coverage, or your multi-threading discipline depends on knowing who the champion was, this one matters more than it looks.
Campaign Member status is the part worth keeping, and the part usually dropped. A Salesforce campaign member carries a status: sent, responded, registered, attended. The membership imports easily enough. The status is what made it useful for attribution, and it is what typically does not survive. Marketing finds out when someone asks which webinar actually sourced pipeline.
Line items move, quoting logic does not. Both platforms have line items, so the data lands. Salesforce CPQ has no HubSpot counterpart, and for a SaaS business the harder question is how subscription terms, renewals, and expansions were modelled. If that logic lived in CPQ or in custom objects hanging off the opportunity, budget real time for redesigning it rather than assuming it maps.
The automation layer does not port at all. Workflow rules, Process Builder, Flows, and Apex triggers have to be rebuilt, and Apex has no equivalent whatsoever. This is genuinely good news if you use it properly. Every automation you rebuild is one you have to justify first, and a meaningful share of them turn out to exist only to compensate for a Salesforce constraint that no longer applies.
What quietly changes meaning
Everything above announces itself. You hit it during mapping, you argue about it, you decide. This next category is the one that gets missed, because every field involved imports successfully and every count reconciles. Nothing looks wrong. The data simply means something slightly different than it did, and you find out when a number you have reported for two years moves without explanation.
- HubSpot deduplicates contacts primarily on email and companies primarily on domain. That is a design opinion, and it will act on your data whether or not you agree with it. Contacts with no email deduplicate against nothing and pile up. Subsidiaries sharing a parent domain can collapse into a single company. Both are recoverable if you decide in advance and painful if you discover them in month two.
- Picklist values move by label, not by intent. A Salesforce picklist whose API name drifted from its label years ago will import as whatever the label says, and any workflow keyed to the old value goes quiet rather than erroring.
- Activity history is the most fragile thing in the move. Emails, calls, meetings, and tasks carry timestamps and associations that matter for reporting, and they are also the highest-volume objects you are moving. Decide how far back you actually need it before you start, because "all of it" is a meaningfully different project.
- Records owned by deactivated users have to land somewhere. Left alone they end up assigned to whoever ran the import, which quietly corrupts every ownership-based report you build afterwards.
- Multi-currency behaves differently, particularly for historical amounts. If you report in a reporting currency and close deals in local ones, confirm what happens to closed-won values from three years ago before anyone presents a trend line.
- Source attribution is the most dangerous one, because both systems have a field for it and the fields do not agree. Salesforce Lead Source is whatever your team decided to write into it. HubSpot computes Original Source itself, from its own tracking. Import one into the other and you get a column that looks authoritative and is measuring something else entirely. Decide which definition you are keeping, and expect the year over year comparison to break either way.
Want to know what will drift in your instance before you commit to a date?
Book a free assessment and we will walk your Salesforce org with you, flag the structures that have no counterpart and the fields that will quietly change meaning, and tell you honestly how big the job is. If you would rather start on your own, the free RevOps Health Check gives you a scored read on your data and stack in a few minutes.
See how we run migrations Book a Free AssessmentThe order that keeps you out of trouble
Sequence is most of the discipline here. The work below is not glamorous and skipping any of it is how migrations acquire their reputation.
Audit before you map. Pull every object, field, workflow, and integration, then find out which ones are actually in use. Field population rate is the fastest honest signal you have. A custom field filled on two percent of records over eight years is not a requirement, it is an artifact, and you are about to spend money moving it.
Make the redesign decisions next, while nothing has moved and changing your mind is free. This is where the Lead object question gets answered, where record types get resolved, and where somebody senior confirms what the reports need to say afterwards. If your team cannot articulate what a qualified lead is today, the migration will not clarify it. That conversation belongs to the operating model, not to the migration.
Then build in a sandbox and move a representative slice first. Not the clean records. Take the ugly ones: the account with four duplicates, the opportunity with a null close date, the contact owned by someone who left in 2023. Those tell you what the migration is going to be like. A clean test set tells you nothing you did not already assume.
Reconcile object by object against the source before cutover, and rebuild automations in the new system rather than translating them one for one. A workflow that existed to patch a Salesforce limitation may have no reason to exist in HubSpot, and porting it faithfully means importing the limitation too.
Cut over when the team can absorb it, which is rarely the end of a quarter. Keep the old instance readable for a while. Nobody has ever regretted that.
What to leave behind
The instinct is to bring everything, on the theory that storage is cheap and you might need it. Storage is cheap. Confusion is not. A migration is the only moment when deleting things is politically easy, and that window closes the day you go live.
Leave the custom fields nobody populates. Leave the records owned by users who left two reorganisations ago. Leave the objects built for a product line you sunset. Archive them somewhere retrievable if that helps people sleep, then do not import them. Every one you carry across is a field in a dropdown that a rep has to scroll past for the next five years, and a column somebody will eventually build a report on without knowing it was abandoned in 2021.
The companies that come through a migration well are not the ones that moved the most data. They are the ones that knew which data mattered, decided what the ambiguous cases would mean, and arrived on the other side with a system their team could explain. That discipline is the same one that keeps a CRM worth trusting afterwards, and it is the argument underneath choosing the right platform in the first place.
Frequently asked questions
What is the hardest part of migrating from Salesforce to HubSpot?
The Lead object. Salesforce keeps leads separate from contacts and converts them into an account, contact, and opportunity. HubSpot has no separate lead record, it has contacts with a lifecycle stage. Every report, routing rule, and conversion metric built on that distinction has to be redesigned rather than mapped, and teams usually discover this after the data is already moved.
How does HubSpot handle duplicates during an import?
HubSpot deduplicates contacts primarily on email address and companies primarily on domain. That is an opinion baked into the platform, and it has consequences. Contacts without an email address will not deduplicate against anything, and separate subsidiaries that share a parent domain can collapse into one company record. Decide how you want both cases handled before you import, not after.
How long does a Salesforce to HubSpot migration take?
For a mid-sized B2B SaaS instance, plan in weeks rather than days, and expect the mapping and redesign work to take longer than the data movement itself. Moving records is largely mechanical. Deciding what happens to record types, formula fields, lead conversion history, and validation logic that has no direct equivalent is the part that needs real decisions from people who know why the system was built that way.
Should you migrate all of your historical Salesforce data?
No. Migrating everything is how you import old problems into a new system. Bring the records and history the business actually uses, archive the rest somewhere retrievable, and leave behind dead custom fields, records owned by long-departed users, and objects nobody has written to in years. A migration is the cheapest opportunity you will ever get to stop carrying them.
Migrations are a large part of what we do. If you are still deciding whether to move at all, start with HubSpot vs Salesforce by stage. If the decision is made, see how we scope and run the work in CRM migration and CRM solutions, or read what an eight-week move actually looked like in this migration case study.