HubSpot CRM Migration: What Survives the Import (2026)

GenFlows Team · · 32 min read

TL;DR

  • HubSpot imports records. It does not import history. Contacts, companies, deals, calls, emails, meetings, notes and tasks all have supported import paths. The derived reporting layer — time in stage, date entered stage, create dates on some objects — does not come with them.
  • The single most expensive field in your whole migration is optional. HubSpot documents Activity date as recommended, not required — and if you leave it out, activity dates are "automatically set to the date and time the activities were created." Two years of call and email history collapses onto go-live day.
  • Deal stage timestamps are read-only and derived from stage movement inside HubSpot. Import a deal that is already Closed Won and its only stage-history entry is the import itself. Time-in-stage and sales-velocity reporting starts at go-live, not at your first deal.
  • A multi-file import is capped at two files and two objects. "Select the two desired objects," says the UI. So a five-object migration is a planned sequence of imports joined on Record ID — not one upload.
  • Emails, meetings, notes and tasks are create-only. They "cannot be updated through imports." Get the timestamp or the association wrong and your only fix is delete-and-reimport.
  • Good news on the bill: the import tool sets contacts as non-marketing by default, and a multi-file import always does. Migrating 80,000 contacts does not automatically move you up a marketing-contact tier.
  • HubSpot's native Salesforce integration is not a migration tool. HubSpot's own documentation: "Records won't automatically sync after installing and setting up the Salesforce integration."
  • The onboarding fee is mandatory, and it is not migration. $1,500 on Sales Hub Professional, $3,500 on Enterprise, described as "required" in HubSpot's own product catalogue. It buys onboarding — HubSpot sells no productised CRM-data migration service at all.
  • Custom objects are Enterprise-only. If your old CRM leaned on them, that is a re-architecture decision during scoping, not a field-mapping problem on migration weekend.

Almost every CRM migration guide describes the same project: export a CSV, map your fields, click import, done. That project is real, and it is the easy fifth of the work. It is not where migrations go wrong.

Migrations go wrong two weeks after go-live, when someone opens a pipeline report and every deal in the business appears to have been created on the same Tuesday. Nothing was lost, exactly — the records are there, the notes are there. What is missing is the time dimension: when things happened, in what order, how long they sat. HubSpot builds that layer by watching records move, which is precisely why an import cannot hand it over. This post is the migration written backwards from that failure: what transfers, what structurally cannot, and which decisions are one-way doors.

Sourcing note: every limit, quoted sentence and property behaviour below was read on HubSpot's own knowledge base or developer documentation in September 2026, and quoted verbatim where it matters. Where HubSpot's own pages are inconsistent or silent, we say so explicitly rather than picking the tidier answer. Cost figures and project durations are marked (directional) in-text. Re-confirm limits against your own portal before you plan around them.

The Short Answer

Three mechanisms exist, and they solve different problems:

  • The import wizard is the right default for almost everyone: 512MB files, 1,048,576 rows per file and 10,000,000 rows per day on a paid seat. Its real constraint is not volume but that a multi-file import handles only two objects at a time.
  • The CRM imports API is for scale and repeatability — same per-file limits, but 80,000,000 rows a day. Use it when the migration should be a script you can rehearse against a sandbox rather than clicks somebody has to remember.
  • Data Hub data sync (formerly Operations Hub) can act like a migration but isn't one. Its initial pass does move existing records — "All existing records in both apps are passed through the sync engine" — then it keeps running, checking every five minutes, forever. Choosing it is a decision to operate two systems.

And one that is not a mechanism despite being sold as one: the native Salesforce integration. HubSpot is plain about it — "Records won't automatically sync after installing and setting up the Salesforce integration. You can import your Salesforce records into HubSpot, or allow them to sync gradually based on automatic sync triggers." It is a sync layer for running both platforms in parallel. If you are leaving Salesforce, you are still doing an import.

What Actually Moves, and What Doesn't

