Welcome to Migration Studio

Your comprehensive guide to seamless Salesforce data migration

Quick Navigation

Getting Started

Prerequisites

  • Salesforce CLI: Installed and configured (sf version)
  • Authenticated Orgs: Both source and target orgs authenticated via CLI
  • Load Plan: JSON file defining your migration configuration

5-Step Workflow

1
Authenticate Orgs
Connect to your source and target Salesforce orgs
2
Select Objects
Choose which objects to include in your migration
3
Configure Load Plan
Upload or edit your migration plan in JSON format
4
Compare Data
Review differences between source and target orgs — including value-level differences
5
Execute Migration
Validate, generate CSVs, or run full migration

CLI Flags

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.

Key Features

Modern Interface

Dark theme UI with Monaco code editor, real-time terminal, and split pane layout

Advanced Comparison

Sortable, searchable tables with pagination. Compare field-level differences including value-level diffs for records present in both orgs

Data Export

Download comparison results as CSV. Export all data to ZIP archives. Generate update-ready CSVs from Value Differences

Real-time Updates

Live terminal output via WebSocket. Monitor migration progress in real-time

Secure

Uses Salesforce CLI authentication. Credentials stored locally only

Large Volume Support

SOQL pagination via nextRecordsUrl handles unlimited records. CSV uploads auto-split into 100 k-row chunks

Authentication Tab

Connect to your Salesforce orgs using usernames or aliases configured in the Salesforce CLI.

How to Authenticate

  1. Enter your source org username or alias (e.g., user@source.com)
  2. Click "Authenticate Source Org"
  3. Repeat for target org
  4. Status indicators will turn green when connected

Important

Orgs must be pre-authenticated via Salesforce CLI. Run sf org list to see available orgs.

Select Objects Tab

Choose which Salesforce objects to include in your migration using the searchable object list.

Search

Quickly find objects in large load plans

  • • Type to filter objects in real-time
  • • Press Ctrl+K to focus search
  • • Press Esc to clear

Bulk Actions

Manage multiple objects at once

  • Select All: Selects visible objects
  • Deselect All: Deselects visible objects
  • • Works with search filter
💡

Pro Tip

Search for a specific object type (e.g., "Product"), then click "Select All" to quickly select all product-related objects.

Edit Plan Tab

Configure your migration using a JSON load plan in the Monaco editor.

Load Sample

Start with a pre-configured example plan

Upload JSON

Import your existing migration plan

Save Plan

Save changes to your configuration

Monaco Editor Shortcuts

Format JSON: Alt+Shift+F
Find: Ctrl+F
Replace: Ctrl+H
Autocomplete: Ctrl+Space

Compare Data Tab

Analyze differences between source and target orgs with advanced comparison features. Results are grouped into four categories:

Only in Source

Records that exist in source but are absent from target — these are insert candidates.

Only in Target

Records present in target but missing from source — potential deletion candidates (see Deletion Candidates section).

Value Differences

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.

In Both Orgs

Records that exist in both orgs with identical field values — no action needed.

Table Features

Column Sorting:

Click headers to sort ascending/descending

🔍
Search:

Filter across all fields in real-time

📄
Pagination:

Choose 10, 25, 50, or 100 rows per page

📥
Export CSV:

Download full dataset for each category

CLI Integration

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.

Value Differences (Compare Tab)

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.

Reading the Table

  • Cells with changed values are highlighted in amber. The cell text shows the new (source) value followed by the previous (target) value in muted text: Acme Corp  (was: Acme)
  • Unchanged fields in the same row are displayed normally so you have full record context.
  • Pagination, search, and column sorting work the same as other comparison tables.

Download Update-Ready CSV

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:

  • The Id column contains the target-org record Id.
  • Each column contains the source value (what you want the target to become).
  • Fields that are null in source but non-null in target are written as #N/A — the Bulk API v2 token to explicitly clear a field (see Null Field Handling).
💡

Workflow Recommendation

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.

Migration Tab

Execute your migration with four different operation modes.

Validate Configuration

Checks if your migration setup is valid. Verifies object and field accessibility. Always run this first!

📄

Generate CSV Files

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.

🚀

Start Migration

Executes the full migration to target org. Shows real-time progress in terminal. Requires confirmation.

📦

Export to ZIP

Downloads all data from source and target orgs. Creates comparison summary. Saves as all.zip.

Verbose Logging Toggle (Migration Tab)

