Section 01
Why teams migrate to Salesforce Service Cloud
The four shapes a Service Cloud migration takes, and what makes the platform harder — or easier — than the category average.
Salesforce, Inc. was founded by former Oracle executive Marc Benioff in March 1999 and is headquartered in San Francisco, California 1. For fiscal year 2026 the company reported $41.5 billion in annual revenue, and Service Cloud sits inside a broader stack that includes Sales Cloud, Marketing Cloud, Revenue Cloud, Tableau, Slack and the Agentforce AI layer 1.
The typical Service Cloud customer is a mid-market or enterprise support organisation — 50 to 10,000+ agents — that needs case management, Knowledge, Entitlements + Milestones for SLA, Omni-Channel routing and an extensibility model through Apex, Flow and Validation Rules. Compared with Zendesk or Freshdesk, Service Cloud positions on configurability, the Sales Cloud + Service Cloud single record, and a deeper automation surface; compared with HubSpot Service Hub, it positions on Knowledge versioning, multi-channel routing maturity and the AppExchange.
The shapes of migration that actually land on Service Cloud fall into four patterns. First, competitor exits from Zendesk, Freshdesk, Help Scout, Intercom or Kayako when teams outgrow the source platform or need the single Account view shared with Sales Cloud. Second, legacy consolidation from Desk.com, Parature, on-prem ticketing systems or shared inboxes where the source schema is loose and the project is really a re-architecture.
Third, multi-org consolidation, where two or more Salesforce orgs from past M&A activity are merged into one — typically the hardest shape because both sides carry incompatible Record Types, Sharing Rules and Apex Triggers on the Case object. Fourth, Sales+Service unification, where a company already on Sales Cloud bolts Service Cloud onto the same org and migrates an external helpdesk in.
What makes migrating *to* Service Cloud harder than the category average is the automation that runs on insert. Validation Rules, Apex Triggers, Workflow Rules, Process Builder and Flow all evaluate every imported Case, CaseComment and EmailMessage, and a Trigger that auto-assigns owner blows the SOQL governor limit on the 51st row of a 200-row batch 22. Most migration teams disable automation during the load and re-enable it post-cutover with a regression test plan.
The second difficulty is Lightning Knowledge, which uses a versioned article model with its own publish workflow — articles are inserted as draft Knowledge__kav rows, published, then re-versioned. Standard bulk import patterns that work for Cases do not translate to Knowledge.
What makes it easier than the average is the External ID field type — a first-class upsert mechanism on every object, capped at 25 external IDs per object, that lets you match Cases, Contacts and Accounts by a value from the source system rather than by Salesforce's 18-character Record ID 3. Combined with the platform's job-based async loader, the platform rewards teams who plan their External IDs and load order before writing a single row.
Apex Triggers, Flows, Macros, Quick Actions, Entitlement Processes and Reports do not import — they are rebuilt from documentation. Teams that scope for that work up front finish on time; teams that assume parity do not.
The destination's automation layer fires on every imported Case, CaseComment and EmailMessage unless you actively quiet it — and re-enabling without regression is how teams break support on day five.
Section 02
The Salesforce Service Cloud data model you need to map into
Case, CaseComment, EmailMessage, Knowledge__kav, Entitlement, Record Types, and the External ID upsert mechanism — the destination schema decoded.
Service Cloud's data model is built on the same Salesforce platform as Sales Cloud — Standard Objects plus Custom Objects plus a relationship model of Lookups, Master-Detail and Junction Objects. The objects that distinguish Service Cloud are Case at the centre, CaseComment for ticket notes, EmailMessage for inbound and outbound email threading, Knowledge__kav for Lightning Knowledge articles, Entitlement and ServiceContract for SLA, and the routing objects PendingServiceRouting and AgentWork that power Omni-Channel.
Before you can map a field, you need to know which Standard Object the row belongs on, which Record Type applies inside that object, which required fields the Page Layout enforces, and which field you will use as the External ID for upsert. The table below summarises the objects you will touch in a Service Cloud migration.
| Object | Stores | Required on import | Tier |
|---|---|---|---|
| Account | Companies that submit cases (or households on Person Accounts) | Name (or Last Name on Person Accounts) | All editions |
| Contact | Individual requesters tied to an Account | Last Name, Account ID (unless Individual model) | All editions |
| Case | Support tickets — the central object | Status, Origin; Subject and ContactId on most layouts | All editions |
| CaseComment | Internal notes and public replies on a Case | ParentId (Case); IsPublished flag for public visibility | All editions |
| EmailMessage | Inbound and outbound email threads attached to a Case | ParentId (Case); FromAddress, ToAddress, Status, MessageDate | All editions |
| Knowledge__kav (Article Version) | Lightning Knowledge versioned articles | Title, UrlName; PublishStatus + Language drive lifecycle | Service Cloud editions with Knowledge enabled |
| Entitlement + ServiceContract | SLA contracts that drive Milestone timers on Cases | Name, AccountId, Type, StartDate, EndDate, BusinessHours | Enterprise+ (Service Cloud) |
| Macro / QuickText | Agent productivity templates and canned responses | Name, Instructions (Macro) / Message (QuickText) | All Service Cloud editions |
| LiveChatTranscript / MessagingSession | Chat / Messaging for In-App and Web session records | Status, StartTime; Contact/Case associations | Service Cloud Digital Engagement add-on |
| Custom Objects | Customer-defined record types (e.g. Asset extensions) | Defined per object; deployed schema before load | Enterprise+ for unlimited; lower editions capped |
Salesforce assigns an 18-character Record ID to every record on insert — you cannot set Record IDs on import. The migration pattern is to use External ID fields: up to 25 custom fields per object (auto-number, email, number or text) flagged as External ID and used as the upsert match key 3. Mark them *Unique* and case-sensitive on Case, Contact, Account, EmailMessage and Knowledge__kav to prevent silent duplicate merges.
Relationships come in three shapes. Lookup is a loose one-to-many — deleting the parent does not cascade. Master-Detail is tightly coupled, where the child inherits ownership and sharing from the master and is deleted with it. CaseComment, EmailMessage and CaseFeed all sit in Master-Detail-like behaviour under Case. Junction Object is a custom object with two Master-Detail relationships used to model many-to-many.
| Field type | Limits | Notes |
|---|---|---|
| Text / Text Area | Text 255 chars; Long Text Area 131,072 chars; Rich Text 131,072 | CaseComment.CommentBody capped at 4,000 chars 21 |
| Number / Currency / Percent | 18 digits total; up to 18 decimal places | Currency respects multi-currency org settings |
| Date / Date-Time | Date-Time stored in UTC; ISO-8601 in loader | Wrong format silently imports null on Data Import Wizard |
| Picklist (single / multi-select) | 1,000 active values; 2,000 inactive on single-select | Restrict picklist enforces strict ENUM — typo = rejection |
| Formula / Roll-Up Summary | Formula 3,900 char compiled; Roll-Up needs Master-Detail | Does not import — recomputed by platform after load |
| Lookup / Master-Detail | 40 lookups per object; 2 Master-Detail max per object | Master-Detail cascades delete; Lookup does not |
| External ID fields | Up to 25 per object | Primary upsert mechanism via loader and Data Import Wizard 3 |
| Custom fields per object | 500 on Enterprise; 800 on Unlimited | Hard cap; External Objects for overflow |
Record Types add a second axis on Case: one Case object can have multiple Record Types — for example Tier 1 Support, Tier 2 Support, Field Service, Billing — each with its own Page Layout, picklist value subset, support process, and required-fields list. A Case inserted with the wrong Record Type displays the wrong fields to the agent on day one, and the value RecordTypeId on every imported Case row decides which one it lands on.
Note that Field Service (formerly Field Service Lightning) is a separate Salesforce product layered on top of Service Cloud — it adds WorkOrder, ServiceAppointment and ResourceAbsence objects for dispatch and mobile work. If your source is a field-service platform, plan for Field Service licensing separately from Service Cloud. Big Objects (the platform's archive tier) default to 1 million records and are not used for active migration loads 11.
Section 03
Pre-migration prep — the work before you touch Service Cloud
What must be true on the source, the destination, and across the team before the first Case row is loaded.
The single best predictor of a clean Service Cloud migration is how much work you do on the source side before the first load job is submitted. Practitioners consistently report that field-mismatch breakage is not really about the fields — it is about the Validation Rules, Apex Triggers and Flows that fire on every imported Case and reject anything legacy data does not perfectly match 22.
Disable Validation Rules and Triggers during the load, then re-enable and run regression tests against a sample of migrated Cases — most teams skip the regression step and pay for it on day five.
Treat the source export as raw material shaped to Service Cloud's expected formats — email validated, phone normalised to international format, ticket status values converted to the destination's exact case-sensitive picklist values, dates rewritten to ISO-8601, agent emails resolved to Salesforce User IDs, ticket priority and channel re-mapped to Case.Priority and Case.Origin.
Source-side prep
- Audit and dedup the source helpdesk before export — Cloudingo, DemandTools and Plauti Duplicate Check catch fuzzy-match duplicates that Salesforce's built-in Matching Rule and Duplicate Rule would silently merge during Account or Contact insert 25.
- Stamp a stable External ID on every Case, Contact, Account, KB article and EmailMessage in the source export — the legacy primary key, a UUID or composite key — and create custom *External ID + Unique + case-sensitive* fields on each destination object to land them 3.
- Convert ticket status, priority and channel values to the exact destination picklist case — restricted picklists reject any typo, casing difference or trailing space with
bad value for restricted picklist field. Build a transform table per picklist per Record Type. - Resolve agents by exporting your destination User list (User.Id, Username, FederationIdentifier) and joining to the source agent column. Rows whose
OwnerIdcannot be resolved fall to the integration user, silently breaking owner-based assignment and Omni-Channel routing. - Decide what is in scope for historical email threads and attachments. EmailMessage rows can be inserted with backdated
MessageDate, but each Case with 50 message threads is a 50× multiplier on storage and daily load allocation.
Destination-side prep
- Create a Full Sandbox (or Partial Copy on lower editions) from Setup → Sandboxes — a Full Sandbox copies production data and metadata for end-to-end dry-runs and the refresh interval is 29 days 17.
- Provision agents and supervisors first through your identity provider (Okta or Microsoft Entra ID), assign Permission Sets and Profiles, and confirm the Service Cloud User permission is checked — Omni-Channel and Macros require it.
- Deploy every Case Record Type, Page Layout, Support Process, custom field and picklist value via a deployment tool before importing. Cases targeting a Record Type or Status value that does not yet exist on the destination are rejected.
- Disable Validation Rules, Workflow Rules, Process Builder Flows and Apex Triggers on Case, CaseComment, EmailMessage and Account during the load (or wrap them in a
Bypass__cCustom Setting skip flag). Re-enable post-cutover with a regression test plan 22. - Pre-build Entitlement Processes, Milestones, Service Contracts and Business Hours before importing Cases — a Case linked to a missing EntitlementId silently runs no SLA timer, breaking your downstream SLA dashboards.
People prep
Cutover works only when humans cooperate. Lock down a source-helpdesk freeze window — typically 24 to 72 hours — and communicate it to every channel that touches support. Train agents on Service Console daily workflows, Case management, Macros and Omni-Channel before go-live, not after. A clean Zendesk-to-Service-Cloud migration under 25,000 Cases often lands in six weeks; a multi-org consolidation runs eight to sixteen weeks 27.
Section 04
Import mechanisms: Data Import Wizard and Data Loader
Multiple mechanisms in, each with different limits, object support, and async behaviour. Picking the wrong one stalls mid-migration at scale.
Service Cloud exposes the same load paths as the rest of the Salesforce platform, and the right one depends on dataset size and object mix. Data Import Wizard covers small loads on a handful of objects but does not support Case, CaseComment or EmailMessage. Data Loader and Workbench cover the medium tier. Helpdesk-specific migration tools sit on top of all of them.
Data Import Wizard
The native UI tool lives at Setup → Data Import Wizard and supports a limited set of objects: Leads, Accounts, Contacts, Campaign Members, Solutions, Person Accounts and Custom Objects. The record limit is 50,000 per import, files must be CSV with UTF-8 encoding, and dates must use the org's locale format. For Service Cloud the Wizard is useful for prerequisite Account and Contact loads — Case is unsupported.
Data Loader and Workbench
Data Loader is the desktop app (Windows/macOS) that ships from Salesforce. It supports every Standard and Custom Object including Case, CaseComment and EmailMessage, runs Insert / Update / Upsert / Delete / Hard Delete / Export, and supports both interactive and CLI modes with scheduled jobs. Workbench is the browser equivalent — useful for one-off jobs without local install.
Large-volume async loading
For large-volume work, Data Loader can be configured to use the platform's async load mode, where Salesforce auto-chunks server-side — you do not size batches yourself. The same async path is what helpdesk-specific migration tools use under the hood for very large ticket loads.
Per-call limits compound on top: Apex Triggers firing on imported Cases consume governor limits — 100 SOQL queries and 150 DML statements per transaction — which is why bypassing Triggers during the load matters 27. The Salesforce Knowledge import path is separate: articles are inserted as draft Knowledge__kav rows, published via KbManagement.PublishingService.publishArticle, then re-versioned, and tools that work cleanly for Cases do not translate to Knowledge.
Third-party staging and helpdesk-specific tools
Dataloader.io (web Data Loader from MuleSoft), Skyvia, Talend, Informatica Cloud, Jitterbit and MuleSoft Anypoint all handle general Salesforce object loads. For Service Cloud specifically, helpdesk migration vendors like Help Desk Migration / Relokia and Import2 ship pre-built source connectors for Zendesk, Freshdesk, Help Scout, Intercom and Kayako that handle ticket → Case + thread → EmailMessage decomposition out of the box. Most enterprise migrations end up on MuleSoft or Informatica when source data is on-prem.
Accounts/Contacts under 50,000 → Data Import Wizard. Cases + CaseComments + EmailMessages, any volume → Data Loader. Knowledge articles → Salesforce Knowledge publish workflow (versioned insert pattern). Repeatable / scheduled / over 5 M records → Data Loader in async mode or a helpdesk-specific migration tool.
Section 05
Mapping your data into Salesforce Service Cloud
The longest section — because Case threading, Knowledge versioning, Macros rebuild and Entitlement-driven SLA is where every Service Cloud migration that fails actually breaks.
Mapping is where every Service Cloud migration earns its scars. The schema decisions you make in your mapping spreadsheet determine whether Case dashboards work on day two, whether Entitlement-driven SLA timers fire correctly on day five, and whether your agents trust the data on day thirty.
Work object by object, top to bottom of the load order: Users first (done in prep), then Accounts, then Contacts, then Cases, then CaseComments and EmailMessages against their parent Case External ID, then Knowledge articles via the publish workflow, then Macros and QuickText rebuilt from documentation. Load order matters because every child row needs a parent External ID that already exists.
Account and Contact
Common source → Service Cloud Account / Contact mapping
- organisation / company→Account.Name + Legacy_Account_ID__c (External ID)
Required; map by domain on dedup 25
- requester first/last name→Contact.FirstName / LastName
LastName required; resolve to existing Contact via Email match
- requester email→Contact.Email + Legacy_Contact_ID__c (External ID)
Drives Email-to-Case auto-match and Standard Contact Matching Rule 25
- organisation domain→Account.Website + custom Domain__c
Used by Email-to-Case lookup to auto-link new emails to Account
- user role (admin/end-user)→Profile or Permission Set on User
End-users on source map to Contacts; only agents become Users
Case — the ticket itself
Recreate every Case Support Process, Status value, Priority and Origin in Service Cloud before importing Cases. Each Status has a IsClosed Boolean that drives reporting and Entitlement Milestone completion. Cases that target a Status not present in the assigned Record Type's Support Process are rejected with bad value for restricted picklist field. Map source ticket statuses to destination Status values explicitly per Record Type.
Common source → Service Cloud Case mapping
- ticket_id→Legacy_Case_ID__c (External ID, Unique)
Primary upsert key — required for CaseComment / EmailMessage parent lookup
- subject / title→Subject
Required on most Page Layouts
- description / first message body→Description
Long Text Area; preserve plain-text fallback for HTML bodies
- status→Status
Restricted picklist per Support Process per Record Type
- priority→Priority
Restricted picklist; map source values to Low/Medium/High/Critical
- channel (email/chat/web/phone)→Origin
Restricted picklist; aligns with Email-to-Case and Web-to-Case generated values
- ticket type / record type→RecordTypeId
Drives Page Layout + Support Process — set explicitly
- assignee→OwnerId
Drives Omni-Channel routing + Role Hierarchy sharing
- requester→ContactId + AccountId
Resolve via Contact External ID lookup; AccountId derives from Contact
- created_at / updated_at→CreatedDate / LastModifiedDate (requires Create Audit Fields)
Otherwise stamped to load day — preserve in Legacy_Created_Date__c
Case history — CaseComment + EmailMessage threads
Service Cloud splits ticket conversation across two objects. CaseComment holds internal notes and short public replies — CommentBody is capped at 4,000 characters, IsPublished controls whether the customer sees the comment in the portal 21. EmailMessage holds full inbound and outbound email threads attached to a Case via ParentId, with Incoming Boolean, FromAddress, ToAddress, Subject, TextBody, HtmlBody, MessageDate and Status (Sent/Received/Draft).
The migration pattern for source threads is: classify each thread entry as either CaseComment (short internal note, agent annotation) or EmailMessage (actual email exchange), load them with ParentId referencing the Case External ID and MessageDate backdated, then attach files via the ContentVersion + ContentDocumentLink pattern below. EmailMessage thread ordering inside the Case Feed is driven by MessageDate — get it wrong and the customer-visible thread reads out of order.
Lightning Knowledge — versioned articles
Lightning Knowledge uses a versioned model: each article is a KnowledgeArticleVersion (Knowledge__kav) row with many versions in Draft, Online or Archived states. Only one Draft and one Online version can exist per article at a time, and parallel inserts are not allowed. The pattern is: insert version one as Draft, publish via KbManagement.PublishingService.publishArticle, then re-insert subsequent versions sequentially.
Map source KB title → Title, slug → UrlName, body → a Rich Text custom field, categories → Data Categories, and tags → keyword fields. Standard CSV import via Data Loader does not work for Knowledge — use the dedicated Knowledge publish workflow or a migration tool that wraps it. Multilingual KB articles add another axis: each Language is a separate Knowledge__kav chain with its own version history.
Macros, Quick Actions and Email Templates
Source canned responses, automation rules and email templates do not import — they are rebuilt. Service Cloud Macros run a sequence of Quick Actions on a Case and live in Macro + MacroInstruction records; Email Templates live in EmailTemplate. Source rules from Zendesk Triggers, Freshdesk Automations or Help Scout Workflows are rebuilt as Flows, Case Assignment Rules or Apex Triggers — the Freshdesk practitioner thread captures a 240-rule rebuild collapsed cleanly via Custom Metadata Types 39.
Entitlements, Milestones and SLA history
SLA in Service Cloud runs through Entitlement Management. The chain is: ServiceContract (customer agreement) → Entitlement (specific support coverage on an Account or Asset) → Entitlement Process (with one or more MilestoneType definitions for response time, escalation, resolution) → BusinessHours (working calendar). A Case links to an Entitlement via EntitlementId, and the Entitlement Process clocks Milestones automatically.
Source SLA definitions (Zendesk SLA policies, Freshdesk SLAs) are rebuilt as Entitlement Processes — they do not import. Historical SLA breach data is captured by populating custom datetime fields like Legacy_First_Response_At__c and Legacy_SLA_Breached__c from the source export so that historical SLA reports continue to work.
CSAT history
Salesforce delivers CSAT via Salesforce Feedback Management or via the Survey object, which stores Question + Response rows linked to a Case. Source CSAT scores (Zendesk Satisfaction, Freshdesk CSAT, Intercom Conversation Rating) do not import into the Survey object cleanly — the practical pattern is to land them in a Legacy_CSAT_Score__c numeric custom field plus a Legacy_CSAT_Comment__c text field on the Case, then build a new Survey for go-forward measurement.
Multi-channel — Email-to-Case, Voice, Chat, Messaging
Service Cloud's multi-channel surface is configured *after* the data load, but routing and threading rules need design during mapping. Email-to-Case creates Cases from inbound email and threads replies via a thread identifier in the subject or References header. Service Cloud Voice (with Amazon Connect or partner telephony) creates VoiceCall records routed through Omni-Channel. Chat uses LiveChatTranscript; Messaging for In-App and Web uses MessagingSession.
For migrated tickets that started on chat or social, the cleanest pattern is to land the transcript on the Case as a single CaseComment or EmailMessage row with Origin = Chat (or Social) — full LiveChatTranscript record reconstruction is rarely worth the effort. Omni-Channel routing configuration (queues, skills, presence statuses) is rebuilt against the migrated Case Record Types post-load.
Files and attachments
Service Cloud has two file frameworks: the legacy Attachment object (25 MB cap per file, no metadata customisation) and the modern Files framework built on ContentVersion + ContentDocument + ContentDocumentLink (10 GB cap per file in Lightning Experience, full metadata support). New migrations should land on Files. The migration pattern: insert a ContentVersion with the binary as VersionData (base64) and Title, capture the returned ContentDocumentId, then link to the parent Case via a ContentDocumentLink row.
For large attachment estates (TBs of ticket attachments), most teams keep originals in S3 or Azure Blob and store a deep link in a custom URL field on the Case — only the most-recent or most-referenced subset inlines. Inline image references inside EmailMessage HTML bodies need to be rewritten to point at the new ContentDocumentLink URLs or they break the rendered email view.
Audit trail, ownership and original timestamps
By default Salesforce stamps CreatedDate, CreatedById, LastModifiedDate and LastModifiedById on insert and they are read-only. To preserve original audit trail on Case, CaseComment and EmailMessage, file a support case requesting Create Audit Fields permission so those four fields can be set during insert. Toggle the permission off after cutover. Field History Tracking captures 20 fields per object by default; Field Audit Trail extends to 60 fields with 10-year retention.
Section 06
The pitfalls that derail Service Cloud migrations
Specific failure modes — ranked by impact, each tied to the exact Service Cloud mechanism that breaks.
High impact
Apex Triggers and Validation Rules firing on every imported Case
Service Cloud evaluates Validation Rules, Apex Triggers, Workflow Rules and Flows on every Case insert. An auto-assignment Trigger that queries the parent Account for every Case blows the 100-SOQL governor limit on the 51st row of a 200-row batch; a Validation Rule requiring populated industry rejects everything historically null 22. The mitigation is to disable Validation Rules and toggle Triggers behind a Bypass__c Custom Setting during the load, then re-enable with a regression test plan against sample migrated Cases. 22
High impact
Restricted picklist rejection on Case Status / Origin / Priority
Case Status, Origin and Priority are restricted picklists, and any typo, casing difference or trailing space returns bad value for restricted picklist field in Data Loader and partial-success on Data Import Wizard. The trap is that the same Status value may pass for one Record Type's Support Process and fail for another because Support Processes subset the active values. Build a transform table per Record Type, validate against the destination's exact list, and run a 100-row dry-run before scaling.
High impact
CreatedDate locked unless Create Audit Fields is enabled
By default CreatedDate, CreatedById, LastModifiedDate and LastModifiedById on Case, CaseComment and EmailMessage are stamped to load day and are read-only. Teams discover this on day two when Case-age and first-response reports return everything stamped to import day. The mitigation is to file a support case requesting the org-wide Create Audit Fields permission *before* the migration starts — Salesforce typically enables it for a defined window. Forgetting to disable it after cutover lets any privileged user rewrite history.
High impact
Knowledge versioned insert pattern breaks standard import tooling
Lightning Knowledge does not behave like other Standard Objects. Only one Draft and one Online version of an article can exist at a time, and parallel inserts of multiple versions return an error. Data Loader tooling that works cleanly for Cases fails on Knowledge__kav. The mitigation is to use the dedicated Salesforce Knowledge publish workflow with sequential publishArticle + re-version calls, or a migration tool that wraps it. Plan KB migration as a separate workstream from Cases.
High impact
EmailMessage thread order driven by MessageDate, not insert order
EmailMessage rows attached to a Case display in the Case Feed ordered by MessageDate, not by insert order. If your source export does not preserve the original send timestamp per message, the customer-visible thread reads out of order on day one and agents lose context. Worse, EmailMessage attachment references (inline images, Content-ID links) embedded in HTML bodies need URL rewriting to point at the new ContentDocumentLink — otherwise the rendered email view shows broken images on every migrated thread.
Medium impact
Entitlement Milestone clocks do not retro-fire on backdated Cases
When you backdate a Case via Create Audit Fields, the Entitlement Process attached on insert starts its Milestone clocks at the moment of insert, not at the original CreatedDate. The result: every migrated Case shows zero elapsed time on first-response and resolution Milestones, breaking historical SLA reporting. The mitigation is to populate Legacy_First_Response_At__c, Legacy_Resolved_At__c and Legacy_SLA_Breached__c custom datetime fields from the source, rebuild SLA dashboards against those, and let live Entitlements clock new Cases forward only.
Medium impact
Silent partial-success when Triggers consume governor limits
When Apex Triggers run on imported Case batches, each chunk shares 100 SOQL queries and 150 DML statements per transaction. A well-meaning auto-assignment Trigger that queries the Account for every Case blows the SOQL limit on the 51st row of a 200-row chunk, and the loader returns a partial-success response — most rows insert, some fail, no obvious blocking error 22. Monitor logs for partial successes (not just failures) and re-import rejected rows by Legacy_Case_ID__c after bulkifying the Trigger. 22
Low impact
EU data residency requires Hyperforce region selection at org provisioning
Salesforce's Hyperforce architecture lets EU customers pin data to specific EU regions for GDPR residency compliance, but the region is set at org creation and changing it later requires a Salesforce-run migration project, not a customer setting toggle. If your migration target is an org already provisioned in the wrong region, schedule the region migration *before* the helpdesk data migration, or you will move millions of Cases and EmailMessages twice. Hyperforce regions also have their own deployment pipeline considerations for sandbox refreshes.
Section 07
Validation and cutover
What to verify after the loader finishes Cases, in what order — and how to fail safely when Triggers ate a chunk.
Validation is the bridge between the loader returning success and agents being allowed in. Service Cloud data-migration practitioners recommend a three-stage validation: a test load of 10 percent of Cases in a Full Sandbox with department-rep spot-checks, the full production load with real-time monitoring of partial-success counts, and a 30-day post-migration data-quality audit using DemandTools or Cloudingo to surface the merges that Matching Rules did silently34.
Build a reconciliation queries spreadsheet that compares source and Service Cloud on each of the counts below. Anything outside a 0.5 percent variance gets investigated before agent login access opens.
- Total Cases inserted vs source helpdesk —
SELECT COUNT() FROM Case WHERE Legacy_Case_ID__c != nullensures you only count migrated rows. - Total Cases per Status per Record Type plus Cases per Priority and per Origin — a non-trivial variance signals a picklist-mapping error or a Trigger that re-stamped Status on insert.
- Total CaseComments per Case spot-check — pick 30 high-volume Cases and verify the public-vs-internal mix matches source, catching CaseComment.IsPublished mis-flagging.
- Total EmailMessages per Case + MessageDate ordering — confirm thread order reads correctly in the Case Feed on a sample of 20 long-thread Cases.
- Knowledge articles per Data Category + PublishStatus vs source KB — confirm version history depth and Published state matches.
- OwnerId distribution —
SELECT OwnerId, COUNT(Id) FROM Case GROUP BY OwnerIdand confirm no Case landed on the integration user that should not have. - Entitlement linkage —
SELECT COUNT() FROM Case WHERE EntitlementId = null AND AccountId IN (SELECT AccountId FROM Entitlement)should be near zero on Cases that should have SLA coverage. - External ID uniqueness —
SELECT Legacy_Case_ID__c, COUNT(Id) FROM Case GROUP BY Legacy_Case_ID__c HAVING COUNT(Id) > 1should return zero rows.
On top of reconciliation, run a manual spot-check: pick 30 random Cases across Record Types and verify each field against the source UI. Pick five high-value Cases and trace the full graph — Account, Contact, CaseComments, EmailMessages, attachments, Entitlement. If three or more of the 30 show non-trivial discrepancy, halt the load, fix the root cause (almost always a Trigger or Validation Rule), and re-import affected rows by Legacy_Case_ID__c via Data Loader upsert.
Service Cloud's native Recycle Bin holds deleted records for 15 days and can be used for small-scale undo from the UI 34. Undoing an Import under Setup is available only for Data Import Wizard imports launched within the last 24 hours and only deletes records the import created 34. For Data Loader there is no built-in undo — you delete by Legacy_Import_Batch_ID__c custom field and re-import from the cleaned source.
The rollback strategy practitioners actually use: full org backup via Salesforce Data Export (Setup → Data Export) or a third-party backup tool like Odaseva or OwnBackup *before* the migration starts, plus stamping every imported row with an Import_Batch_ID__c custom text field, so catastrophe means a SOQL delete by batch ID followed by re-import from clean source 34.
Cutover sequencing: (1) source helpdesk goes read-only; (2) final delta export captures every Case, CaseComment, EmailMessage and KB version changed during sandbox-test; (3) delta upsert via Data Loader using Legacy_ID External IDs; (4) reconciliation queries run; (5) Email-to-Case routing, Omni-Channel queues, Entitlements and Validation Rules re-enabled with regression pass; (6) agents get login and a 48-hour hyper-care window; (7) source decommission 30 to 90 days out, never same day.
Section 08
Migration partners and tools
Summit and Crest Salesforce Partners, ETL vendors, helpdesk migration specialists — what each is good for and how to choose.
The Salesforce Partner Program tiers consulting firms by Navigator certifications, Customer Satisfaction (CSAT) scores and Salesforce-credentialed engineer count. The named tiers were historically Global Strategic, Summit, Crest and Ridge; Salesforce announced a 2026 consolidation to two tiers (Select and Summit) rolling out through FY27. 70 percent of Salesforce implementations are delivered through Partners rather than direct, and most non-trivial Service Cloud migrations end up with one.
Deloitte Digital, Accenture, Capgemini, IBM and Slalom dominate the global Strategic tier for enterprise multi-cloud rollouts. For mid-market Service Cloud migration projects specifically, Summit-tier partners with explicit helpdesk-exit practices (Service Cloud from Zendesk, from Freshdesk, from Help Scout, from Intercom) tend to ship cleaner than generalist implementation shops. Salesforce also runs Professional Services in-house — typically the most expensive option but the one with deepest product-team access.
On the helpdesk-migration tooling side, Help Desk Migration / Relokia and Import2 are the two most-named specialist vendors, both shipping pre-built connectors for Zendesk, Freshdesk, Help Scout, Intercom, Kayako and Kustomer that handle ticket-to-Case + thread-to-EmailMessage decomposition. For general ETL, MuleSoft is the Salesforce-owned default for on-prem integration, Informatica Cloud is common in regulated industries, and Fivetran, Airbyte, Stitch and Workato cover the warehouse-first stack. Cloudingo and DemandTools handle Account + Contact dedup.
Managed-migration cost ranges vary widely. A clean Zendesk- or Freshdesk-to-Service-Cloud move under 25,000 Cases, standard Email-to-Case and one Record Type, typically lands in the $20,000–$60,000 range. A multi-org consolidation with Case history, Knowledge re-versioning, Macro and Entitlement rebuild, Omni-Channel skill design and Apex/Flow rebuild runs $60,000–$500,000+, driven by Case count, channel count and integration scope.
For teams that want to outsource the migration end-to-end, FlitStack specialises in Salesforce Service Cloud migrations and handles External ID schema design, Case + CaseComment + EmailMessage thread decomposition, Lightning Knowledge versioned-article load, Macro and Entitlement rebuild scoping, Trigger bypass setup, and the reconciliation work in Sections 5 and 7. Pricing is fixed-fee, based on Case count and source platform, with separate line items for Knowledge depth, Apex/Flow rebuild and historical SLA scope.
This is one of several legitimate paths — the right choice for any given team depends on whether they want a Summit Partner with a wider services footprint, Salesforce Professional Services with deepest product-team access, a helpdesk-migration specialist focused on the load itself, or an ETL-first approach via MuleSoft. Explore FlitStack →
Section 09
Frequently asked questions
The questions every Service Cloud migration team works through before they sign the scope.
References
Sources
- 1 Salesforce — Wikipedia
- 3 Custom Field Attributes — Salesforce Help (External ID)
- 11 Increase Limit of Salesforce Big Object Storage Allocation — Salesforce Help
- 17 Sandboxes — Staging Environments for Customizing and Testing
- 21 Case Comment STRING_TOO_LONG — Salesforce Stack Exchange
- 22 Salesforce Data Migration: 7 Challenges and How to Solve Them — DEV
- 25 Salesforce Duplicate Management — Salesforce Stack Exchange
- 27 Async Load Limits — Salesforce Help
- 34 Undoing an Import — Salesforce Help
- 39 Migrating from FreshDesk to Service Cloud — r/salesforce
Need help running this migration?
FlitStack AI runs Salesforce Service Cloud migrations end-to-end.
Fixed-fee pricing, a hands-on migration engineer, full field mapping and validation. The work described in this guide — done for you.