Take this into your planning meeting. The middle column is what people assume; the right column is what bites.

Data layerTransfers?What you need to know
Contact, company, deal, ticket records Yes — create and update The straightforward part. Required fields: Email for contacts; Name or domain for companies; Deal name, Pipeline and Deal stage for deals.
Custom objects and properties Yes — create and update Build the schema first. Importing into a property that does not exist yet means a second pass.
Calls Yes — create and update Call notes is the required property. Calls are the one activity type you can go back and fix, which makes them the safest to migrate first.
Emails, meetings, notes, tasks Create only They "cannot be updated through imports" — on any import path. One shot per record. Delete-and-reimport is the only correction.
Activity timestamps Yes — but opt-in Activity date is "recommended," not required. Omit the column and every activity is dated at import time. See below — this is the trap.
Activity ownership ("who logged this") No Activity "Created by user ID" — "This value is set automatically by HubSpot." Your migrated history is attributed to the importing user.
Deal stage history / time in stage No Read-only properties, derived from movement through a pipeline inside HubSpot. No documented way to set them.
Last Modified Date, Last Activity Date No Set automatically by HubSpot and not editable or importable. Deal Last Modified Date reflects "any property on a deal was updated, regardless of the source" — so your import itself sets it.
Create Date Unclear — test it HubSpot's own pages are inconsistent. See the section below; do not plan reporting around an assumption here.
Attachments and call recordings Indirectly The activity property holds "the IDs of the files attached to the activity" — file IDs, not URLs. The files must already exist in HubSpot, so uploading them is a prior step (directional: inferred from the property definition, not stated as a migration rule).
Email opt-out status Yes — separate import type A dedicated opt-out import, not a column on your contact file. Do it as its own step.
Per-type subscription preferences Not via import HubSpot documents managing subscription types on the record, in bulk from the index page, or by workflow — import is referenced only for opt-out lists.

The Activity Date Trap

If you read one section, read this one: it is the most common defect and the most permanent.

HubSpot's documentation says "while not required, it's recommended to include Activity date when importing new activities." That word "recommended" is doing enormous work. Activity date is what HubSpot defines as "the date and time the activity occurred" — the property that places an activity on the timeline. Omit it and the documented behaviour is that "the Activity date values are automatically set to the date and time the activities were created": the moment your import ran.

Why this is not recoverable. Emails, meetings, notes and tasks "cannot be updated through imports." So if you import 40,000 notes without an Activity date column, you cannot go back and add the dates — you have to identify all 40,000 wrongly-dated activities, delete them, and import again. On a live portal that people are already working in, that is a materially harder job than the original import.

Two consequences. Activities are the part to rehearse in a sandbox rather than do confidently on the first pass. And calls are the exception worth exploiting: they support create and update, so a call import you get wrong is fixable — migrate them early while you are still learning your data, and save notes and emails for when the mapping is proven.

On the API the same idea is an explicit required field rather than a footnote: a note requires hs_timestamp, which HubSpot describes as marking "the note's time of creation" and determining "where the note sits on the record timeline." One more argument for the API path on a history-heavy migration — there, the thing you must not forget is not optional.

Required properties, by activity type

ActivityRequiredAlso bring
Call Call notes Activity date, direction, duration, outcome
Email Email body, Email direction Activity date, subject
Meeting Meeting description, start time, end time Activity date, outcome
Note Note body Activity date
Task Task title, Due date Activity date, status, type
Line item Name, Quantity, Price Must be associated with a deal — Record ID or Deal name

The Reporting Layer You Cannot Import

This is the part no amount of careful field mapping solves, and the reason a migration is a reporting project rather than a data project.

HubSpot's stage calculated properties — "Date entered [stage]", "Date exited [stage]", "Latest time in [stage]", "Cumulative time in [stage]", "Date entered current stage", "Time in current stage" — are the foundation of every pipeline, velocity and conversion report you will build. One HubSpot sentence settles the question: "These are read-only HubSpot default properties that automatically update based on record movement through a pipeline." Read-only, and derived from movement through a pipeline. There is no column to map and no field to write.