The Verbose toggle switch in the Migration tab enables or disables detailed diagnostic output in the terminal panel.

What verbose mode logs

  • Full SOQL queries sent to each org
  • Field-resolution steps (source field → target field mapping)
  • Bulk API job IDs and batch submission details
  • Pagination cursors (nextRecordsUrl)
  • Row counts per chunk upload

When to use it

  • Debugging unexpected migration results
  • Verifying which fields are being mapped
  • Investigating slow or stalled jobs
  • Auditing SOQL queries for permission errors

CLI equivalent and live toggle

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

Deletion Candidates (Migration Tab)

Requires --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.

Paginated Candidate Table

  • Lists every target record absent from source with clickable links to the target-org record page.
  • Sortable and searchable — same controls as the Compare tab tables.
  • Pagination configurable: 10 / 25 / 50 / 100 rows per page.
  • Download CSV exports all candidates so you can review them offline before taking action.

Delete from Target

The "Delete from Target" button triggers a Salesforce Bulk API 2.0 delete job for all candidates in the current view.

  1. Click "Delete from Target".
  2. A confirmation modal displays the record count and object type. Review carefully.
  3. Confirm to submit the Bulk API 2.0 delete job. The terminal shows job progress in real-time.
  4. Job results (success / failed rows) are streamed to the terminal as the job completes.

Bulk API 2.0 Delete — Technical Notes

  • The delete payload is a CSV containing only the Id column.
  • Large candidate sets are automatically split into chunks of 100 k rows — one Bulk job per chunk.
  • Each job is polled until JobComplete or a 30-minute timeout.
  • Partial failures (individual row errors) are reported in the terminal and do not abort remaining chunks.

Null Field Handling in Update CSVs

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)

Important: #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.

Large Volume Support

Migration Studio is designed to handle arbitrarily large datasets without manual intervention. The following mechanisms work together automatically.

SOQL Pagination

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.

Automatic CSV Chunking

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.

  • Chunk boundaries are computed on row count, not byte size, to keep logic simple.
  • Jobs run sequentially to avoid Bulk API concurrency limits.
  • Each job's result URL is logged to the terminal for later audit.

Job Poll Timeout

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.

💡

Tip for very large migrations

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.

Keyboard Shortcuts

Global Shortcuts

Focus object search Ctrl+K
Clear search Esc

Monaco Editor

Format JSON Alt+Shift+F
Find Ctrl+F
Replace Ctrl+H
Autocomplete Ctrl+Space

* On Mac, use Cmd instead of Ctrl

Troubleshooting

Authentication Failed

Check if org is authenticated in Salesforce CLI:

sf org list

Re-authenticate if needed:

sf org login web --alias my-org

Load Plan Errors

Ensure your JSON is valid:

  • Use the Monaco editor's format feature (Alt+Shift+F)
  • Check for missing commas, brackets, or quotes
  • Verify all required fields are present

Migration Issues

Common solutions:

  • Always run "Validate Configuration" before migration
  • Check terminal output for detailed error messages
  • Enable Verbose Logging for field-resolution details
  • Verify field permissions in target org
  • Ensure required fields have values

Delete Button Not Visible

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.

Bulk Job Timeout After 30 Minutes

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:

  • In Salesforce Setup, search for "Bulk Data Load Jobs" and locate the Job ID.
  • Check the job's failed-results file for row-level error messages.
  • Very large jobs may need to be broken into smaller object subsets.

Performance Tips

  • Use pagination in the Compare tab for large datasets
  • Download logs to review later instead of keeping terminal open
  • Process objects in batches if you have many objects
  • Enable Verbose Logging only when debugging — it adds overhead for large jobs

Tips & Best Practices

Do This

  • ✅ Always validate configuration before migration
  • ✅ Compare data to understand differences — including Value Differences
  • ✅ Use "Generate CSV" to review update files (including #N/A cells) before a live migration run
  • ✅ Test with a small subset first
  • ✅ Download and review logs
  • ✅ Use descriptive load plan filenames
  • ✅ Review Deletion Candidate CSV before clicking "Delete from Target"

Avoid This

  • ❌ Don't skip validation step
  • ❌ Don't migrate without comparing first
  • ❌ Don't ignore terminal warnings
  • ❌ Don't close browser during migration
  • ❌ Don't forget to backup data
  • ❌ Don't edit #N/A tokens out of update CSVs — they are intentional null signals
  • ❌ Don't start the server with --allow-delete in shared environments unless necessary

Reminder: #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.