High-performance Dataverse data migration engine. A drop-in replacement for CMT (Configuration Migration Tool) with 3-8x performance improvement through parallel operations and modern bulk APIs.
dotnet add package PPDS.Migration
using Microsoft . Extensions . DependencyInjection ;
using PPDS . Dataverse . DependencyInjection ;
using PPDS . Dataverse . Pooling ;
using PPDS . Migration . DependencyInjection ;
using PPDS . Migration . Export ;
using PPDS . Migration . Import ;
// Configure services
var services = new ServiceCollection ( ) ;
services . AddDataverseConnectionPool ( options =>
{
options . Connections . Add ( new DataverseConnection ( "Target" , connectionString ) ) ;
} ) ;
services . AddDataverseMigration ( options =>
{
options . Export . DegreeOfParallelism = 8 ;
options . Import . BatchSize = 1000 ;
options . Import . UseBulkApis = true ;
} ) ;
var provider = services . BuildServiceProvider ( ) ;
// Export
var exporter = provider . GetRequiredService < IExporter > ( ) ;
var exportResult = await exporter . ExportAsync ( "schema.xml" , "data.zip" ) ;
// Import
var importer = provider . GetRequiredService < IImporter > ( ) ;
var importResult = await importer . ImportAsync ( "data.zip" ) ;
All entities exported concurrently (no dependencies during export)
Configurable degree of parallelism
FetchXML paging with paging cookie support
Automatic dependency resolution using Tarjan's algorithm
Entities grouped into tiers based on lookup dependencies
Entities within a tier processed in parallel
Circular Reference Handling
Automatic detection of circular references (e.g., Account ↔ Contact)
Deferred field processing: import records first with null lookups, then update
No manual intervention required
Reads CMT schema.xml format
Produces CMT-compatible data.zip
Drop-in replacement for existing pipelines
Connection strings never logged
No PII/record data in logs
Only entity names, counts, and timing information reported
Export Flow:
schema.xml → SchemaAnalyzer → ParallelExporter → data.zip
↓
(N parallel workers)
Import Flow:
data.zip → DependencyGraphBuilder → ExecutionPlanBuilder → TieredImporter
↓ ↓ ↓
Tarjan's SCC Tier ordering Parallel within tier
↓
DeferredFieldProcessor
↓
RelationshipProcessor
Option
Default
Description
DegreeOfParallelism
CPU * 2
Maximum concurrent entity exports
PageSize
5000
Records per API request
Option
Default
Description
BatchSize
1000
Records per bulk operation
UseBulkApis
true
Use CreateMultiple/UpsertMultiple
BypassCustomPluginExecution
false
Skip custom plugins
BypassPowerAutomateFlows
false
Skip flows
ContinueOnError
true
Continue on individual failures
Mode
Upsert
Create, Update, or Upsert
Scenario
CMT
PPDS.Migration
Improvement
Export 50 entities, 100K records
~2 hours
~15 min
8x
Import 50 entities, 100K records
~4 hours
~1.5 hours
2.5x
.NET 8.0 or .NET 10.0
PPDS.Dataverse (connection pooling)
MIT License