The same page carries a sentence that is easy to misread in your own favour: "The values for the properties will be populated retroactively based on existing data." That retroactive population runs against HubSpot's own property history, not your legacy CRM — it does not mean HubSpot reconstructs the history of a system it has never seen. To be precise about what is documented: HubSpot nowhere states, in so many words, that historical stage timestamps cannot be backfilled. It states that they are read-only and derived. The consequence follows from the mechanism, and the mechanism is unambiguous.

What this looks like on go-live day. You import a deal that closed eleven months ago, already at Closed Won. HubSpot writes one stage value, now. That deal's only stage-history entry is the import timestamp. It has no date entered Discovery, no date entered Proposal, and no time in any stage but its last. Multiply by your whole deal table and your average-sales-cycle report reads as roughly zero days, forever, for every deal that predates the migration. (Directional: this is the reasoned consequence of the documented mechanism, not a quoted HubSpot statement.)

Note too that these properties are gated to Professional and Enterprise across HubSpot's hubs. On Starter you do not get the reporting layer at all, which changes what is even worth migrating.

The three things to do about it instead

1. Migrate stage history into custom properties. If your source CRM exports "date entered proposal" per deal, create matching custom date properties — legacy_date_entered_proposal and so on — and import into those. Native velocity reports will not read them; a custom report will, and the data lives in HubSpot rather than in a decommissioned tool. Do it before you cancel the old contract.

2. Draw a bright line in your reporting. Decide explicitly that native pipeline-velocity reporting measures post-migration deals only, tell leadership that date before they find it themselves, and keep pre-migration history as a separate, clearly-labelled custom report. The failure mode is not missing data — it is a blended report quietly averaging real cycle times with zeros.

3. Keep the source system readable for a quarter. Readable, not writable. A month of the old CRM's cheapest tier is the best insurance in the project, because the questions you cannot anticipate all arrive in weeks two through six.

For what to build once you are the other side of this, our guides to HubSpot deal stages for outbound teams and building a RevOps dashboard both assume a clean stage-history layer — which is exactly why the migration decision above determines what you can report on for the next year.

Create Date: Two HubSpot Pages, Two Answers

Every migration asks this, and the honest answer is that HubSpot does not say clearly.

On the default deal properties page, Create date is "set automatically by HubSpot, but can be manually edited." On the default contact properties page it is "the date that the contact was created in your HubSpot account. This is automatically set by HubSpot" — no editability clause. The company page takes no position either way. So one object's docs say editable, another's say automatic, and none of the three states whether the property accepts a mapped column on import. You will find confident blog posts asserting each answer; we could not find the sentence.

The only safe move: test it, on your own portal, before you plan around it. Import ten records with a mapped Create Date into a sandbox or a throwaway pipeline, then look at what the property says. Ten minutes of testing beats a documented answer that does not exist — and beats discovering the behaviour after 60,000 contacts are in.

One genuine backfill path exists for editable properties: HubSpot supports exporting a property's history and re-importing it — "once you've exported a property's history, use the data to restore past values," then "import the new file into HubSpot." It is capped at 45 revisions for contacts and 20 for companies, deals, tickets and custom objects, and it does not rescue read-only stage-calculated properties. It restores values you once had in HubSpot; it is not an on-ramp for foreign history.

The Two-Object Ceiling, and Why Import Order Matters

Most migrations involve at least four objects — companies, contacts, deals, activities. HubSpot's multi-file import handles two; the UI instruction is "Select the two desired objects," with one object plus one activity type also allowed. That single constraint dictates the shape of the project: not one import but a planned sequence, stitched together by Record ID.

