Used by a global banking software vendor on the Microsoft stack to move bank data into Dynamics 365, in place of SSIS packages.
Read the case study →- 4 to 5M
- records in a single bank migration into Dynamics 365
- 1
- outbound call from the client's tenant: a license check
- 3
- deployment modes: client Azure, on-premises, hosted in-region
01 · The problem
SSIS was built for one data team. You serve dozens of clients.
Every client is a new build.
Packages are copied, patched and rebuilt for each engagement.
Mapping lives in dialogs and workshops.
Field decisions sit in designer dialogs and meeting notes, and leave with the consultant who made them.
Failures are slow to trace.
Finding the record that broke a load means reading package logs by hand.
Scheduled runs need licensed, always-on servers.
A nightly job keeps a production server provisioned between runs.
02 · How it works
Build it once as a template. Bind it for each client.
Partners build a Job Template once and reuse it for every client. Only the bound connectors and arguments change.
Layer 1
Task
One streaming read, transform and write pipeline, defined in YAML with no credentials inside.
Layer 2
Job Template
Chains Tasks into a dependency graph: validate the source, build lookups, then migrate.
Layer 3
Job
Binds a template to a client's real connectors and arguments.
Every execution
Run
Recorded with status, per-task progress, logs and errored records.
Mapping store
Records which destination record each source record became, with a content hash.
No duplicates
Re-runs update what already exists. They never create a second copy.
Change detection
Only records whose content hash changed are reprocessed.
Resume on failure
A failed run resumes where it stopped.
Records stream through with backpressure, so millions of rows never exhaust memory.
See how a run works →03 · AI and the engine
AI drafts the mapping. The engine proves every record.
- Drafts mappings and pipelines from a prompt.
- Flags bad source data before the load.
- Explains failures and proposes the fix, with raw logs one click away.
- Works from Claude: start jobs, ask about runs, pull reports.
Why did last night's run fail?
Assistant · read 412 log entries and the validate_source report
412 contacts failed in migrate_contacts. Their parent accounts were skipped by validate_source because AccountStatus is empty. Suggested fix: default AccountStatus to Active in map_fields.
- 186 accounts have an empty AccountStatus
- 412 contacts point to those accounts as their parent
- The other 111,812 contacts loaded normally
If I resume, will it create duplicate accounts?
Assistant
No. The mapping store records which Dataverse record each source row became, so the 47,838 accounts already loaded are skipped and only the 186 fixed ones are created. The 412 contacts then link to them.
02:14:07.221 ERROR migrate_contacts record=CT-204118 parentcustomerid unresolved: account ACC-100311 skipped by validate_source (AccountStatus empty) 02:14:07.236 ERROR migrate_contacts record=CT-204119 parentcustomerid unresolved: account ACC-100311 … 410 more
11 task: migrate_accounts22 connectors:33 source: sqlserver44 destination: dynamics36555 steps:66 - call_method:77 connector: source88 method: read99 table: dbo.Customers1010 - map_fields:1111 name: CustomerName1212 accountnumber: CustomerNo1313 emailaddress1: PrimaryEmail14+ accountstatus: AccountStatus ? AccountStatus : "Active"1415 - compute_hash: {}1516 - call_method:1617 connector: destination1718 method: upsert1819 entity: account1920 error_handling: ignore_rest2021 - set_destination_id: {}
Every suggestion becomes plain YAML on a deterministic engine: readable, diffable and versioned.
04 · Deployment
It runs inside your client's tenant. Only a license check leaves.
Cloneto license service
Sources
Client's Azure subscription
Control plane
UI and API
Executor
Scales to zero
Azure Key Vault
Managed identity
State store
Auto-pausing SQL: run history, mapping store, metrics
Destination
Data residency
Records are read, transformed and written inside the client's Azure subscription or on-premises environment.
Secrets in Azure Key Vault
Connector credentials live in the client's Key Vault, reached through a managed identity. None sit in YAML.
Separation of duties
The control plane resolves credentials at run time. The executor that moves the data never resolves secrets.
One deployment per client
Each client runs in its own isolated deployment, with its own state store and run history.
Every run audited
Status, per-task progress and logs are recorded for every run, down to each errored record.
Login with optional SSO
Users sign in to the control plane, with single sign-on available when the client requires it.
05 · Cutover and sync
One engine for cutover and nightly sync.
One-time cutover
Initial load
History moves into Dynamics 365 while the source stays live.
Delta runs
Only what changed carries over, while users keep working.
Final delta
A last delta at cutover, then users move to the new system.
Ongoing nightly sync
- Trigger
- A cron schedule or a webhook
- Scope
- Only records whose content hash changed
- Between runs
- The executor scales to zero
Batch and scheduled pipelines. Cloneto does not do real-time event streaming.
An SSIS runtime is provisioned for peak and runs around the clock. Cloneto's executor starts for the run and scales to zero afterwards, so between runs the only standing cost is the control plane.
06 · Client visibility
Your client sees progress and errors as they happen.
A shareable dashboard shows the end client live progress, per-object counts and errors. It replaces the status email.
Migration status
Northwind · Migration to Dynamics 365
Live · last updated 14:32 UTC
In progress
Initial load
Started today 08:05
From Sat 3 Oct
Delta runs
Nightly, changed records only
Sat 10 Oct
Final delta
Source set to read-only
Mon 12 Oct
Cutover
Users move to Dynamics 365
Records migrated
93,436
of 289,678 · 32.3%
Objects complete
1 of 4
Errors
42
each one explained
Progress by object
| Object | Migrated | Errors |
|---|---|---|
| Accounts | 21,406of 21,406 | 0 |
| Contacts | 63,118of 67,240 | 38 |
| Opportunities | 8,912of 14,630 | 4 |
| Activities | 0of 186,402 | 0 |
Errors as they surface
Contacts · 38 records14:21 UTC
Email address format is invalid
Trey Research is correcting these in the source. They retry in the first delta run.
Opportunities · 4 records14:29 UTC
Close date is earlier than created date
Waiting on Northwind to confirm the right close dates.
07 · Connectors
Dynamics 365 and Dataverse, and the systems that feed them.
Microsoft
Dynamics 365 and Dataverse
Databases
SQL Server
PostgreSQL
MySQL
SQLite
MongoDB
Files and storage
CSV
YAML
Azure Blob Storage
Amazon S3
Business apps
Business Central
NetSuite
Salesforce
HubSpot
Zendesk
and hundreds more, through a unified connector layer
Not on Dynamics? Cloneto runs one-time migrations and ongoing sync between any systems it connects to.
See every use case →08 · Why now
Support dates are set.
Dynamics 365 Customer Engagement v9 on-premisesMainstream support ends January 12, 2027. Extended, security-only support ends January 9, 2029.
SQL Server 2016Home to many SSIS estates, it reached end of support on July 14, 2026.Plan a Dynamics 365 move to the cloud →
09 · The team
Built by the ClonePartner team.
Cloneto comes from the team behind ClonePartner, the engineer-led data migration company. When a job needs hands-on engineering, ClonePartner engineers can take it.
ClonePartner holds a SOC 2 Type II report and ISO 27001 certification, and the security package is available on request.
Trust and compliance →The last migration you build from scratch.
Bring a real migration.
Thirty minutes with an engineer. Bring a source, a target and a sample of the data, and we'll draft the mapping and run it against a sandbox on the call.
Book a technical walkthrough