All articles

Custom CRM

CRM Data Migration Checklist: 9 Silent Losses

The import says success and nine things are already gone. A field service CRM migration checklist built from the vendors' own import documentation.

Om Patel 19 min read
Photo: Tasha Kostyuk / Unsplash

The short answer

A CRM data migration runs in eight steps: inventory objects, export completely, dedupe, map fields explicitly, decide what not to migrate, load in dependency order, test on twenty records, then cut over. The step that decides the outcome is none of those. It is knowing which nine things your new platform drops without ever showing you an error, because unmapped fields, invoice line items and job photos fail silently while the import reports success.

Every CRM data migration checklist you will find says the same eight things: audit, back up, map, dedupe, test, import, validate, train. They are all correct and none of them are the reason migrations go wrong.

Here is the honest version. The import will tell you it succeeded. It will be lying by omission, because the things that fail during a CRM migration fail silently: unmapped fields are discarded without warning, invoice line items collapse to a single line, note timestamps get rewritten to today's date, and job photos never move at all. You find out in week three, when a tech opens a customer record before a call and the history is empty.

This checklist is written for service businesses, where the data is shaped differently than the Salesforce-to-HubSpot migrations most guides describe. Your atomic unit is not a company. It is a property, with equipment on it, with a job history attached. That distinction breaks almost every generic checklist on the first step.

The short answer

A CRM data migration runs in eight steps, in this order:

#StepWhat it actually decides
1Inventory the objects you ownWhether you discover the losses now or in month two
2Export completely, not convenientlyWhether line items and expenses come with you
3Dedupe at sourceWhether your team trusts the numbers in week one
4Map every field explicitlyWhether anything is discarded without telling you
5Decide what you are not migratingWhether you move the mess into a nicer building
6Load in dependency orderWhether relationships survive the trip
7Test on twenty records, reconcileWhether you catch a broken mapping at 20 records or 20,000
8Cut over, validate, keep the old system read-onlyWhether you can answer "where did that field go" in March

Budget two to four weeks of calendar time and 20 to 40 hours of real work for a few thousand customers. The export is hours. Everything else is the project.

Why generic checklists fail service businesses

Generic CRM migration guides model your business as companies, contacts, deals and activities. That model was built for B2B software sales, and it has no place to put the three things a contractor actually runs on.

The property, not the company. A homeowner with a rental duplex is one customer and three service addresses. Housecall Pro's import field list treats service address and billing address as genuinely separate fields with separate notes, which is correct. But ServiceTitan's guide to exporting Housecall Pro data warns about the consequence: "If you have multiple addresses on file for some of your customers, your exported customers report will include additional sets of address columns." Your CSV has a variable number of columns depending on which customer has the most properties. Any importer expecting a fixed column order chokes, and any spreadsheet cleanup that assumes a stable layout quietly shifts data into the wrong fields.

The equipment, not the deal. The serial number, model, install date and warranty expiry on the furnace in that basement is the single most valuable record a service company owns. It is what lets you avoid billing for warranty-covered work, and it is what tells you which customer to call in 2027. It is also the object no generic checklist mentions. Note that Housecall Pro's own documentation scopes equipment migration to their MAX plan, handled by their Data Import team alongside customers, job history and price book. On a lower tier, equipment is your problem.

The attachment, not the note. Job photos, signed estimates, permits and load calculations. These are frequently the largest data volume in the account and the least likely to move.

Watch out

Before you sign anything, ask the new vendor one question in writing: "Which of my objects do you import, and what happens to a field I cannot map?" The answer separates vendors who have done this from vendors who will hand you a CSV wizard and wish you luck.

The nine things that vanish silently

This is the part no competing checklist publishes, because it requires reading the vendors' own import documentation rather than describing migration in the abstract. Each of these is documented behaviour, not speculation, and none of them produces an error.

