Migrating to Salesforce: How to Preserve Relationships, History and Metadata

Salesforce

You can migrate 100% of your Accounts, 100% of your Contacts, and 100% of your Opportunities — and still fail the Salesforce migration. Because a successful Salesforce migration is not just about data. It is the convergence of four distinct problems: identifier management, relationship reconstruction, history preservation, and metadata migration (configurations, custom objects, Flows, rules, permissions). This article covers all four.

Problem 1 — Salesforce ID Management

When migrating from one Salesforce org to another (or from another CRM to Salesforce), records receive new Salesforce IDs in the target org. An Account with ID 001XXXXXXXXXXXX in the source org will have a completely different ID in the target org. If your external processes (ERP, scripts, API calls) referenced the old IDs, they break immediately after migration.

The solution is to create an ID mapping table between old and new IDs, and/or to store the original ID in a custom External ID field (e.g., Legacy_Salesforce_ID__c). This enables three things: tracing back to the original record in case of dispute, using the External ID as a post-migration reconciliation key, and reconstructing relationships between objects without knowing the new Salesforce IDs in advance.

Problem 2 — External ID and Upsert for Relationship Reconstruction

External ID is probably the most underused concept in Salesforce migrations. It transforms a brittle migration (that depends on exact import order and real-time IDs) into a robust, repeatable one.

Upsert with External ID principle: if a record with External_ID__c = '458792' already exists in Salesforce, Data Loader / Bulk API updates it. Otherwise, it creates it. Result: the migration is idempotent — re-running the import does not create duplicates.

But the most powerful use of External IDs is reconstructing parent-child relationships. When importing Contacts, you don't need to know the parent Account's Salesforce ID. Salesforce accepts a relationship-by-External-ID notation in the CSV file: Account.External_ID__c. Data Loader resolves the correspondence between the External ID and the real Account Salesforce ID automatically.

CSV Structure with External ID Reference

  • Column FirstName: contact first name
  • Column LastName: contact last name
  • Column Email: contact email
  • Column Account.External_ID__c: the External ID of the parent account (not its Salesforce ID)
  • Salesforce resolves the relationship automatically on import

Problem 3 — Import Order and Cascading Relationships

Object migration order is not optional. A Contact imported before its parent Account exists in the target org will either be rejected or created without an AccountId — making it an orphan. Orphan records are extremely difficult to clean up properly after migration.

  • 1. Users — Owners must exist before all other objects.
  • 2. Accounts — Accounts are the foundation of all commercial relationships.
  • 3. Contacts — linked to an Account via External ID.
  • 4. Leads — if your org separates Leads and Contacts.
  • 5. Opportunities — linked to an Account and optionally a Contact.
  • 6. Opportunity Products (OpportunityLineItem) — linked to an Opportunity.
  • 7. Cases — linked to an Account and/or Contact.
  • 8. Tasks and Events — always last. They can be attached to any object via WhoId (Contact / Lead) and WhatId (Account, Opportunity, Case…).

Problem 4 — Data ≠ Metadata

This is the most important — and most often ignored — distinction. Your data (Account, Contact, Opportunity records…) and your metadata (custom objects, fields, Flows, validation rules, Apex classes, Lightning pages, Permission Sets, Custom Metadata…) are two separate entities that require two distinct migration methods.

  • Data → Data Loader, Bulk API, ETL: everything that is a record in a table.
  • Metadata → Metadata API, Salesforce CLI, Change Sets, DevOps Center: everything that is org configuration.

Mental model for a complete Salesforce migration:

  • DATA: Accounts, Contacts, Opportunities, Cases, Leads, Activities, Custom Object records
  • METADATA: Custom Objects (definitions), Custom Fields, Flows, Validation Rules, Apex Classes, Apex Triggers, Lightning Pages, Permission Sets, Profiles, Record Types, Custom Metadata Types, Custom Labels, Named Credentials

Migrating Metadata with Salesforce CLI

Salesforce CLI is the reference tool for deploying metadata between orgs. The sf project retrieve start command retrieves metadata from the source org into a local versionable project. sf project deploy start deploys it to the target org.

  • sf project retrieve start --metadata ApexClass,Flow,ValidationRule,PermissionSet: retrieves specified metadata from the source org.
  • sf project deploy start --target-org target@company.com: deploys the project to the target org.
  • sf project deploy validate: validates the deployment without executing it (dry run — strongly recommended before any production deployment).

Change Sets (in Salesforce Setup) also move metadata between connected orgs, but without version control or CI/CD integration. DevOps Center is Salesforce's solution for teams that want to manage metadata in a Git pipeline with code review — it combines version control and Salesforce deployment in an integrated interface.

Complete Salesforce Migration Checklist

  • ☐ External ID field created on every migrated object (Account, Contact, Opportunity…)
  • ☐ Old ID → New ID mapping table prepared and archived
  • ☐ Metadata retrieved via sf project retrieve and versioned in Git
  • ☐ Metadata deployment validated in sandbox before production
  • ☐ Object import order respected (Users → Accounts → Contacts → Opportunities → Activities)
  • ☐ Pilot migration on sandbox with full dataset
  • ☐ Bulk API enabled on Data Loader for volumes > 50k
  • ☐ Apex triggers disabled or tested in sandbox (Bulk API behavior)
  • ☐ Post-migration reconciliation: orphan accounts, contacts without Account, Opportunities without Stage
  • ☐ External systems that referenced old Salesforce IDs verified and updated

To choose the right tool between Data Import Wizard, Data Loader and Bulk API based on your volume, see: Salesforce Migration — Data Import Wizard, Data Loader, Bulk API or ETL?

Contactez-nous

Notre équipe est disponible du lundi au vendredi de 9h à 18h pour répondre à vos questions.