Three documented behaviours to internalise first:

  • "If a row in your file doesn't contain a value for Record ID, a new record will be created." This is how a careless second pass duplicates your entire contact table.
  • "Record ID is mapped during your import, it will supersede any other mapped unique identifiers." Record ID wins over email, over domain, over your custom key. Powerful, and unforgiving.
  • For same-object associations (contact to contact, company to company), "At least one record in a record pair must already exist in HubSpot" — and explicitly, "You cannot import to create and associate two new contacts."

Cross-file associations are made on a common column present in both files and unique per row in one of them — your source CRM's own account ID is usually the right choice, and worth importing into a custom property so the mapping survives the project. Where one record associates to several, separate values in the cell with semicolons. Association labels require Professional or Enterprise.

The order that works, and why:

PassWhatWhy here
0 Schema: properties, pipelines, stages, owners, custom objects Nothing can land in a property that does not exist. Deals need their Pipeline and Deal stage to exist first.
1 Companies, carrying the source system ID The top of the association tree. Deduped on domain.
2 Contacts + company association (two-file import) Companies now exist, so the common column resolves. Export the resulting Record IDs.
3 Deals + their associations Needs contacts and companies in place. Bring legacy stage-date custom properties on this pass.
4 Calls (fixable), then notes / emails / meetings / tasks (not) Last, with Activity date mapped, against known Record IDs. Rehearse in a sandbox first.
5 Opt-out list, as its own import type Separate mechanism from the contact import. Never leave this to the end of a busy week.

One note on runway: HubSpot runs a maximum of three simultaneous imports — "if you start 4 or more simultaneous imports, they will be queued" — with at most two exceeding 10,000 rows. A weekend migration is serial by design. Plan the hours.

Dedupe Before You Import, Not After

Import-time deduplication is exact match on a single unique identifier: Email for contacts, Company domain name for companies, Record ID for any object, or a custom property whose values you have made unique. There is no fuzzy matching in the import path.

HubSpot does have fuzzy duplicate detection — a separate tool that scores likely duplicates daily, matching contacts on First Name, Last Name, Email address, IP country, Phone number, Zip Code and Company Name, and companies on Company Domain Name, Company Name, Country/Region, Phone Number and Industry, with custom rules over up to nine properties on Data Hub. But that is post-import cleanup; it will not stop a messy file from making the mess.

Two controls to use deliberately: the import mode — "Create and update", "Create new only", "Update existing only" — and the per-column "Don't overwrite" checkbox, which stops an import replacing values that already exist. On any pass after the first, "Update existing only" is what makes a correction safe.

One easily-missed rule: "If you're using a custom unique value property to deduplicate contacts, the Email property will still require unique values." A clever composite key does not exempt you from HubSpot's email uniqueness, so if your source CRM lets two contacts share an address, resolve it in the file rather than the wizard. Our guide to CRM data hygiene for outbound teams covers the cleanup worth doing first — a migration is the best chance you will get not to carry six years of duplicates forward.

Opt-Outs, Compliance and the Bill

Opt-outs are a separate import type, not a column. HubSpot's opt-out import takes a CSV with an Email column and sets "the Unsubscribed from all email property of all the contacts" to true, disqualifying those addresses "from receiving any future marketing emails or emails sent through the sequences tool." That covers sequences, not just marketing email — exactly what an outbound team needs it to cover.

A useful billing nuance rides along: "Contacts added via an opt-out import will not be added to your billable contact total or created as contacts." If the address already exists as a contact it stays one and keeps counting, and HubSpot's documented workaround is to delete those contacts then re-import the addresses as opted-out. For a large suppression list of people you will never market to, that is a real saving, and a migration is the right moment to take it.

Two more compliance details. For legitimate one-to-one outbound, you "can still send a one-to-one email to an existing contact updated through an opt-out import as long as you provide one time legal basis with each one-to-one send." And the "Legal basis for processing contact's data" property carries a consequence worth reading twice: "if this is set to Not applicable, it will exempt the contact from GDPR protections." Set that field intentionally during a migration rather than leaving it to a default — our cold email compliance guide covers the consent side in depth.