#What disappearsWhyThe fix
1Any field you did not mapHousecall Pro: "fields that are not mapped will be discarded"Review every mapping screen before continuing, hover each column to preview
2Invoice line items past the firstImporters expect one row per invoice; exports give one row per line itemMerge rows into a single row per invoice on the invoice number before upload
3Custom fields with no destinationHCP's guide states custom fields cannot be createdConcatenate into the notes field with a label prefix, e.g. "pH Level: 7.2"
4Sub-customers and parent-child billingHCP supports "only one level of customers"; child accounts are not importedFlatten sub-customers onto their own rows before import, rebuild the hierarchy after
5Note and activity timestampsMany platforms stamp imported records with the import datePrefix each note body with its real date and source so the timeline survives in text
6Job photos and attachmentsUsually not included in any standard exportBulk download separately, keep the old account read-only, re-attach only what is active
7Material and expense records logged to jobsLive in reporting exports, not the standard data exportPull a custom expense report filtered by date range
8Recurring job templates and maintenance agreementsCommonly not exportable at allScreenshot them and rebuild by hand. This is your recurring revenue
9Everything past row 1,500Some exports cap rows per file and split into multiple emailed filesCount your records first, then count the rows you received

Number 5 deserves a specific mention because it is the most quietly destructive. A practitioner posting a PSA in r/gohighlevel documented that GoHighLevel "stamps every imported note with the import date, not the original date. So years of history all collapse to 'today.'" Their conclusion is worth quoting directly: "For a CRM that kills the whole point of notes, the timeline's gone." Their workaround, after finding no native fix, was to write the original date and source into the body of every note before importing. It is inelegant and it works.

By the numbers

Industry estimates put typical duplicate rates at 10 to 30% of CRM records, and pre-migration cleaning is widely cited as 3 to 10 times cheaper than fixing the same records after they land. A contractor who documented moving nine years off Jobber found 34 duplicate pairs in 847 clients, plus about 180 clients with no email address at all.

Step 1: Inventory the objects, not the records

Write down every object you own and, next to each, the count. Not "we have about 900 customers." A real number per object:

  • Customers, and separately, service addresses (these are different numbers)
  • Equipment records, with how many have a serial number and install date
  • Jobs and work orders, open versus closed
  • Estimates, open versus expired
  • Invoices, and separately, invoice line items
  • Payments and credits
  • Attachments, with total file size
  • Price book services and materials
  • Recurring templates and maintenance agreements
  • Team members and their roles
  • Tags, lead sources, job types and business units

The gap between customers and service addresses is your first finding. The gap between invoices and invoice line items is your second, and it tells you exactly how bad the row-collapse problem will be. If you have 4,000 invoices and 14,000 line items, a naive import loses 10,000 rows of detail and every invoice total will be wrong.

Step 2: Export completely, not conveniently

Neither major field service platform gives you one complete file, and both have a default that quietly under-exports.

Jobber. Exports live in Settings under Data Export, and clients, job history and invoice history come out as separate CSVs. Per a contractor's firsthand account of the process, published as a guest post on the Bit and Grain blog, the client list exports cleanly with name, address, email and phone. The job export includes title, client, status, created date and scheduled date, but "does NOT include the line item detail from invoices, the material costs logged to the job, or the notes you have added along the way." Invoice line items require a separate pull from Reports. Material and expense records need a custom expense report filtered by date range. And in his words: "Job photos and attachments do not export automatically. Recurring job templates do not export."

Housecall Pro. Only employees listed as Admins can export customers and jobs. Both arrive by email as CSVs from their notifications address rather than downloading in-browser, so budget an hour of waiting. The critical default: ServiceTitan's migration documentation instructs you to set the date range back to "when you first started using Housecall Pro" and, in Table Columns, "select all items." Skip that and you export the columns currently visible on your screen, which is a fraction of what exists. The same guide notes that if the report errors, you should run it in one-year batches.

Reconcile every file against your Step 1 counts before you go further. If you counted 2,140 customers and the CSV has 1,500 rows, you are holding one of several files.

Step 3: Dedupe at source, before mapping

