A Salesforce to HubSpot migration is an ownership decision before it is a data move, for a revenue team changing its system of record. The decisions are which system is master for each object and field, which direction each one syncs, and what happens to the reports built on the fields that move. The export is the easy half.

Consultants at The InHouse Marketers have delivered this move, and it sits under Salesforce to HubSpot in our migration track record beside the two marketing platform pairs, Marketo to HubSpot and HubSpot to Marketo. CRM work of this kind runs through our Salesforce practice and our marketing automation practice.

What moves as a record, and what has no HubSpot equivalent?

Three columns, agreed before the extract and signed by whoever owns the forecast. On this pair the second column holds most of the configuration a Salesforce org accumulates.

What transfers with an extract and a field map: contacts, accounts as companies, opportunities as deals, cases as tickets, products and price book entries as products and line items, notes, and files. Carry the Salesforce 18-character record ID onto every HubSpot record as a property while you are at it. It is the only join key you will have for reconciliation, for anything still reading Salesforce, and for the argument six months later about whether a record came across.

What gets rebuilt in HubSpot's model: pipelines and stages, assignment as workflow-driven owner rotation, validation as property rules and workflow enforcement, formula fields and roll-up summaries as calculation properties where they express at all, and every report leadership reads. Salesforce record types and page layouts have no single HubSpot equivalent, so the question becomes which pipelines and which property groups carry the same distinction.

What cannot move at all:

  • The Lead object and its conversion event. The subject of the trap section below.
  • Activity history. Activity history mostly stays behind: opens, clicks, form fills and page views remain in the old platform, so every report or scoring rule with a lookback window restarts at cutover. Tasks and meetings can be loaded as HubSpot activities with effort. Field history tracking, the setup audit trail and the Chatter feed have no destination.
  • Apex, triggers and anything written in code. HubSpot's nearest construct is a custom code action, which is a different programming model with different limits. Each Apex trigger needs a written decision: re-express as a workflow, re-express as code, or retire. A trigger nobody can describe is a retirement candidate.
  • The sharing model. Role hierarchy, org-wide defaults, sharing rules and field-level security do not map onto HubSpot teams and permissions one for one. Re-specify who can see what, and check a field you believe is restricted by opening a record as somebody junior.

Why is this an ownership question before it is a migration?

Because in most of these projects Salesforce does not switch off. Finance keeps a report, a business unit keeps its pipeline, an integration keeps writing. So the end state is two systems holding overlapping records, and the integration between them is the design.

HubSpot's Salesforce integration gives you two controls that decide everything downstream. An inclusion list decides which Salesforce records sync at all, and a rule per property decides which side wins when both have changed. Those two controls are the ownership model. Written down, they are a one-page table: object, field, master, direction, and the report that depends on it. Undocumented, they are the reason a sales operations lead spends a quarter asking why a value keeps reverting overnight.

Settle the table before the connector is switched on, field by field, with the reporting owner in the room. Two systems updating Lead Source is not a debate to have retrospectively. The field-use evidence that makes this conversation short, rather than a list of opinions about which fields matter, is what our audit checklist produces: for each field, how many records hold a non-null value and when it was last written.

What happens to lifecycle, scoring and routing?

Lifecycle is where the object models collide. Salesforce expresses the early funnel as a separate object with its own status picklist, and the later funnel as opportunity stages on a different object. HubSpot expresses the whole thing as one lifecycle stage property on the contact plus deal stages on a pipeline. So the Salesforce lead status values become lifecycle stages, and the mapping is a judgement and never a translation: two status values that meant the same thing to two teams have to become one stage or two, and somebody has to decide which. Build a timestamp property per stage transition at the same time, because the stamps are what attribution reporting reads and they have to be continuous across cutover.

Scoring depends on where it lived, and on this pair it usually did not live in Salesforce. If the model sat in Account Engagement or Marketing Cloud, that is a second migration with its own plan, and the rule holds: scoring models are not portable between platforms, because a two-dimensional profile and engagement grid does not map onto a single score field and behavioural decay is modelled differently in each platform. If the model sat in Salesforce as a formula field or a managed-package score, read the formula, re-derive the intent, and rebuild it as HubSpot score attributes. If there was no model, say so in the plan and treat scoring as new scope with its own estimate.

Routing is the part sales feels first. Salesforce assignment rules and lead queues have no HubSpot queue object behind them, so a queue becomes an owner-less state plus a workflow that rotates records to a team. Test it with records a rep will open. A lead called Test Test routes perfectly and tells you nothing. Then name one owner on each side of the handoff, marketing operations and sales operations, reachable through the cutover weekend, because leads not arriving is the one failure sales will remind you of a year later.

What happens to Web-to-Lead and the values it was carrying?

If HubSpot marketing is in scope, and on this pair it usually is, the website becomes its own workstream. Salesforce Web-to-Lead forms post to an endpoint with an organisation id and numeric field ids, plus whatever hidden values the site was stuffing in alongside: UTM parameters, GCLID, referrer, internal source and sub-source, consent flags, campaign ids. Each one has to exist as a HubSpot property before it can be a form field, and each gets verified by submitting a test and reading the created record. The register, the batching and the zero-submission alert are set out in website forms during a migration.

The Salesforce-specific item is the endpoint itself. Web-to-Lead will keep accepting posts long after everyone has agreed it was decommissioned, so switch it off on a date, with someone accountable for it, or it stays an undocumented data collection point feeding a system nobody is watching.