On marketing contacts, the news is good. Only marketing contacts count toward your contact tier and affect subscription cost, and HubSpot documents the import default clearly: "the import tool sets contacts as non-marketing by default," and "if you're completing a multi-object or multi-file import, the import tool will always set contacts as non-marketing." API and integrations behave the same way. So a large migration does not silently push you up a pricing tier — the tool defaults to the cheap side and you opt contacts into marketing status afterwards, deliberately. (Forms, by contrast, set contacts as marketing by default.) Still worth setting a maximum marketing contacts limit as a guard before go-live.

Import Wizard vs API vs Data Sync

Import wizardImports APIData Hub data sync
Per file 512MB, 1,048,576 rows (paid); 20MB on free tools 512MB, 1,048,576 rows n/a — record-level sync
Per day 10,000,000 rows, 500 imports (paid); 500,000 rows, 50 imports (free) 80,000,000 rows Continuous; five-minute change checks
Objects at once Two files / two objects max Multiple, with association type mapping Supported objects per app
Repeatable Manual, clicks Yes — scriptable, sandbox-testable Ongoing by design
Tier notes Association labels need Pro/Enterprise Needs the crm.import scope; rate limits are tier-based Available on all plans; custom field mappings need Data Hub Starter+
Use it when Most migrations. Under a few hundred thousand records. Heavy activity history, or you need a rehearsable script You are keeping both systems, not leaving one