Duplicates are not a cleanup task for later. They propagate. One duplicate customer becomes two service addresses, two job histories, two invoice streams and two sets of equipment, and separating them after import means merging records that now have real activity attached to both.

A migration consultant writing in r/CRM put the human consequence sharply: if you do not resolve identity before import, "you ship duplicates on day one, reps stop believing the numbers in week one, and by month two they're keeping their real pipeline in a spreadsheet again. Now you have two CRMs and paid for the privilege."

For service businesses, match on the service address plus phone, not on the customer name. Names are unreliable: the same household appears as "Bob Smith," "Robert Smith," "Smith, Robert" and "Bob and Sue Smith" over ten years. The property address barely changes. Decide survivorship rules in advance, meaning which record's phone number wins when two disagree, and apply them consistently.

We run this object inventory and export audit as the first hour of every scoping call, including for businesses moving to a platform we did not build. If Jobber or Housecall Pro fits how you work, we will tell you to buy it. The builds worth doing are the ones where no packaged tool can model the properties, equipment and recurring work you actually run.

Book a free CRM demo

Step 4: Map every field explicitly, and kill the orphans

Every field gets one of four decisions written next to it: migrate, transform, archive, or drop. "Keep everything" is not a decision, it is a deferral, and the importer will make the decision for you by discarding it.

Work through the mapping screen slowly. Housecall Pro's wizard lets you hover each field to preview the column contents, which is the only chance you get to catch that your "Organization" column landed in the wrong destination. Where the destination has no matching field and custom fields cannot be created, use their documented workaround: prefix the value with a label and merge it into notes, so "7.2" becomes "pH Level: 7.2" and stays legible to a human later.

Three transformations to run before upload, all of which fail silently otherwise:

  1. Dates to ISO format. Convert every date column to YYYY-MM-DD as text. Day-first and month-first are ambiguous, and 03/04/2026 flips to a different date without erroring. This trap is covered in more depth in our spreadsheet to CRM migration guide, and it applies identically here.
  2. One row per invoice. Merge multi-line invoice rows on the invoice number, combining line items into a single field. Housecall Pro's formatting guide is explicit that multiple rows for the same job "will not upload successfully," and that uploading only the first occurrence means "additional data existing in subsequent rows (such as the additional line items) will not import."
  3. One sheet, not many. Most importers accept a single sheet. If your job detail and invoice header are separate reports, join them on the invoice number yourself before uploading.

Step 5: Decide what you are not migrating, the contractor way

This is where standard CRM advice is actively wrong for a service business, and it is the highest-value contrarian call on this list.

Generic guidance says archive any contact untouched in 24 months, because B2B contact data decays and old records are mostly fiction. For a software sales pipeline, that is right. The contact left the company, so the record is dead.

For a contractor, the homeowner did not leave the house. A customer you have not spoken to since 2011 is not a dead lead, they are a replacement job approaching. Furnaces average roughly 15 to 20 years and air conditioners roughly 10 to 15, per manufacturer lifespan guidance from Carrier and Trane, so the 2011 install in your "dormant" pile is the 2026 quote you are about to lose to whoever knocks first.

So invert the rule. Segment by equipment age and install date, not by last contact date.

  • Migrate in full: every customer with equipment on site, regardless of when you last spoke to them. This is your replacement pipeline and it is the most valuable list you own.
  • Migrate in full: anyone under a maintenance agreement, plus open jobs, open estimates and unpaid invoices.
  • Migrate as a summary: closed job history older than about three years. One line per job, with date, description and amount, is usually enough to answer "have we been here before and what did we charge."
  • Leave behind: one-time calls with no equipment installed and no contact detail, duplicate shells, and anything with neither a valid phone nor a valid address.

The same r/CRM consultant framed the general principle well: "History is a trap that looks like a feature. Everyone wants 'all the notes.' Almost nobody needs all the notes." That holds. The contractor amendment is that equipment records are the exception, and they are the one thing you should bring even when the contact looks cold.

