How to Migrate from SolarWinds Service Desk to ServiceNow
A step-by-step guide to migrating SolarWinds Service Desk to ServiceNow, covering API limits, CMDB mapping, and real-world edge cases.
Planning a migration?
Get a free 30-min call with our engineers. We'll review your setup and map out a custom migration plan — no obligation.
Schedule a free call- 1,500+ migrations completed
- Zero downtime guaranteed
- Transparent, fixed pricing
- Project success responsibility
- Post-migration support included
How to Migrate from SolarWinds Service Desk to ServiceNow
A SolarWinds Service Desk to ServiceNow migration moves your ITSM data — incidents, problems, changes, CMDB configuration items, assets, users, groups, knowledge articles, and attachments — from the Samanage-based cloud platform into ServiceNow's table-driven architecture. This is a data model conversion, not a ticket dump. The safe pattern is API extraction from SolarWinds, staged loading into ServiceNow Import Sets, relationship rebuilds, then a delta cutover.
Quick Answer: This migration is medium-to-high complexity. Realistic timelines range from 3 weeks for small environments (under 50,000 records) to 8+ weeks for enterprises with deep CMDB hierarchies and 500,000+ records. The single biggest risk is broken CI-to-incident relationships caused by loading records in the wrong order. Automations, SLA policies, workflow rules, and triggers cannot be migrated and must be rebuilt manually in ServiceNow. Teams with fewer than 100,000 total records and no multi-level CMDB dependencies can often handle this in-house with a dedicated engineer. Environments with complex CMDB trees, custom CI types, and compliance requirements should use a managed migration service.
Why Teams Migrate from SolarWinds Service Desk to ServiceNow
Enterprise IT teams outgrow SolarWinds Service Desk when they need deeper workflow automation, granular role-based access, or a platform that scales across multiple business units. For an in-depth architecture and cost comparison, see our ServiceNow vs SolarWinds Service Desk analysis.
The most common drivers:
- Workflow engine limits. SolarWinds Service Desk automation rules support basic triggers and field updates. ServiceNow Flow Designer (available in ITSM Pro and higher) and Business Rules offer scripted, multi-step orchestrations across any table, including cross-table subflows and approval chains.
- CMDB maturity. SolarWinds Service Desk supports a parent/child CI hierarchy with dependency mapping, but ServiceNow's CMDB uses a class-based inheritance model (
cmdb_ciand 700+ subclasses) with relationship types, discovery integrations, the Common Service Data Model (CSDM), and the CMDB Health Dashboard for ongoing quality scoring. - Multi-department scale. SolarWinds supports Enterprise Service Management with renamed modules per service provider. ServiceNow's domain separation and scoped applications handle true multi-entity isolation.
- Licensing alignment. Confirm whether your target ServiceNow instance is ITSM Standard or ITSM Pro/Enterprise. Features like Flow Designer, the Identification and Reconciliation Engine (IRE), and CSDM alignment require ITSM Pro or higher. If your migration plan depends on these capabilities, verify licensing before committing to a timeline.
What Makes This Migration Non-Trivial
Four architectural differences create the most friction:
Request model split. SolarWinds Service Desk stores incidents and service requests in the same object, differentiated by a classification field. ServiceNow splits these across the incident table and sc_req_item (RITM) table with separate workflows. Service requests in ServiceNow also require parent sc_request records and often depend on catalog items, variables, and downstream tasks. (documentation.solarwinds.com)
CMDB structure. SolarWinds uses a parent/child CI hierarchy with inherited fields per CI type. ServiceNow's CMDB uses class inheritance from cmdb_ci with relationship records stored in cmdb_rel_ci. Direct parent/child links do not map 1:1. Each SolarWinds CI type must be mapped to a specific ServiceNow CI class before import, and CI relationships must be loaded after both endpoint CIs exist. (documentation.solarwinds.com)
Comment and journal storage. SolarWinds stores public and private comments as nested objects on the incident record. ServiceNow stores journal entries in the sys_journal_field table with element values of comments (public) or work_notes (internal). Timestamp preservation requires overriding sys_created_on with an import user that has elevated privileges.
State and workflow differences. SolarWinds lets you rename system states and add custom states for incidents, service requests, changes, and assets. ServiceNow uses numeric state codes (1=New, 2=In Progress, 3=On Hold, 6=Resolved, 7=Closed). Blindly mapping custom SolarWinds states without a reporting review will break dashboards and SLA logic on day one. (documentation.solarwinds.com)
SolarWinds Service Desk to ServiceNow Object Mapping
Map every SolarWinds object to its exact ServiceNow target before writing extraction logic. Do not assume standard CRM objects apply. For scope control on what to migrate and what to leave behind, see our help desk data migration playbook.
| SolarWinds Service Desk Object | ServiceNow Target Table | Notes / Caveats |
|---|---|---|
| Incidents | incident |
Classification field determines if record is incident vs. service request. State fields require enum-to-integer translation. |
| Service Requests | sc_req_item (RITM) |
Requires creating parent sc_request records first. Catalog context must exist before loading request history. |
| Catalog Items | sc_cat_item |
Forms, variables, approvals, and fulfillment logic usually need a full rebuild, not field copy. |
| Problems | problem |
SolarWinds problem tasks map to problem_task. Do not land primary problem records on problem_task. |
| Changes | change_request |
Differentiate between Standard, Normal, and Emergency types. CAB workflow states need manual remapping. |
| Releases | rm_release |
Not all ServiceNow instances have release management activated. Many teams archive release history or map it to change history. |
| Configuration Items (CIs) | cmdb_ci subclasses |
Map each CI type to the correct ServiceNow CI class (e.g., cmdb_ci_server). Do not dump everything into generic cmdb_ci. |
| CI Relationships | cmdb_rel_ci |
Load only after both endpoint CIs exist. Map SolarWinds dependency links to ServiceNow relationship types (e.g., "Runs on", "Depends on"). |
| Assets / Hardware | alm_asset + alm_hardware |
SolarWinds merges asset and CI concepts that ServiceNow separates. Decide whether each source asset becomes an asset, a CI, or both. |
| Users | sys_user |
Must be migrated first to preserve record ownership. Match on email address as the unique key. |
| Groups | sys_user_group |
Group membership stored separately in sys_user_grmember. |
| Departments | cmn_department |
Flat in SolarWinds, can be hierarchical in ServiceNow. Used for cost centers and organizational hierarchy. |
| Sites | cmn_location |
SolarWinds site = ServiceNow location. Site-driven routing usually becomes location plus assignment rules. |
| Solutions (Knowledge Base) | kb_knowledge |
Must create kb_knowledge_base and kb_category records first. Categories and publishing flow may differ. |
| Categories / Subcategories | sys_choice entries |
Become picklist values on the target table, not standalone records. |
| Comments (public) | sys_journal_field (element=comments) |
One journal entry per comment, linked by element_id. |
| Comments (private/internal) | sys_journal_field (element=work_notes) |
Timestamp preservation requires sys_created_on override with elevated privileges. |
| Attachments | sys_attachment + sys_attachment_doc |
ServiceNow stores attachments in 4KB chunks. Must be downloaded from SolarWinds and uploaded via the Attachment API. |
| Tasks | Case by case | As of June 30, 2026, SolarWinds Task Management v2 has no API support. Confirm an alternate extraction path if task records are in scope. (documentation.solarwinds.com) |
| Contracts | ast_contract |
Field mapping differs significantly. |
| Risks | No direct equivalent | Migrate as records in a custom table or as risk assessment entries. |
Field-Level Mapping Considerations
Picklist and enum handling. SolarWinds uses string-based picklist values (Priority: "Critical", "High", "Medium", "Low"). ServiceNow incident priority uses numeric codes (1=Critical, 2=High, 3=Medium, 4=Low). Your transform map must convert strings to integers.
State mapping. SolarWinds incident states (New, Assigned, Awaiting Input, In Progress, On Hold, Resolved, Closed) need explicit mapping to ServiceNow's numeric state field (1=New, 2=In Progress, 3=On Hold, 6=Resolved, 7=Closed). Custom states in SolarWinds require creating matching sys_choice entries in ServiceNow before loading data.
Custom fields. SolarWinds supports unlimited custom fields per object. In ServiceNow, you must create matching fields on the target table using the correct field type (string, integer, reference, date/time). Reference fields require the referenced record to exist before the referring record is loaded. SolarWinds custom fields often export as dynamic key-value pairs and must be mapped to predefined dictionary columns or variables in ServiceNow.
Timestamps. To preserve original created and updated timestamps, set the glide.sys.date_format property and use the sys_created_on and sys_updated_on fields with an import user that has the import_set_loader or admin role. Normalize all timestamps to UTC in ServiceNow's expected format (YYYY-MM-DD HH:MM:SS).
Import Set string casting. Cast everything to strings before it hits a ServiceNow Import Set. ServiceNow documents string-only request body values for Import Set POST methods. (servicenow.com)
Coalesce field configuration. Coalescing is the mechanism that prevents duplicate records during import. In your Transform Map, mark one or more fields as "Coalesce" — typically correlation_id (mapped to the legacy SolarWinds ID) or email for users. When a transform runs, ServiceNow checks whether a record with that coalesce value already exists. If it does, the transform updates the existing record instead of inserting a duplicate. This is critical for delta syncs, re-runs after error correction, and user deduplication. Without coalesce fields configured, every re-run of your migration creates duplicate records. Set coalesce on sys_user.email, incident.correlation_id, and cmdb_ci.correlation_id at minimum.
What Data Cannot Be Migrated
The following SolarWinds Service Desk elements have no automated migration path:
- Automation rules, triggers, and workflow logic — rebuild in ServiceNow using Business Rules, Flow Designer, or Scheduled Jobs
- SLA policies and business hours — recreate manually in ServiceNow SLA Definitions
- Report configurations and dashboards — cannot be exported; must be rebuilt
- Email templates and notification rules — manual setup in ServiceNow notifications
- Portal branding and catalog workflows — complete reconstruction in ServiceNow Service Portal
- Approval logic and routing behavior — must be redesigned, not field-copied
Even migration vendors that automate ticket and article transfer treat workflow and SLA behavior as follow-up configuration work, not as a direct historical import. (help-desk-migration.com)
Migration Approaches Compared
Four viable approaches exist. The right choice depends on record volume, engineering bandwidth, and tolerance for risk.
Native CSV Export + ServiceNow Import Sets
Export data from SolarWinds Service Desk using the Actions > Export > CSV option on each index page. Upload each CSV into a ServiceNow Import Set staging table and use Transform Maps to load records into target tables. (documentation.solarwinds.com)
When to use it: Small environments with fewer than 10,000 records, no CMDB dependencies, and no attachment requirements.
Limitations: CSV exports do not include attachments, inline images, or comment threading. Cells exceeding 32,767 characters cause Excel formatting corruption. No delta sync capability. SolarWinds CSV exports can take hours and the download link is only valid for 14 days.
API-Based Custom ETL
Build a custom extraction pipeline using the SolarWinds Service Desk REST API (api.samanage.com) and load data into ServiceNow via the Import Set API.
When to use it: Mid-size to large environments (10,000–500,000 records) with engineering resources and the need to preserve attachments, comments, and CMDB relationships.
Limitations: High engineering cost. Handling pagination, error retries, rate limits, and relationship rebuilds takes weeks of developer time. Plan for 150–250 hours of engineering effort.
iPaaS / Integration Platform (Zapier, Make, Workato)
Use a no-code connector to sync records between SolarWinds Service Desk and ServiceNow in near-real-time. Zapier lists SolarWinds Service Desk (as Samanage) and ServiceNow as supported platforms with actions like creating or updating records.
When to use it: Ongoing sync scenarios where both platforms run in parallel, or for routing new incidents during a transition period.
Limitations: Not designed for bulk historical migration. Zapier connectors support basic incident creation and updates but not CMDB, problems, or changes. No attachment support in most connectors. Poor fit for replaying years of ITSM history.
Managed Migration Service
A dedicated migration team builds custom extraction scripts, handles field mapping, manages API rate limits, preserves relationships, and runs validation.
When to use it: Enterprise environments with 100,000+ records, multi-level CMDB hierarchies, compliance requirements, or zero-downtime constraints.
Limitations: Requires budget and vendor selection.
| Criteria | CSV Export | API-Based ETL | iPaaS | Managed Service |
|---|---|---|---|---|
| Best for | < 10K records | 10K–500K records | Ongoing sync | 100K+ records |
| Attachments | No | Yes | Limited | Yes |
| CMDB relationships | No | Yes (manual) | No | Yes |
| Comments / history | Partial | Yes | Limited | Yes |
| Engineering effort | Low | High | Low | None |
| Risk of broken refs | High | Medium | High | Low |
API Limits That Shape the Migration Architecture
Understanding both platforms' extraction and load constraints is the only way to prevent failed data loads and plan realistic throughput. For a broader view of ServiceNow ingestion challenges, see 10 ServiceNow Data Migration Challenges.
SolarWinds Service Desk API
- Base URL:
https://api.samanage.com - Authentication: JWT token generated from Setup > Users & Groups, passed via
X-Samanage-Authorization: Bearer <token>header. (documentation.solarwinds.com) - Pagination: Offset-based with
pageandper_pageparameters. Maximum page size is 200 records. Use theX-Total-Countresponse header to get total record counts per endpoint before beginning extraction — this lets you estimate extraction time and validate completeness. - Rate limits: SolarWinds enforces rate limiting but does not publicly document specific numeric thresholds. Exceeding limits returns HTTP 429. Plan for conservative throughput of 1 request per second and implement exponential backoff with jitter.
- API access: Gated behind Advanced and Premier plan tiers. Confirm your license level before starting.
- Key endpoints:
/incidents.json,/problems.json,/changes.json,/releases.json,/hardwares.json,/configuration_items.json,/users.json,/groups.json,/departments.json,/sites.json,/solutions.json - Volume estimation: Before starting extraction, call each endpoint with
per_page=1and read theX-Total-Countheader. Sum counts across all endpoints to get total record volume and estimate extraction time.
If your SolarWinds instance uses Task Management v2, those task records currently have no API support as of the June 30, 2026 release. Confirm an alternate extraction path before committing to the migration schedule. (documentation.solarwinds.com)
ServiceNow API
- Table API:
GET/POST/PUT/DELETEon/api/now/table/{tableName}. Query results default to a maximum of 10,000 records per query, controlled by theglide.db.max_view_recordssystem property. Table API POST inserts only one record at a time — do not use it as your bulk loader. (servicenow.com) - Import Set API: The recommended path for bulk loads. The
insertMultiplemethod accepts up to 200 records per request. Sending larger chunks risks transaction timeouts. IfinsertMultipleis not available via REST on your instance, you may need to enable it via thesys_rest_insert_multipletable or use the SOAPinsertMultiplemethod. (servicenow.com) - Rate limits: Configurable per instance via
sys_rate_limit_rules. There is no universal default. Exceeding limits returns HTTP 429 withRetry-AfterandX-RateLimit-*headers. Do not hard-code an assumed rate limit — check your instance configuration. (servicenow.com) - REST payload size: Controlled by
glide.pf.rest.response_payload_max_size. If your attachment payloads exceed the configured limit, you must chunk the binary data. - Attachment uploads: Use the Attachment API (
/api/now/attachment/file) — one file per request. Maximum single file upload of 25 MB via REST. (servicenow.com) - Required roles for migration user: The integration user account needs
import_transformer,import_set_loader, andadminroles to override system fields likesys_created_onandsys_created_by. For attachment uploads, add theattachment_adminrole. Restrict these elevated roles to the migration service account and revoke them after go-live. - Scoped vs. global application context: Decide before building transform maps whether your migration artifacts (import set tables, transform maps, custom fields) live in a scoped application or the global scope. Scoped applications provide cleaner lifecycle management and easier cleanup post-migration, but transform maps in scoped apps cannot access global business rules or script includes without explicit cross-scope access. For most migrations, the global scope is simpler. If your ServiceNow governance requires scoped apps, test transform behavior in a sub-production instance first.
- MID Server considerations: For attachment-heavy migrations (50,000+ files), consider routing API calls through a ServiceNow MID Server deployed in your network. This avoids browser-based upload timeouts and provides better throughput for large binary transfers. A MID Server is not required for record-only migrations.
Throughput Math
With SolarWinds capped at 200 records per page and a conservative 1-request-per-second extraction rate, the theoretical maximum is 720,000 records per hour on the source side. In practice, expect 400,000–500,000 records per hour after accounting for HTTP latency, 429 retries, and JSON parsing overhead. The real bottleneck is the ServiceNow load side.
Using Import Set insertMultiple at 200 records per request with a 5-second cycle (including transform processing), you can stage roughly 144,000 records per hour. With a 10-second cycle, that drops to 72,000. Transform maps, journal replay, and attachment uploads pull the real throughput lower.
Attachments are the slowest stream. The Attachment API uploads one file per request, so a migration with 40,000 tickets and 60,000 files behaves like a file-transfer project long after the ticket rows are loaded.
For environments with 500,000+ records, plan for 30–50 hours of raw data transfer time on the ServiceNow side, not counting transform processing.
Performance impact on production instances: Schedule bulk Import Set loads during off-peak hours (weekends or after business hours). Large transform map runs consume database and application server resources, which can degrade performance for concurrent users. Monitor the sys_import_set_run table for long-running transforms. If you have a dedicated migration window, consider temporarily increasing the instance's transaction quota or running loads against a sub-production instance first, then promoting via Update Sets.
Step-by-Step Migration Process
Data must be loaded into ServiceNow in a strict dependency order. If you load an incident before the assigned user exists, the reference field will be blank. There is no way to retroactively populate reference fields via Import Sets without re-running the transform.
Step 1: Extract from SolarWinds Service Desk
Use the REST API to paginate through each object type. Store raw JSON responses locally or in a staging database. Before extracting, call each endpoint with per_page=1 to capture the X-Total-Count header — this gives you total record counts for progress tracking and post-migration validation.
import requests
import time
SWSD_TOKEN = "your-jwt-token"
BASE_URL = "https://api.samanage.com"
HEADERS = {
"X-Samanage-Authorization": f"Bearer {SWSD_TOKEN}",
"Accept": "application/vnd.samanage.v2.1+json"
}
def get_total_count(endpoint):
resp = requests.get(
f"{BASE_URL}/{endpoint}.json?per_page=1&page=1",
headers=HEADERS
)
return int(resp.headers.get("X-Total-Count", 0))
def extract_all(endpoint):
page = 1
all_records = []
total = get_total_count(endpoint)
print(f"{endpoint}: {total} total records")
while True:
resp = requests.get(
f"{BASE_URL}/{endpoint}.json?per_page=200&page={page}",
headers=HEADERS
)
if resp.status_code == 429:
retry_after = int(resp.headers.get("Retry-After", 60))
time.sleep(retry_after)
continue
if resp.status_code != 200:
break
data = resp.json()
if not data:
break
all_records.extend(data)
page += 1
time.sleep(0.5) # conservative rate limiting
return all_records
incidents = extract_all("incidents")
users = extract_all("users")Step 2: Clean and Transform
- Deduplicate users by email address (watch for variations like john.doe@company.com vs. jdoe@company.com)
- Map SolarWinds picklist strings to ServiceNow integer codes (state, priority, impact, urgency)
- Split incidents from service requests based on the classification field
- Normalize timestamps to UTC in ServiceNow's expected format (
YYYY-MM-DD HH:MM:SS) - Build a lookup table mapping SolarWinds record IDs to ServiceNow
sys_idvalues (populated during load) - Assign orphaned records (referencing deleted users or groups) to a "Migration Archive" user
- Normalize inconsistent category values caused by renamed categories mid-lifecycle
- Cast all field values to strings before loading into Import Sets
Step 3: Prepare ServiceNow Target Schema
Create external ID fields, staging tables (Import Sets), choice list entries for custom picklists, catalog structure, and Transform Maps before loading any data. Freeze SolarWinds configuration changes while you finalize mapping.
Update Set management: Package all ServiceNow configuration changes — import set table definitions, transform maps, custom dictionary fields, choice list entries, and business rules — into a dedicated Update Set. Name it clearly (e.g., SWSD_Migration_Config_v1). This allows you to promote your migration configuration from dev to test to production without manual recreation, and provides a clean rollback path by backing out the Update Set if needed. Capture the Update Set in your dev instance, move it to test for validation, then promote to production only after a successful test migration.
Configure coalesce fields on every transform map: set correlation_id (mapped to the SolarWinds legacy ID) as the coalesce field for incidents, problems, changes, and CIs. Set email as the coalesce field for users. This prevents duplicates during delta syncs and re-runs.
Step 4: Load in Dependency Order
The load sequence that prevents orphaned references:
- Locations — SolarWinds Sites →
cmn_location - Departments — →
cmn_department - Users — →
sys_user, referencing location and department - Groups — →
sys_user_groupand group membership →sys_user_grmember - Knowledge Base structure — →
kb_knowledge_baseandkb_category - Knowledge articles — →
kb_knowledge - CMDB CI classes — →
cmdb_cisubclasses, starting with parent CIs - CMDB relationships — →
cmdb_rel_ci - Assets — →
alm_asset, linked to CIs and users - Incidents — →
incident, referencing users, groups, CIs - Service Requests — →
sc_request+sc_req_item - Problems — →
problem, linking related incidents - Changes — →
change_request - Comments / journal entries — →
sys_journal_field, linked byelement_id - Attachments — →
sys_attachment, linked to parent records
Capture the newly generated ServiceNow sys_id for every record and map it back to the legacy SolarWinds ID in your lookup table. Use the Identification and Reconciliation Engine (IRE) when loading CIs to prevent duplicates — IRE matches incoming CIs against existing records using identifier rules you configure (typically serial number, name + class, or a custom correlation ID).
If you load incidents before users or CIs exist in ServiceNow, every reference field will be empty. There is no way to retroactively populate reference fields via Import Sets without re-running the transform. Get the order right the first time.
import requests
import time
import random
def backoff_with_jitter(attempt, base=2, max_wait=120):
wait = min(base ** attempt + random.uniform(0, 1), max_wait)
return wait
def load_import_set_chunk(records, target_table, instance, auth):
url = f"https://{instance}.service-now.com/api/now/import/{target_table}/insertMultiple"
headers = {"Content-Type": "application/json", "Accept": "application/json"}
chunk_size = 200
for i in range(0, len(records), chunk_size):
chunk = records[i:i + chunk_size]
# Cast all values to strings per ServiceNow Import Set requirements
sanitized = [{k: str(v) if v is not None else "" for k, v in r.items()} for r in chunk]
attempt = 0
while attempt < 5:
response = requests.post(url, auth=auth, headers=headers, json={"records": sanitized})
if response.status_code == 429:
time.sleep(backoff_with_jitter(attempt))
attempt += 1
continue
if response.status_code in [500, 502, 503]:
time.sleep(backoff_with_jitter(attempt))
attempt += 1
continue
break
log_response(response)429 handling is not optional. ServiceNow documents rate-limit response headers and retry behavior, so your loader should treat throttling as normal control flow, not as a surprise outage. (servicenow.com)
Step 5: Rebuild Relationships
After loading primary records, use the ID lookup table to:
- Link incidents to parent problems
- Associate CIs with incidents, problems, and changes via
cmdb_rel_ci - Connect service requests to their parent request records
- Map user assignments (caller, assigned_to, resolved_by)
Step 6: Validate
Run record count reconciliation for every object type. See the validation section below for the full testing protocol.
Step 7: Run Delta Sync and Cut Over
Extract records created or modified after the initial bulk migration using the updated_at filter on SolarWinds API endpoints (e.g., ?updated_at_gte=2026-07-01T00:00:00Z). Load the delta set into ServiceNow — coalesce fields on your transform maps ensure existing records are updated rather than duplicated. Validate counts, then switch agent operations and email routing to ServiceNow.
If audit fidelity matters, decide before build whether SolarWinds comments become ServiceNow comments (requester-visible), work_notes (internal), or a preserved legacy transcript attachment. Retrofitting that choice after UAT usually means a full reload.
Timeline, Phases, and Risk Register
A realistic timeline depends on record volume and CMDB complexity, not raw row count alone.
| Phase | Small (< 50K records) | Enterprise (500K+ records) |
|---|---|---|
| Discovery and audit | 2–3 days | 1–2 weeks |
| Field mapping and transform design | 3–5 days | 1–2 weeks |
| Script development and staging | 5–7 days | 2–3 weeks |
| Test migration (minimum 2 rounds) | 3–5 days | 1–2 weeks |
| Delta sync and cutover | 1–2 days | 2–3 days |
| Post-migration validation | 2–3 days | 1 week |
| Total | 3–4 weeks | 6–10 weeks |
Use a phased rollout when multiple departments share the desk or when service catalog logic is deep. Use a big-bang cutover when one central team owns the desk and the workflow model is simple. Use a delta model when the desk runs 24/7. Our zero-downtime help desk migration guide covers that pattern in detail.
Risk Register
| Risk | Likelihood | Mitigation |
|---|---|---|
| Broken CI-to-incident references | High | Enforce strict load order, validate reference fields post-load |
| SolarWinds API rate throttling | Medium | Implement exponential backoff with jitter, extract during off-hours |
| ServiceNow Import Set transform failures | Medium | Enable synchronous transforms via sys_rest_insert_multiple, log every error, build retry queue |
| Attachment data loss | Medium | Verify attachment byte count source vs. target for random sample |
| Duplicate user records | High | Deduplicate on email before load, configure coalesce on sys_user.email in transform maps |
| Custom field type mismatch | Low | Audit field types during mapping phase, test with sample data before bulk load |
| Workflow drift after go-live | High | Rebuild and test SLAs, approvals, and routing as a separate workstream before cutover |
| Task Management v2 gaps | Medium (if in use) | Scope tasks out or arrange alternate export path (CSV or direct DB query if available) |
| Instance performance degradation during load | Medium | Schedule loads during off-peak hours, monitor sys_import_set_run for long transforms |
| Coalesce misconfiguration causing duplicates | High | Test coalesce behavior with 100-record sample before full load, verify coalesce fields on every transform map |
Rollback Plan
Before go-live, take a full instance clone of your ServiceNow production instance to a sub-production environment. Instance cloning is preferred over XML exports for environments with more than 100,000 records because it captures the complete database state including attachments. ServiceNow instance cloning typically completes in 2–4 hours for mid-size instances.
Clone vs. XML export decision:
- Clone — use for full rollback scenarios. Restores the entire instance to the pre-migration state. Risk: if new post-cutover tickets were created in production after go-live, a clone restore will destroy them. Mitigate by exporting new post-cutover records before restoring.
- XML export — use for partial rollback of specific tables. Faster to restore selectively but does not capture relationships or system state as reliably. Suitable for environments under 50,000 records.
Keep SolarWinds Service Desk active in read-only mode for 30 days post-cutover so agents can reference the legacy system if critical data is missing. Coordinate SolarWinds contract termination timing: do not cancel your SolarWinds subscription until the 30-day validation window closes and all stakeholders have signed off on data completeness. If SolarWinds enforces a data retention policy upon account closure, export a final full backup before the account is deactivated.
What Agents and End Users Notice During Cutover
If you run a delta cutover, end users mostly notice new URLs, new ticket numbers, and a new portal experience. Agents notice more: new state vocabulary, new assignment logic, rebuilt catalog fulfillment, and a different Activity feed for historical comments.
Agent downtime is the biggest operational risk during cutover. A delta migration syncs only the records created or modified since the initial bulk load. This allows agents to work in SolarWinds on Friday and log into ServiceNow on Monday with all weekend tickets fully synced.
Preserving resolution history matters for compliance and agent context. Auditors require proof of exactly who approved a change request and when. If your migration collapses old comments into a single description field, you lose chronology and make audit review harder. Historical SLA metrics are only meaningful if the underlying incident lifecycle data is intact. Load SolarWinds comments as sys_journal_field entries with original timestamps — public replies as comments, internal analyst history as work_notes.
Searchability is the test many teams forget. Agents should be able to find migrated records by legacy ticket number, requester, CI, and article title within ServiceNow. Store the legacy SolarWinds ticket number in the correlation_id field on the incident table and create a list view column for it. If agents cannot search and find migrated records within the first hour, they will lose confidence in the migration regardless of data completeness.
Edge Cases and Known Limitations
Every SolarWinds-to-ServiceNow migration hits edge cases. Plan for these specifically.
Multi-Level CMDB Dependencies
SolarWinds Service Desk CMDB uses a parent/child CI hierarchy with dependency links. ServiceNow stores CI relationships in the cmdb_rel_ci table using typed relationships (e.g., "Runs on", "Depends on", "Used by"). Each SolarWinds dependency link must be mapped to a specific ServiceNow relationship type. If your SolarWinds CMDB has 4+ levels of nested dependencies, plan for a dedicated CMDB mapping phase that adds 1–2 weeks to the timeline.
If a SolarWinds asset does not fit a predefined ServiceNow CI class, you must extend the CMDB schema by creating a new CI class that inherits from an appropriate parent class (e.g., extend cmdb_ci_hardware for a custom hardware type). Do not dump every CI into generic cmdb_ci unless you are intentionally archiving legacy data with no ongoing management need.
After loading CMDB data, use the CMDB Health Dashboard (navigate to Configuration > CMDB Dashboard in ServiceNow) to validate CI completeness, relationship integrity, and orphan detection. The Health Dashboard scores CIs on completeness (required fields populated), compliance (CSDM alignment), and relationship health. Run this validation before declaring the CMDB migration complete.
Inline Images
Images pasted directly into SolarWinds ticket descriptions are hosted on SolarWinds servers. If you migrate the raw HTML, the image links will break when the SolarWinds instance is decommissioned. You must programmatically download these images, upload them to ServiceNow via the Attachment API, and rewrite the HTML src tags in the ticket body to point to the new ServiceNow attachment URLs. Regex pattern to identify SolarWinds-hosted images: src="https://[^"]*samanage [^"]*".
Attachments
SolarWinds attachments are accessible via the API as downloadable URLs on incident, problem, and change records. ServiceNow stores attachments as chunked binary data in sys_attachment and sys_attachment_doc tables (4KB chunks). Each attachment must be downloaded from SolarWinds and uploaded to ServiceNow via the Attachment API. The ServiceNow inbound REST payload limit means attachments above the configured threshold must be uploaded using the binary file upload endpoint (Content-Type: application/octet-stream) rather than base64-encoded JSON payloads.
Orphaned Records and Duplicates
Common data quality issues in SolarWinds exports:
- Duplicate users created by email address variations. Deduplicate before load by normalizing email to lowercase and choosing the most recent active record.
- Orphaned incidents referencing deleted users or groups. Assign these to a "Migration Archive" user in ServiceNow with a note in the
work_notesfield indicating the original assignee was deleted in the source system. - Inconsistent category values caused by renamed categories mid-lifecycle. Build a normalization map before creating
sys_choiceentries. Example: "Network Issue" and "Network Issues" should resolve to a single value.
ServiceNow Transform Map Failures
The Import Set API's insertMultiple method processes asynchronously by default and may not provide meaningful error feedback in the response. To get transform results, configure synchronous processing: navigate to sys_rest_insert_multiple, find the record for your import set table, and set the synchronous field to true. Monitor the sys_import_set_run table for row-level error details — each failed row gets a status of error with a message column describing the failure. Common failure causes: reference field pointing to a non-existent record, field type mismatch, and mandatory field violations.
Validation and Testing Protocol
A migration is only done when the numbers match. Do not rely on total record counts alone — a count might match while reference fields are completely empty.
Record count reconciliation. Compare total record counts per object type between SolarWinds (from your extraction X-Total-Count headers) and ServiceNow (query each target table with sysparm_count=true). Allow 0% variance tolerance for incidents, users, and CIs. Document any intentional exclusions (e.g., test records, spam tickets).
Field-level spot checks. Sample 50–100 records per object type. Verify every mapped field contains the correct value, especially reference fields (Caller, Assignment Group), timestamps, state, and priority. Use a spreadsheet that maps SolarWinds record ID → ServiceNow sys_id → field-by-field comparison.
Relationship integrity. Confirm that CI-to-incident links, problem-to-incident links, and user group memberships are intact. Query cmdb_rel_ci to verify CMDB relationship counts match the source. Run SELECT count(*) FROM cmdb_rel_ci WHERE parent IS NULL OR child IS NULL to find orphaned relationships.
Attachment verification. Compare attachment counts and byte sizes for a random sample of 50 records. Download and open 10–20 attachments to confirm they are not corrupted or zero-byte.
Comment thread order. Verify that journal entries on migrated incidents appear in correct chronological order with accurate author attribution. Check 20 incidents with 5+ comments each.
Knowledge Base validation. Confirm articles retain formatting and that internal links point to the new ServiceNow URLs. Verify that KB articles are associated with the correct knowledge base and category.
CMDB Health Dashboard. Run the CMDB Health Dashboard after CI and relationship loading. Target a completeness score above 80% and zero orphaned relationships.
UAT with agents. Have 3–5 IT agents perform their standard triage workflow on migrated tickets. Confirm they can view history, add notes, search by legacy ticket number (via correlation_id), and resolve tickets without issues. Document any usability gaps.
For a comprehensive post-migration testing framework, see our help desk migration QA checklist.
Build In-House vs. Use a Managed Service
Build In-House When:
- You have fewer than 50,000 total records across all objects
- Your CMDB is flat or has one level of CI hierarchy
- You have a ServiceNow developer on staff who understands Import Sets, Transform Maps, and coalesce configuration
- You can tolerate a 24–48 hour maintenance window for cutover
- No regulatory audit trail requirements
- Engineering team can dedicate 150–250 hours without impacting product delivery
Use a Managed Service When:
- You have 100,000+ records or a multi-level CMDB with custom CI types
- Zero downtime is a requirement (24/7 IT operations)
- You need to preserve comment timestamps and original author attribution for audit compliance
- Your team cannot absorb 4–8 weeks of engineering time without impacting product work
- Compliance requires a documented chain of custody for migrated data
- You have 50,000+ attachments requiring binary download, upload, and re-linking
The primary risk of DIY is not the initial build — it is the 2–3 re-migration cycles caused by broken references, missed edge cases (inline images, coalesce misconfiguration, transform map async behavior), and errors not caught until agents work in the new system. Each re-migration cycle adds 1–2 weeks.
Frequently Asked Questions
How long does a SolarWinds Service Desk to ServiceNow migration take?
Small environments with fewer than 50,000 records typically complete in 3–4 weeks including testing. Enterprise migrations with 500,000+ records, CMDB hierarchies, and compliance requirements take 6–10 weeks. The largest time variable is the number of test migration cycles required to achieve clean validation — most teams need 2–3 test rounds.
What data cannot be migrated from SolarWinds Service Desk to ServiceNow?
Automation rules, SLA policies, workflow triggers, report configurations, dashboards, email notification templates, and portal branding cannot be migrated. These must be manually rebuilt in ServiceNow. The historical data moves; the operating logic does not.
Can SolarWinds Service Desk history be preserved in ServiceNow?
Yes. Incident history, internal work notes, and public comments can be fully preserved by loading them as sys_journal_field entries with original timestamps. This requires the migration user account to have elevated privileges (import_set_loader, admin) to override sys_created_on and sys_created_by fields. Each comment becomes a separate journal entry linked by element_id to the parent record's sys_id.
Can I migrate CMDB data without losing relationships?
Yes, but it requires treating CMDB as its own migration stream. Load CIs into the correct ServiceNow subclasses first, then load cmdb_rel_ci relationship records after both endpoint CIs exist. Use the Identification and Reconciliation Engine (IRE) to prevent duplicate CIs. After loading, validate with the CMDB Health Dashboard. Without strict load ordering, CMDB data will load but relationships will be lost.
How much does a SolarWinds Service Desk to ServiceNow migration cost?
A DIY API-based migration for a small environment (under 50,000 records) costs primarily in engineering time — typically 150–250 hours of developer effort at your internal rate. Managed migration services for enterprise environments with CMDB and attachments typically range from $10,000 to $50,000+ depending on record volume, CMDB complexity, and compliance requirements. Native CSV exports are free but risk significant data loss on attachments, comments, and relationships.
Do I need ServiceNow ITSM Pro for this migration?
Not for the data migration itself. ITSM Standard supports Import Sets, Transform Maps, and the Table/Attachment APIs. However, if your post-migration workflow design depends on Flow Designer (beyond basic flows), the Identification and Reconciliation Engine, or CSDM alignment tools, you need ITSM Pro or Enterprise. Verify your license tier before designing post-migration workflows.
When should I cancel my SolarWinds Service Desk subscription?
Keep SolarWinds active in read-only mode for at least 30 days after cutover. This gives agents a fallback reference and provides a safety net for data validation. Do not cancel until all stakeholders have signed off on data completeness. If SolarWinds enforces data deletion upon account closure, perform a final full data export before deactivation.
Frequently Asked Questions
- How long does a SolarWinds Service Desk to ServiceNow migration take?
- Small environments with fewer than 50,000 records typically complete in 3–4 weeks including testing. Enterprise migrations with 500,000+ records, CMDB hierarchies, and compliance requirements take 6–10 weeks. The largest time variable is the number of test migration cycles required to achieve clean validation.
- What data cannot be migrated from SolarWinds Service Desk to ServiceNow?
- Automation rules, SLA policies, workflow triggers, report configurations, dashboards, email notification templates, and portal branding cannot be migrated. These must be manually rebuilt in ServiceNow. The historical data moves; the operating logic does not.
- Can SolarWinds Service Desk history be preserved in ServiceNow?
- Yes. Incident history, internal work notes, and public comments can be fully preserved by loading them as sys_journal_field entries with original timestamps. This requires the migration user account to have elevated privileges to override sys_created_on and sys_created_by fields.
- Can I migrate CMDB data without losing relationships?
- Yes, but it requires treating CMDB as its own migration stream. Load CIs into the correct ServiceNow subclasses first, then load cmdb_rel_ci relationship records after both endpoint CIs exist. Use the Identification and Reconciliation Engine to prevent duplicate CIs.
- How much does a SolarWinds Service Desk to ServiceNow migration cost?
- A DIY API-based migration for a small environment costs 150–250 hours of developer time. Managed migration services for enterprise environments typically range from $10,000 to $50,000+ depending on scope, CMDB complexity, and compliance requirements.
