Moving the data is easy. Not losing anything is the job
Two systems never model the world the same way. One has a customer with many addresses; the other has an address with a customer attached. A migration is a translation, and translations are where meaning goes missing — quietly, in a field nobody checked, discovered three weeks later by somebody who needed it.
YOU ARE PROBABLY HERE BECAUSE
- everything worked until you migrated
- somebody else moved you and things are missing
- you need to move without the billing stopping
What I can do for you
Nobody should quote a migration before reading the source data. What is in there is always worse than the export suggests.
Source data assessment
Reading the system you are leaving — record counts, what is orphaned, what is duplicated, what is encoded wrongly, which relationships are already broken. Plus a field-by-field map of where each thing would land. You keep it, and it is what a real quote is built from.
Full migration
Extract, transform, load, verify. Run repeatedly against a clone until two consecutive runs agree, then cut over with a rollback that has been tested rather than assumed.
Zero-downtime migration
For systems that cannot stop — subscriptions billing, orders arriving, people logged in. The new system is populated and kept in step while the old one still runs, with a delta sync at cutover so nothing that happened during the move is lost.
Rescue a migration that went wrong
Someone has already moved and things are missing, duplicated or mangled. First job is working out what is recoverable from the old system and what has to be reconstructed. Do not delete the source.
Forty-five minutes, no charge.
Bring record counts and what you are moving from.
How the data actually gets across
Extract, transform, load — the same three stages whatever the systems are. The middle one is where the work is, and where a careless migration silently drops things.
Database migrations
Different storage models make different assumptions. The translation between them is a set of decisions, not a script you can download.
Relational to relational
MySQL to PostgreSQL, SQL Server to MySQL, or one schema to a better one. Looks simple and is not — data types, collations, auto-increment behaviour and date handling all differ in ways that corrupt quietly rather than failing loudly.
- Type and precision mapping
- Character set and collation
- Constraints and foreign keys
- Stored procedures and triggers
Document to relational
MongoDB or a document store into MySQL. Nested documents have to become tables, and every nested array is a decision: its own table, a JSON column, or flattened. Documents also vary in shape between records, so the schema has to accommodate what actually exists rather than what the docs describe.
- Normalising nested structures
- Inconsistent fields between documents
- Array and embedded object handling
- Generating relational keys
Relational to document
The reverse, and it is a modelling exercise rather than a copy. Joins become embedded documents, which means deciding what to duplicate and accepting the update cost that comes with it.
- Denormalising joins deliberately
- Choosing embed against reference
- Duplication and update strategy
- Access patterns first, schema second
Legacy and proprietary
Flat files, XML, Access databases, spreadsheets maintained by hand for a decade, and systems whose only export is a CSV with inconsistent columns. Frequently the data was never validated, so the migration is also the first audit it has ever had.
- Parsing inconsistent exports
- Inferring structure from the data
- Human-entered values needing repair
- Scraping where no export exists
WordPress and WooCommerce migrations
Each of these is a different problem with different things that go missing.
Moving from another CMS, a hosted platform or a bespoke system. Content, structure, taxonomy and URLs mapped so the new site is not a fresh start that loses ten years of accumulated search value.
Content, forms and tracking moved out of a closed builder into something you own. The awkward part is rarely the pages — it is keeping the form submissions, contact history and campaign attribution working after the site no longer lives inside the marketing platform.
Live subscribers moved with billing uninterrupted — schedules reconstructed from payment history rather than trusted from an export, and payment tokens carried where the gateway allows. More on subscriptions →
Products, variations, attributes, categories, pricing rules and stock. The awkward parts are variable products whose options do not map cleanly and pricing logic that lived in the old platform's own rules engine.
Historical orders with their line items, totals, tax, shipping and status. These have to reconcile against your accounts afterwards, which makes them less forgiving than most content.
Accounts, addresses, order history and roles. Passwords are hashed differently by different systems, so either everyone resets or the old hash is verified once at next login and re-hashed transparently. The second is almost always worth building.
Posts, pages, custom types, taxonomies, metadata and relationships between them. Plus a redirect map from every old URL to its new home, which is the difference between keeping your rankings and starting again.
Images, documents and video moved with their references rewritten so nothing points at the old server. Frequently the biggest single part of a migration by size, and the part most often left until it becomes urgent.
Moving to a new theme, or off a page builder, where the content is entangled with the presentation. Extracting the actual content from builder markup is its own exercise and rarely fully automatable.
Splitting one site out of a network, or bringing several together. User tables are shared in a network and separate outside one, which is where most of the difficulty lives.
Moving hosting without downtime — DNS lowered in advance, files and database synced, a final delta at cutover, old server kept warm. More on hosting →
What goes wrong
Every one of these I have seen, and several I have been called in to repair after somebody else.
Encoding corruption
Accented characters, currency symbols and emoji arriving as question marks or mojibake, because the source, the export and the target disagreed about character sets. Usually noticed weeks later, by which point new content is mixed in with the damage.
Relationships silently broken
Records arrive but their connections do not. Orders with no customer, products in no category, media attached to nothing. The counts match, so the migration looks successful.
Duplicates from a re-run
An import that fails halfway and is run again from the start, producing two of everything. This is what idempotency prevents, and it is the most common cause of a migration needing to be undone.
Everything that happened during the move
Orders placed, accounts created and content edited between the export and the cutover, all lost because nobody planned a delta sync.
URLs not mapped
Content arrives, addresses change, no redirects. Rankings accumulated over years disappear within weeks and the cause is not obvious to anyone but a developer.
The source deleted too early
The old system decommissioned before the new one has run for a full cycle. Keep it read-only for months. It costs almost nothing and it is the only real safety net.
Where this has been done
ProgressiveChristianity.org and Progressing Spirit
Millions of records and thousands of live subscribers moved with payments running throughout. Existing database corruption was repaired first, so the migration did not faithfully reproduce a decade of mess. Zero interrupted payments, and the accounts reconciled.
Millions of records
live subscribers · no interruption
2022 — 2026
Sparketh
Rebuild including an order migration, an LMS restructure and a move off Paid Memberships Pro onto WooCommerce Subscriptions.
Orders · subscriptions
LMS restructure
2025 — 2026
International Cinema Lighting Society
Subscriptions imported from a third-party system without interrupting payments, across a six-tier membership running in nine languages.
Third-party import
multilingual membership
via Digital Silk
aimacademy.online
Migration to a new theme on a live subscription platform, with the content extracted from the old presentation layer and a list of long-standing faults resolved along the way.
Theme migration
live subscription site
What this does not include
Guaranteeing perfect data
If the source is wrong, the migration moves something wrong. I will show you what I find and repair what is repairable, but I cannot invent what was never recorded.
Deciding what to keep
Whether fifteen years of old orders should come across is a business question. I will tell you what each option costs in time and complexity.
Redesigning while migrating
Both at once doubles the surface area and makes it impossible to tell which change broke something. Sequential is cheaper, even when it feels slower.
Working without the source
If the old system is already gone and there is no backup, there is nothing to migrate. Please do not decommission anything until the new system has run a full cycle.
Questions I get asked
How much downtime will we have?
For a normal content or catalogue migration, a short read-only window at cutover — usually under an hour. For subscriptions or anything still taking orders, none: the new system is populated in advance and kept in step, with a delta sync at the switch. Zero downtime costs more, and for a shop it usually pays for itself in a single afternoon of not being closed.
Will our customers have to reset their passwords?
Not necessarily. Password hashes differ between systems, but the old hash can usually be stored and verified once at the customer's next login, then transparently re-hashed. They log in as normal and never know. Where the old system used something unrecoverable, a reset is unavoidable and I will tell you before we start.
Can you migrate from a system with no export?
Usually. Direct database access is easiest, an API is fine, and where neither exists the data can often be extracted from the running site itself. It is slower and messier, and it is worth knowing that before you assume you are locked in.
What about our SEO?
A redirect map from every old URL to its new one, built before the move rather than reconstructed after complaints. Structure and metadata carried across, and Search Console watched for a few weeks afterwards. Migrations that lose rankings almost always lost them here.
Someone else migrated us and things are missing. Can you fix it?
Often yes, provided the old system still exists — which is the first thing to check and the reason I say never to delete it early. What is recoverable comes from the source; what is not has to be reconstructed, and I will be honest about which is which before quoting.
How do we know nothing was lost?
Counts reconciled by record type, financial totals compared against the source, and a sample of real records checked field by field — including the awkward ones you nominate, because you know which customers matter. If the verification does not agree, we have not finished.
Tell me what you are moving from and roughly how much
Record counts and the name of the old system are usually enough for me to say whether this is a two-week job or a two-month one.