Your comprehensive guide to seamless Salesforce data migration
sf version)
Start the Migration Studio server with one or more optional flags:
node server.js [--port <n>] [--verbose] [--allow-delete]
| Flag | Default | Description |
|---|---|---|
--port <n> |
3000 | TCP port the HTTP server listens on |
--verbose |
off | Enable detailed field-resolution and SOQL query logs in the terminal. Can also be toggled live in the Migration tab without restarting. |
--allow-delete |
off |
Unlocks the Deletion Candidates button and the
/api/bulk-delete endpoint.
Without this flag the server returns HTTP 403 on any delete request
and the UI button remains hidden.
|
Use --allow-delete with caution.
It enables permanent deletion of target-org records via Bulk API 2.0.
Always review Deletion Candidate CSVs before confirming a delete job.
Dark theme UI with Monaco code editor, real-time terminal, and split pane layout
Sortable, searchable tables with pagination. Compare field-level differences including value-level diffs for records present in both orgs
Download comparison results as CSV. Export all data to ZIP archives. Generate update-ready CSVs from Value Differences
Live terminal output via WebSocket. Monitor migration progress in real-time
Uses Salesforce CLI authentication. Credentials stored locally only
SOQL pagination via nextRecordsUrl handles unlimited records. CSV uploads auto-split into 100 k-row chunks
Connect to your Salesforce orgs using usernames or aliases configured in the Salesforce CLI.
user@source.com)Orgs must be pre-authenticated via Salesforce CLI. Run sf org list to see available orgs.
Choose which Salesforce objects to include in your migration using the searchable object list.
Quickly find objects in large load plans
Manage multiple objects at once
Search for a specific object type (e.g., "Product"), then click "Select All" to quickly select all product-related objects.
Configure your migration using a JSON load plan in the Monaco editor.
Start with a pre-configured example plan
Import your existing migration plan
Save changes to your configuration
Analyze differences between source and target orgs with advanced comparison features. Results are grouped into four categories:
Records that exist in source but are absent from target — these are insert candidates.
Records present in target but missing from source — potential deletion candidates (see Deletion Candidates section).
Records present in both orgs where one or more field values differ. Highlighted cells show the delta. Download CSV generates an update-ready file. See full details below.
Records that exist in both orgs with identical field values — no action needed.
Click headers to sort ascending/descending
Filter across all fields in real-time
Choose 10, 25, 50, or 100 rows per page
Download full dataset for each category
For detailed field-level comparison, use the personalized CLI command shown in the interface:
sf-data-util compare -s source@org.com -t target@org.com -l ./your-file.json -o ObjectName
Click "Copy" to copy the command with your actual credentials.
The Value Differences category appears between "Only in Target" and "In Both Orgs" in the Compare tab. It lists every record that exists in both orgs but has at least one field whose value differs between source and target.
Acme Corp (was: Acme)
The Download CSV button for Value Differences produces a CSV that is pre-formatted for direct use with Salesforce Bulk API v2 as an update operation:
Id column contains the target-org record Id.#N/A — the Bulk API v2 token to explicitly clear a field (see Null Field Handling).Download the Value Differences CSV and review it in a spreadsheet before running "Start Migration". This gives you a precise, auditable list of every field that will change.
Execute your migration with four different operation modes.
Checks if your migration setup is valid. Verifies object and field accessibility. Always run this first!
Creates insert and update CSV files without loading data.
Use this to review the exact data that will be migrated — including
any #N/A null-clearing fields —
before committing to a full migration run.
Executes the full migration to target org. Shows real-time progress in terminal. Requires confirmation.
Downloads all data from source and target orgs. Creates comparison summary. Saves as all.zip.
The Verbose toggle switch in the Migration tab enables or disables detailed diagnostic output in the terminal panel.
nextRecordsUrl)
Starting the server with --verbose enables verbose
mode from launch. The in-app toggle mirrors this flag and can be flipped at any time
without restarting the server — useful when you want verbose output for a specific
migration run but not others.
node server.js --verbose
--allow-delete
The "Deletion Candidates" button is only visible when the server was started with the
--allow-delete flag.
Without it the button is hidden and any direct API call to
/api/bulk-delete returns
HTTP 403 Forbidden.
Deletion Candidates are target-org records whose external key (or Id) is absent from the source org — i.e., records that were deleted in the source but still exist in the target.
The "Delete from Target" button triggers a Salesforce Bulk API 2.0 delete job for all candidates in the current view.
Id column.JobComplete or a 30-minute timeout.When building update CSVs (from Generate CSV Files or from a Value Differences download), the app applies specific encoding rules to correctly signal clearing a field versus leaving it unchanged — a distinction that matters in Salesforce Bulk API v2.
| Source value | Target value | CSV cell | Bulk API v2 meaning |
|---|---|---|---|
| Any non-null value | Any value | "new value" |
Set field to new value |
| null | Non-null | #N/A (unquoted) |
Explicitly clear the field to null |
| Same as target | Same as source | "" (empty string) |
No change (field not updated) |
#N/A means null — not "missing data"
If you open a generated update CSV in Excel or Google Sheets, cells showing
#N/A are intentional null-clearing tokens,
not errors. Do not replace or delete them before uploading.
The Salesforce Bulk API v2 specification defines #N/A
(unquoted, case-sensitive) as the signal to set a field to null.
An empty cell "" instructs Bulk API v2 to
leave the field unchanged.
Migration Studio is designed to handle arbitrarily large datasets without manual intervention. The following mechanisms work together automatically.
All SOQL queries use the Salesforce REST API's cursor-based pagination. When a result set
exceeds the batch size, the server automatically follows
nextRecordsUrl until all records are retrieved.
This handles any volume — there is no practical upper limit imposed by the app.
Enable Verbose Logging to see each page fetch logged in the terminal.
Before uploading CSVs to the Bulk API v2, the app splits each file into chunks of at most 100,000 rows — well under Salesforce's 150 MB per-job limit. Each chunk is submitted as an independent Bulk API v2 job.
The server polls each Bulk API v2 job for status at regular intervals.
If a job has not reached JobComplete after
30 minutes, the poll loop exits and the terminal
displays a clear timeout error message including the Job ID, so you can investigate
the job directly in Salesforce Setup → Bulk Data Load Jobs.
Use "Generate CSV Files" first to stage the data locally, review the chunks in your file system, then run "Start Migration". This decouples data extraction (SOQL) from data loading (Bulk API) and makes it easier to retry only the failed chunk if something goes wrong.
* On Mac, use Cmd instead of Ctrl
Check if org is authenticated in Salesforce CLI:
sf org list
Re-authenticate if needed:
sf org login web --alias my-org
Ensure your JSON is valid:
Common solutions:
The "Deletion Candidates" / "Delete from Target" button is intentionally hidden unless the server
is started with the --allow-delete flag.
Restart the server with:
node server.js --allow-delete
If the button still does not appear after restarting, hard-refresh the browser (Ctrl+Shift+R) to clear any cached UI state.
If a Bulk API v2 job takes longer than 30 minutes, the poll loop exits with a timeout error and logs the Job ID. To investigate:
#N/A cells) before a live migration run#N/A tokens out of update CSVs — they are intentional null signals--allow-delete in shared environments unless necessary#N/A in update CSVs means null
When you open a generated update CSV in Excel or Google Sheets, cells reading
#N/A are not spreadsheet errors —
they are the Salesforce Bulk API v2 token that explicitly sets the corresponding field to null
in the target org. Removing or quoting these tokens will cause the field to be left unchanged
instead of cleared.