On the API path, know the rate limits before you write the script. For a privately-distributed app: 100 requests per 10 seconds and 250,000 per day on Free and Starter; 190 per 10 seconds and 625,000 per day on Professional; 190 and 1,000,000 on Enterprise. An API Limit Increase add-on can be bought up to twice, each adding 250 per app and 1,000,000 per account, and exceeding a limit returns HTTP 429. The burst limit applies per app while the daily limit is shared across every app in the account (directional — consistent with HubSpot's published per-app vs per-account columns), which matters when your migration script competes with a production integration. One deal-specific gotcha: "You must use the internal ID of a deal stage or pipeline when creating a deal via the API" — not the label in the UI, so pull the internal IDs first.

If your outbound tools are the reason you are moving to HubSpot at all, the integration path is a separate design question — see syncing cold email and LinkedIn data into HubSpot and the Clay + HubSpot integration. Do not try to solve both in the same weekend.

Before You Cancel the Old Contract

Every migration has one genuinely irreversible step, and it is not an import — it is the day the source system stops being readable. Almost every "we lost our history" story traces back to an export nobody took, or took in a format nobody checked. Gotchas by source system, from each vendor's own documentation:

SourceThe gotcha nobody plans for
Close CRM Your call, email and SMS history is fully exportable — but "JSON is the only format you can use to export all Activities." Not CSV, which is what your migration tool and your ops person both expect. Also: contacts export from the Leads page, "not from the Contacts page"; Notes, Meetings, Email Messages and SMS Messages need a support request for CSV; download links expire after 7 days; and the Event Log API reaches back only 30 days, so audit history older than a month is already gone.
Pipedrive "Activities, notes and files linked to deals and contacts must be exported separately" — there is no one-click everything. Worse, exports reflect only what is visible to the exporting user, so a rep-run export silently drops records; use a global admin. Files stored in Google Drive are not included. Exports remain available 28 days.
Salesforce The cliff. Standard Field History Tracking retains history for 18–24 months and tracks up to 20 fields per object; Salesforce "archives data after 18 months in production." The Field Audit Trail add-on extends that to "until deleted" and 200 fields — but is API access only, with no UI export. Then in Data Loader, plain Export omits archived activity and soft-deleted records: you need "Export All."
Apollo.io Better than its reputation. Emails export to CSV from the Emails hub, and per-contact engagement state — Email sent, Email open, Replied, Email bounced, Last contacted, Stage — rides along on the contact export. Watch two things: exports consume export credits, and CSV exports do not retain Apollo's sort order, with emails and phone numbers not always included unless enabled in export settings.
Smartlead The best reply export of any tool here. The inbox CSV carries Sequence Number, Sent Time, Opened Time, Clicked Time, Replied Time and Reply Message — "the content of the reply, if applicable." Actual reply bodies, in a spreadsheet.
Instantly Every event about a reply exports — sent, opened, clicked, replied, bounced, with timestamps and clicked links — but "there is no direct way to bulk export all Unibox replies from the interface." Reply text needs API work. And an active subscription is required to reach the dashboard at all, so export before you cancel, not after.

The one-line version: take every export while the subscription is still active, keep the raw files, and check the format before you trust them. Close links die in 7 days, Pipedrive's in 28, and Instantly locks the dashboard when the plan lapses. If your Salesforce org has been running longer than two years without Field Audit Trail, some of the history you are planning to migrate does not exist any more — find that out now, not in the kickoff call.

What Your HubSpot Tier Can Actually Hold

One structural limit reshapes more migrations than any other: custom objects are Enterprise-only. Marketing, Sales, Service, Content and Revenue Hub Enterprise allow up to 10 custom object definitions, 1,000,000 custom object records and 50 custom object pipelines; Data Hub Enterprise raises that to 20 definitions, 1,500,000 records and 100 pipelines. On Sales Hub Professional you model contacts, companies, deals and tickets — and nothing else.

If your Salesforce org or Close instance leaned on custom objects, that is a re-architecture decision for scoping, not a mapping problem to discover mid-import. Flatten the custom object into properties on an existing one, or accept the Enterprise price step — both are fine; being surprised on migration weekend is not.

Other published ceilings worth knowing while you scope: 1,000 custom properties per object, identical on Starter, Professional and Enterprise; 15 million records per object type included, extendable to 50 million via paid limit increases at $1,100 per month per additional million (Enterprise only); workflows capped at 300 on Professional and 1,000 on Enterprise; active lists at 50 on Starter, 1,200 on Professional, 2,000 on Enterprise.

Cost and Timeline

There is exactly one hard, published number in this entire market, and it is HubSpot's own.

Line itemPublished costConfidence
HubSpot Sales Hub Professional onboarding $1,500 one-time, required Verified — product catalogue and pricing page
HubSpot Sales Hub Enterprise onboarding $3,500 one-time, required Verified
Marketing Hub onboarding, if in scope $3,000 Professional / $7,000 Enterprise Verified — and the reason "$3,500 for Professional" gets misquoted
Import2 CRM migration $499 up to 50k records · $999 up to 100k · $1,499 up to 200k · $1,999+ above Verified on Import2's own pricing page
MigrateMyCRM by SyncMatters Free under 100 records · $149 under 5k · $349 under 12.5k · $599 under 25k · $1,199 under 100k · $2,499 under 500k · $3,499 to 2M. Guided Migration add-on $875 Verified on SyncMatters' own pricing page
Agency / Solutions Partner migration Roughly $3,000–$6,000 for basic onboarding; CRM data migration quoted from about $7,000 (directional) — no published rate card exists; see below

Three things about that table deserve saying out loud.

The onboarding fee is required, and HubSpot's own pages are inconsistent about it. The pricing-page footnote and the legal product-and-services catalogue both use the word "required" — "Onboarding is required for a one-time fee of $1,500" — while HubSpot's softer services page frames it as "when you purchase onboarding." The legal catalogue is the binding document, so budget it as mandatory at Professional and above. And note what it buys: onboarding, not data migration. HubSpot's published "Migration Services" SKUs are website and CMS replatforming and require Content Hub. HubSpot does not sell a productised CRM-data migration service at all.

Do not trust marketplace listing prices. Both Import2 and MigrateMyCRM appear in HubSpot's app marketplace at $99, which matches neither vendor's own pricing page ($499 and $149). Import2's listing even carries the disclaimer that "the pricing here is for display purposes only." Quote the vendor page. Both are HubSpot Certified apps — a marketplace programme, not HubSpot authorship — and if you are looking for Trujay, that brand is retired and redirects to SyncMatters.

Agency pricing has no published floor. HubSpot publishes no partner rate card, and every range in circulation comes from agencies selling the service. The most traceable set we found compiles partners' own published rate cards: roughly $3,000–$6,000 for basic onboarding, $10,000–$25,000 for complex multi-hub work, CRM data migration from about $7,000. That is self-published marketing rather than survey data, so treat it as a sighting shot, not a benchmark. Our RevOps agency pricing guide goes deeper on what HubSpot help costs.

On timeline, and one statistic we are not going to repeat

You will read that 70% of CRM projects fail. We tried to source it. Every trail ends at a consultancy's own blog, a literature review we could not open, or a Gartner press release from the early 2000s that is no longer published. There is no primary study behind the number, so we will not quote it — and you should discount any migration proposal that opens with it.

What we can offer instead is HubSpot's own scoping: every hub onboarding SKU carries a stated delivery period of 90 days from purchase. That is a far better planning anchor than a folklore percentage. The data work is usually a small fraction of that window — the schema decisions, the reporting bright line and the export archaeology are what fill it.

The Migration Checklist

In order, and the first four are the ones that get skipped:

  1. Export everything from the source CRM while you still pay for it — including the exports you do not think you need, and field history and activity logs especially. Then download the files: Close links expire in 7 days, Pipedrive's in 28, and Instantly locks the dashboard when the subscription lapses. This is a one-way door tied to a billing date.
  2. Decide your reporting bright line and tell leadership the date before go-live. Native velocity reporting starts at migration.
  3. Check what your tier can hold before mapping anything — custom objects need Enterprise, and properties cap at 1,000 per object on every tier.
  4. Build the schema first: properties, pipelines and stages, owners, custom objects, and legacy date properties for stage history you want to keep.
  5. Rehearse activities in a sandbox. Emails, notes, meetings and tasks are create-only; the rehearsal is the only cheap place to get Activity date wrong.
  6. Test Create Date behaviour on ten records rather than trusting any blog post, this one included.
  7. Clean and dedupe the files, resolve duplicate email addresses, and carry the source system ID into a custom property on every object.
  8. Import in dependency order: companies, then contacts, then deals, then calls, then the create-only activities.
  9. Run the opt-out import as its own step, and delete-then-reimport pure suppression addresses so they stop counting as billable contacts.
  10. Set marketing contact status deliberately and set a maximum marketing contacts limit as a cost guard.
  11. Reconcile by count and by spot-check: record counts per object, association counts, then ten records walked end to end against the source.
  12. Keep the old CRM readable for a quarter at its cheapest tier.
  13. Only then connect your sending tools, sequences and automation. A migration and an integration project in the same week means you cannot tell which one broke.

Frequently Asked Questions

Can you import deal stage history into HubSpot?

No, not into HubSpot's native stage properties. Stage calculated properties such as "Date entered [stage]" and "Cumulative time in [stage]" are, in HubSpot's words, "read-only HubSpot default properties that automatically update based on record movement through a pipeline" — they are computed from stage changes that happen inside HubSpot, so there is no column to map. HubSpot's note that values are "populated retroactively based on existing data" refers to its own property history, not your legacy CRM. The practical workaround is to create custom date properties, import your legacy stage dates into those, and build a custom report on them. Native pipeline-velocity reporting will effectively start at your migration date.

Does migrating contacts into HubSpot increase my bill?

Not automatically. Only marketing contacts count toward your contact tier and affect subscription cost, and HubSpot documents that "the import tool sets contacts as non-marketing by default" — and that a multi-object or multi-file import "will always set contacts as non-marketing." Integrations and the API default to non-marketing too. So a large migration lands on the cheap side of the meter and you opt contacts into marketing status afterwards, deliberately. Two things to still do: set a maximum marketing contacts limit as a guard, and handle pure suppression addresses through the opt-out import, since contacts added that way "will not be added to your billable contact total."

How much history actually transfers when you migrate to HubSpot?

The records and their content transfer well; the metadata about when and by whom does not, fully. Calls, emails, meetings, notes and tasks all have supported import paths, and their timestamps transfer if you map Activity date — a property HubSpot describes as recommended rather than required, which is why so many migrations flatten their whole timeline onto the import date. What does not transfer: activity ownership, because activity "Created by user ID" is "set automatically by HubSpot"; deal stage history and time-in-stage; and Last Modified Date, which your import itself sets. Attachments are referenced by HubSpot file ID, so files have to be uploaded to HubSpot before an activity can point at them.

Is HubSpot's Salesforce integration a way to migrate off Salesforce?

No, and HubSpot says so directly: "Records won't automatically sync after installing and setting up the Salesforce integration. You can import your Salesforce records into HubSpot, or allow them to sync gradually based on automatic sync triggers." It is a two-way sync layer for running both platforms together, and it requires Professional or Enterprise on the HubSpot side plus a Salesforce edition with API access — Group Edition is not supported. If you are leaving Salesforce, you are doing an import or an API migration; the integration is for the parallel-running period, not the move.

Can you import all your objects into HubSpot in one go?

No. A multi-file import is capped at two files and two objects — the UI instruction is "Select the two desired objects" — or one object plus one activity type. A typical migration is therefore a sequence of imports joined on Record ID and on a common column carried in both files. Two rules govern that sequence: "if a row in your file doesn't contain a value for Record ID, a new record will be created," which is how second passes duplicate whole tables, and "Record ID is mapped during your import, it will supersede any other mapped unique identifiers." HubSpot also runs at most three simultaneous imports, queueing the rest, so plan the migration as serial work.

How much does it cost to migrate to HubSpot?

Budget three separate line items. First, HubSpot's onboarding fee, which is the only published hard number in this market and is described as required: $1,500 one-time on Sales Hub Professional and $3,500 on Enterprise (Marketing Hub is $3,000 and $7,000, which is where the misquoted "$3,500 for Professional" comes from). That fee buys onboarding, not data migration — HubSpot's own "Migration Services" SKUs are website and CMS replatforming, and it sells no productised CRM-data migration service. Second, tooling if you use it: Import2 charges $499 for up to 50,000 records and $999 up to 100,000, while MigrateMyCRM by SyncMatters runs from free under 100 records to $1,199 under 100,000, with an $875 guided add-on. Ignore the $99 figures on their HubSpot marketplace listings — neither matches the vendors' own pricing pages. Third, implementation help, where no published rate card exists; partner rate cards we could trace suggest roughly $3,000–$6,000 for basic onboarding and around $7,000 upward for data migration (directional).


Planning a move into HubSpot and want the reporting consequences mapped before the first file goes up? If you are still choosing the platform, start with our Close CRM vs HubSpot comparison for outbound teams or the wider CRM comparison for B2B outbound — then talk to our team. We build cold email, LinkedIn and HubSpot infrastructure for B2B teams, and migrations are where we spend most of our RevOps time.

By the GenFlows GTM engineering team. All import limits, property behaviours and quoted sentences were read on HubSpot's own knowledge base and developer documentation in September 2026 and are quoted verbatim where quoted; where HubSpot's pages are inconsistent or silent we say so rather than pick an answer. Cost and duration figures are marked directional in-text. HubSpot changes limits — re-confirm against your portal before planning around them. Last updated September 2026.

Share in X
Written by
GenFlows Team

The GenFlows team builds AI-powered cold outbound systems for B2B teams.

Ready to fill your calendar?

We build AI-powered cold outbound engines that book meetings on autopilot. Let's see if it fits your team.

Book a Call