Consent does not transfer with a database: an opted-in flag in one system is not evidence of consent in another unless the record of how and when it was captured moves with it. Salesforce holds the email opt-out and do-not-call flags on the record with the bounce fields next to them, while the evidence of how consent was captured usually sits wherever the form posted. Read those together, re-express them as HubSpot subscription types, put the evidence fields alongside, and carry the bounce history and the manual do-not-contact entries into one suppression list that is master from the first send. A clean portal holding none of that history will mail every one of those people on day one.

Then the commercial mechanic. HubSpot distinguishes marketing contacts from the rest, only marketing contacts can be sent marketing email, and the count drives what the subscription costs. A Salesforce database carries years of records nobody intends to mail: closed-lost contacts, support-only contacts, partners, former employees. Loading all of them as marketing contacts turns an import setting into a budget conversation. Segment the extract into the people you intend to mail, the people you are keeping for sales context, and the people who should have been suppressed years ago.

What is the trap in a Salesforce to HubSpot migration?

The Lead object. Salesforce has two objects for one human and an event that links them; HubSpot has one contact and a property. No other pair on the track record has this problem, and it reaches further than the data model.

Three consequences, in the order they bite.

The first is deduplication. HubSpot deduplicates contacts on email address. Salesforce lets the same person exist as a Lead and as a Contact at the same time, and lets two records share an address across those objects. So a population that was two rows in Salesforce arrives as one contact in HubSpot, and the merge rule decides which field values survive. Write that rule down before the load, decide which object wins per field, and run it against a sample you can check by hand. Discovering the rule afterwards means reading merged records to work out what the import did.

The second is history. Converted date, and the links from a converted lead to the contact, account and opportunity it became, are the spine of every conversion-rate report in a Salesforce org. HubSpot has no conversion event to hold them. The values can be carried across as plain properties, which is worth doing because it is cheap and because nothing else will give you them later. What cannot be carried across is the report: lead-to-contact conversion rate by source and month has to be re-specified against one object plus a lifecycle stage, and the new number will not match the old one.

The third is everything built on the distinction. Lead assignment rules, lead queues, lead-only validation, lead-only page layouts, and the reports that count leads separately from contacts. Each is a decision, never a mapping. Make them in discovery, with the names of the people who agreed them, and accept that some of what the Lead object was doing was compensating for the fact that it existed.

What happens to the reports?

They get re-specified, and the time that takes is routinely left out of the plan. Salesforce report types, cross-object reports and roll-up summaries are not shapes HubSpot's report builder reproduces one for one, so the work is not rebuilding charts. It is agreeing what each number means now.

The sequence that keeps this from landing after go-live:

  • List the reports leadership reads, by name, with the Salesforce object and fields each one is built on.
  • Mark the ones resting on the Lead object, on converted date, or on a roll-up summary. Those are re-specifications, not rebuilds.
  • Decide each one's HubSpot source before the extract: a report, a calculation property, a warehouse table, or a written note that it is retired.
  • Name the charts that will look wrong after cutover, and tell the people who read them before the first one lands. Somebody who was warned asks a question. Somebody who was not escalates.

Then run both systems for a period and explain every difference. New records land in HubSpot; Salesforce stays readable, and the reconciliation is done by hand, daily, until it is boring. The six lenses this runs against are in how we run migrations, and the failure patterns that cut across every pair are in what breaks in a migration.

Frequently asked questions

How long does a Salesforce to HubSpot migration take?

What sets a migration timeline is the complexity of the operational layer, and not the volume of records. On this pair the schedule is set by how much logic lives in Apex, Process Builder and validation rules, how many reports rest on the Lead object or on roll-up summaries, and how long it takes to agree which system is master for each field. An org with standard objects and a handful of automations moves quickly. One with years of code and a reporting layer built on lead conversion does not.

Does the Salesforce Lead object exist in HubSpot?

No. HubSpot holds one contact object with a lifecycle stage property, so leads and contacts arrive as the same object and the conversion event has no destination. Converted date and the links to the contact, account and opportunity a lead became can be carried across as plain properties. The reports built on them have to be re-specified against one object, and the new numbers will not match the old ones.

Does activity history transfer from Salesforce to HubSpot?

Activity history mostly stays behind: opens, clicks, form fills and page views remain in the old platform, so every report or scoring rule with a lookback window restarts at cutover. Tasks and meetings can be loaded as HubSpot activities with effort. Field history tracking, the setup audit trail and the Chatter feed have no destination at all. Export what your reports depend on, and keep Salesforce readable until they are rebuilt.

Can Salesforce and HubSpot both stay live after the migration?

Usually they do, and that is a design and not a failure. HubSpot's Salesforce integration gives you an inclusion list deciding which records sync and a rule per property deciding which side wins. Write the ownership table first: object, field, master, direction, and the report that depends on it. Without it, a value that reverts overnight becomes a quarter of somebody's time.

What happens to Salesforce validation rules, formula fields and Apex?

Validation becomes property rules and workflow enforcement. Formula fields and roll-up summaries become calculation properties where they express, and a reporting job where they do not. Apex has no equivalent: the nearest construct is a custom code action with a different programming model and different limits. Give every trigger a written decision to re-express, rewrite or retire, because a trigger nobody can describe is a retirement candidate.

How do duplicates behave when Salesforce records load into HubSpot?

HubSpot deduplicates contacts on email address, while Salesforce lets one person exist as both a Lead and a Contact and lets records share an address across those objects. Two Salesforce rows can therefore arrive as one HubSpot contact. Decide the merge rule per field before the load, run it against a sample you check by hand, and keep the Salesforce record ID on each HubSpot record so the result can be traced.