The contractor who documented his Jobber move made exactly this call by feel: of 847 clients, about 320 had a job or estimate within two years. He imported all 847 anyway, and re-created his 27 active jobs by hand rather than importing them, on the grounds that active jobs carry context, what is done, what is left, what materials are on site, that "would not survive a CSV import cleanly."

Step 6: Load in dependency order

Records reference each other by ID, and those IDs change when they land in the new system. Load in the order that lets each step capture the IDs the next step needs:

Team members → customers → service addresses → equipment → price book → jobs and work orders → invoices and line items → payments → attachments → notes and activities.

Attachments go near the end deliberately. They are usually the largest volume, they are the most likely to hit an upload size limit, and a file that fails is far easier to retry when every record it attaches to already exists. Import in batches with validation between them, not one big upload. As the GoHighLevel PSA put it: "Import in batches. Test batch, validate, spot check the weird ones, then move the next. Never big-bang it."

Match on email and phone before creating anything, so that if you have to re-run a batch you update records instead of duplicating them.

Step 7: Test on twenty records, then reconcile field by field

Import twenty records. Not a sandbox, and not twenty easy ones. Choose deliberately:

  • The customer with three service addresses
  • The largest multi-line invoice you have
  • Your oldest record, from whenever the business started
  • A name with an apostrophe or hyphen (O'Brien, Smith-Jones)
  • A record where the billing address differs from the service address
  • A customer with equipment installed but no job in five years
  • A job with photos attached

Then open both systems side by side and compare field by field. Not "did it import." Did the third property arrive, did all four invoice lines arrive, did the total match, did the apostrophe survive the encoding, is the note dated 2019 or today.

A test import catches a broken field mapping while it costs you twenty records to fix instead of twenty thousand.

Tip

Do not delete and re-import if something lands wrong. Housecall Pro's documentation explicitly advises against it, warning it "can cause further complications," and says their support team can reverse the initial import instead. Most platforms have a similar reversal path. Ask before you start what it is.

Step 8: Cut over, validate, and freeze the old system

Pick a hard cutover date at a period end, in your shoulder season. For HVAC that means spring or autumn, never July or January. The go-live fortnight consumes your office staff, and it should land when dispatch is slowest.

On the day, make the old system read-only rather than cancelling it. Keep the subscription for a few months if attachments and old history still live there, which they probably do. Running both as live systems is the failure mode: two sources of truth means neither is complete and nobody trusts either. Read-only is not parallel running, it is an archive you can still query.

Then validate, on every object rather than just contacts:

  • Records in versus records out, per object, as a count
  • Sum of invoice totals in the new system versus the old, to the dollar
  • Count of service addresses, not just customers
  • Count of equipment records with a populated serial and install date
  • Spot check twenty records field by field, using the weird ones from Step 7
  • Confirm every open job, open estimate and unpaid invoice is present

If the invoice totals do not reconcile to the dollar, you have found the line item collapse. Fix it before go-live, not after.

The two weeks after go-live decide whether it worked

The cleanest import on earth is worthless if the team keeps working out of the old system. A field service operator commenting in r/CRMSoftware made the point that migration support "matters less than people think," because "most switches stall on the workflow gap after data is imported, not the import itself." He had seen shops move "with all their history moved over cleanly and still struggle for the first month because techs were used to doing things a certain way in the old system." His conclusion: "The bigger unlock is someone walking your actual team through their actual workflow once, not just moving the data."

That matches the broader evidence on why these projects disappoint, which we cover in why CRM implementations fail: the platform is rarely the problem. Budget the first two weeks after go-live as project time, with an owner, not as business as usual.

The bottom line

The eight steps are not the hard part, and every checklist on the internet already lists them. The hard part is that the failure mode of a CRM data migration is silence. Unmapped fields are discarded, line items collapse, timestamps reset and photos never move, and the import screen says success through all of it.

So do three things the generic checklists will not tell you. Inventory your objects and count them, because the gap between customers and service addresses and between invoices and line items is where the loss hides. Read the destination platform's own import documentation before you export anything, because it tells you plainly what it will throw away. And segment what you keep by equipment age rather than contact recency, because in this trade the ten-year-old record is the one about to become a job.

If you are still deciding whether to move at all, what switching a CRM actually costs is the more useful question to answer first. If you are moving off accounting software rather than a CRM, our QuickBooks migration checklist covers the reconciliation side in detail.

Frequently asked questions

What is on a CRM data migration checklist?
Eight steps: inventory every object you own (not just contacts), export completely from the old system, dedupe before mapping, map every field explicitly, decide what you are deliberately leaving behind, load in dependency order, test on twenty records and reconcile field by field, then cut over with the old system left read-only. The step most people skip is the inventory, because the objects that matter to a service business, properties and equipment and attachments, are not on any generic checklist.
What data does not transfer during a CRM migration?
More than vendors advertise. Job photos and file attachments usually do not export at all. Invoice line items typically live in a separate report from the invoice header. Note timestamps are commonly rewritten to the import date. Custom fields cannot always be created in the destination, and Housecall Pro's own import guide states that fields which are not mapped will be discarded. None of these throw an error.
Why did my invoice line items disappear after importing?
Because your export had one row per line item and the importer expects one row per invoice. Housecall Pro's data formatting guide states that if multiple rows are used for the same job or invoice it will not upload successfully, and that if you upload only the first occurrence, the additional line items will not import. A four-line invoice becomes a one-line invoice with the wrong total. Merge the rows into a single row per invoice before you upload.
How long does a CRM data migration take for a small contractor?
Two to four weeks of calendar time and roughly 20 to 40 hours of actual work for a few thousand customers. The export itself is fast. One contractor who moved nine years of Jobber data documented about two hours to export and one to three hours to review and clean, then re-created his active jobs by hand. The long pole is deciding what each field means and validating what landed.
Should I migrate my old inactive customers to the new CRM?
For a service business, usually yes, and this is where generic advice is wrong. Standard CRM guidance says archive anything untouched in 24 months because B2B contact data decays. But a homeowner whose furnace you installed in 2011 is not a dead lead, they are a replacement job coming due, since furnaces average 15 to 20 years and air conditioners 10 to 15. Segment by equipment age and install date, not by last contact date.
Do I need to dedupe before migrating or after?
Before, always. Duplicates carry forward as duplicate service addresses, duplicate job histories and duplicate invoices, and untangling them afterwards costs several times more than cleaning them at source. Industry estimates put typical duplicate rates at 10 to 30% of records. One contractor found 34 duplicate pairs in 847 clients built up over nine years, which is normal, not sloppy.
How do I export everything out of Jobber or Housecall Pro?
Neither gives you one complete file. In Jobber, exports live under Settings and Data Export, and clients, job history and invoice history come out as separate CSVs, with material and expense records only available through a custom report. In Housecall Pro, only Admins can export, and for jobs you must set the date range back to when you started and select all items in Table Columns first, or you export only the columns currently on screen.
What should I validate after a CRM migration?
Count records in versus records out for every object, not just contacts. Then spot check twenty records field by field against the original, choosing your five weirdest customers deliberately: the one with three properties, the one with a hyphenated name, the largest multi-line invoice, the oldest record, and the one with an apostrophe in the address. Confirm totals reconcile and that no customer lost a service address.
When is the best time to migrate a field service CRM?
In your shoulder season, and never in peak. For HVAC that means spring or autumn, not July or January. A migration consumes office staff attention for two to four weeks, and the go-live fortnight is when dispatch is slowest and mistakes are most expensive. Pick a cutover date at a period end so your financial reconciliation has a clean boundary.
Bespoke pipelines, automations, 360° customer records and real-time reporting, a CRM built around how your team actually works, connected to your entire stack.
Book a free CRM demo

Free tools

Find out what your site is costing you.

Enter your address and we check the real page. Scores are free and the itemised report lands in your inbox. No account, and we change nothing on your site.