Data migration

Moving records into the new system without losing history or inventing rows.

The failure is never the 96% of rows that map cleanly. It is the row with a null email the old system allowed and the new one rejects, and the foreign key that breaks because an ID got regenerated, found at two in the morning on cutover night instead of during a dry run three weeks earlier.

What this is

A migration moves records from an old data store into a new one, once, sometimes in phases, and it ends: there is a field mapping, a reconciliation step, and a row count that has to match at the end. That is different from an integration, which keeps two live systems talking indefinitely, and different from modernizing an application's logic, though the two often travel together when a rewrite changes where the data lives too.

The dry run is the part that actually prevents the 2am surprise. We migrate a copy of the data against the new system's real constraints, not a sample that happens to be clean, and count the failures by category before anyone commits to a date. The categories are predictable once you have done this a few times: nulls where the old system allowed them and the new one does not, duplicate customer records that accumulated over a decade of manual entry, and encoding mismatches where old Latin-1 text lands in a UTF-8 column as garbage the moment nobody was looking for it.

The other half is preserving identity. If a record's ID changes during the move, every foreign key pointing at it breaks unless there is a translation table mapping old IDs to new ones, and a decade of linked history quietly orphans itself. We decide the cutover strategy, big-bang, a parallel run, or phased by tenant or region, against how much downtime the business can actually absorb, and we rehearse the rollback before the real date arrives rather than improvising one under pressure.

What you get

A field mapping between old and new schema

Written down, including the fields that do not survive the move unchanged.

A dry run against a copy of the new system

With failures counted and categorized before the real cutover, not discovered during it.

Deduplication and cleanup of records

That accumulated inconsistencies over years, agreed with you rather than decided silently in a script.

An ID and foreign key strategy

That keeps linked history intact, or a translation table where IDs have to change.

A reconciliation report

Row counts, checksums, and a list of what did not migrate and why.

A cutover plan with a defined rollback point

Big-bang, parallel run or phased, chosen against how much downtime the business can absorb.

A handled write-freeze window

So nothing written during cutover gets lost between the old system and the new one.

The migration scripts themselves, handed over

So the move is repeatable rather than a one-off nobody else can rerun.

When this fits, and when it does not

A good fit

  • You are moving from one system to another, a legacy database, a spreadsheet, an old CRM, and the destination already exists or is being built alongside this.
  • History matters: past records, audit trails or linked data have to survive the move intact, not just the current-state rows.
  • The old data is messy in ways nobody has fully catalogued yet: duplicates, inconsistent formats, years of manual edits.
  • You need a dry run and a real reconciliation report before committing to a cutover date, not a script run once and hoped for.
  • The move has a defined end: once the records are in the new system and verified, this project is done.

Not a good fit

  • What you need is a live, ongoing exchange between two systems that both keep running, not a one-time move. That is API integration.
  • The destination system does not exist yet and the application logic still needs to be built or rewritten. Build or modernize that first, then migrate the data into it once it exists.
  • The data is small and clean enough that copying it by hand or through a spreadsheet import genuinely takes less time than scoping a migration project. Do that instead.
  • You need a new interface for people to look at the data afterward, and that interface does not exist either. That is internal tools, on top of or instead of a migration.

How it runs

  1. 01

    Map the schemas

    Old to new, and list every field that does not survive the move unchanged.

  2. 02

    Run a dry run against a copy of the destination

    With real constraints turned on, and categorize every failure it produces.

  3. 03

    Resolve the failure categories

    Nulls, duplicates, encoding, orphaned foreign keys, decided with you, not invented by a script.

  4. 04

    Decide and rehearse the cutover

    Strategy and rollback point agreed and tested before the real date, not improvised on it.

  5. 05

    Migrate, reconcile and hand over

    Row counts checked against the source, scripts handed over so the move is repeatable.

Questions we get

Will this lose any history?

No, that is the point of the ID and foreign key strategy and the dry run. We identify what would break before the real migration runs, not after, and history that would otherwise orphan gets a translation table instead of being silently dropped.

What if some old records do not fit the new system's rules?

They get categorized during the dry run and the handling gets agreed with you: fixed, flagged, or excluded with a written reason. We do not invent placeholder values under deadline pressure to force a row through validation.

How long does the cutover actually take?

Depends on data volume and the strategy chosen. A phased or parallel-run migration can avoid downtime entirely at the cost of running longer; a big-bang cutover is faster but needs a write-freeze window. We size and state this honestly before you commit to a date.

Can you migrate from a specific old system we use?

Usually, if we can read its data, through a direct database connection, an export format, or its API. We say plainly during scoping if a particular source cannot be read reliably rather than discover it mid-project.

Got records that need to move without disappearing?

Tell us the old system, the new one, and roughly how much data. An engineer reads it and tells you what in the old data is going to fight you.