A CMS migration rarely fails because the export did not run. It fails because you learn too late what “correct” means: which pages must keep their URLs, which fields are mandatory, which embedded assets are missing, and which content types do not map cleanly to the new model.
A dry run is a rehearsal that makes those problems visible while you still have time and attention to fix them. Done well, it also produces artifacts you can reuse for the real launch: a runbook, a QA checklist, and a list of known exceptions with owners.
This guide describes a straightforward approach for small teams migrating between CMSs (or from a CMS to a new site architecture). It is intentionally light on tooling. The goal is process and learning, not a perfect one-off script.
Why dry runs matter
A migration dry run is not just “try the import once.” It is a controlled test that answers specific questions:
- Completeness: Did all intended items migrate (pages, posts, authors, categories, media)?
- Correctness: Are fields mapped properly (titles, bodies, SEO metadata, dates, relationships)?
- Stability: Can you repeat the process and get the same result without accumulating duplicates or drift?
- Operational readiness: Can someone other than the person who built the migration run it using documentation?
- Risk discovery: Which edge cases will require manual steps, and how many are there?
The best outcome of a dry run is not “it worked.” It is a clear list of what still needs decision-making: content model changes, redirect rules, editorial cleanup, or acceptance criteria.
Define “done” before you export
Dry runs fail when teams treat them like a vague experiment. Define success criteria that you can measure, even if imperfectly. You are building a shared definition of “good enough” for launch.
A simple acceptance criteria set
- Counts: For each content type, migrated count matches source count within an agreed tolerance (for example, excluding archived items).
- Field mapping: A named list of fields must match (title, slug, body, featured image reference, canonical URL, SEO title, SEO description).
- URL behavior: A defined set of high-traffic URLs must either remain identical or be redirected.
- Media integrity: Media referenced by migrated content is present and accessible in the destination.
- Editorial workflows: Draft vs published state behaves as intended, including author attribution where relevant.
Keep acceptance criteria short. If you cannot test it during a dry run, it is not an acceptance criterion. Put “nice-to-have” checks into a later QA phase.
Build a migration runbook
A runbook is the difference between a migration that lives in one person’s head and one that can be repeated and improved. It should be readable by a teammate who did not build the migration.
At minimum, your runbook should capture: prerequisites, the sequence of steps, inputs and outputs, where logs live, and how to validate results. If you use scripts or a “generator program,” describe what it does and what data it expects rather than embedding large code listings.
Migration Dry Run Runbook (conceptual)
1) Freeze scope: list content types + date range + excluded sections
2) Export: source snapshot identifier + storage location
3) Transform: mapping version + rules (slug rules, HTML cleanup, taxonomy mapping)
4) Import: destination environment + idempotency strategy (upsert keys)
5) Validate: automated checks + manual sampling plan
6) Report: issues list + owner + severity + next dry run date
Tip: Version your mapping decisions, even if you do it in a simple document. “Mapping v3” is meaningful when you are comparing results across dry runs.
Execute the dry run
A useful dry run is structured like a small release: you scope it, run it, verify it, and capture learnings. Here is a practical sequence that works for many teams.
Step-by-step execution
- Pick a realistic slice: Include the most complex content types and a range of ages (old pages often contain weird markup).
- Snapshot the source: Record a clear “as of” reference so results are reproducible.
- Run export, transform, import: Capture counts at each stage (exported, transformed, imported).
- Run automated validations: Even lightweight checks catch a lot: missing required fields, empty bodies, invalid dates, duplicate slugs.
- Do manual sampling: Review a small, representative set: top landing pages, long-form posts, pages with tables, pages with embeds.
- Record exceptions: Every exception should become either a mapping rule, a cleanup task, or an explicit launch exception.
Concrete example: A small training company migrates from a legacy CMS to a modern headless CMS. In their first dry run, 1,200 articles import successfully, but 140 are missing downloadable PDFs because the legacy system stored files in a separate library with inconsistent naming. The dry run turns a vague fear (“assets might break”) into an actionable plan: add an asset reconciliation step, define a rule for resolving duplicates, and create a manual queue for the 12 PDFs that have no reliable match.
Key Takeaways
- Define migration “done” using measurable acceptance criteria: counts, mappings, URL behavior, and media integrity.
- Write a runbook that someone else can follow. It turns a one-time effort into a repeatable process.
- Use dry runs to create decisions: mapping rules, cleanup tasks, and documented exceptions.
- Track issues by severity and owner so each dry run reduces risk, not just adds data.
Analyze results and iterate
A dry run creates a lot of “signals.” Without a simple way to triage, you risk getting stuck in debates about edge cases while real problems stay unresolved.
Use a lightweight issue taxonomy:
- Blocker: Must be fixed before launch (broken redirects, missing required fields, widespread formatting loss).
- Major: Fix if time permits; otherwise define a workaround (some media missing, imperfect taxonomy mapping).
- Minor: Cosmetic issues with low impact (spacing, non-critical metadata mismatches).
- By design: A known difference that is acceptable (for example, removing obsolete fields).
Then, schedule the next dry run with a specific purpose. “Dry run #2 validates new redirect rules and PDF reconciliation” is much better than “run it again.” If you cannot explain what you are validating, you are not iterating, you are re-running.
Common mistakes
- No scope control: Migrating “everything” first creates noise. Start with a slice that contains complexity, then expand.
- Skipping URL decisions: Teams often postpone redirects, then realize too late that slugs changed or the new CMS enforces uniqueness differently.
- Untracked manual fixes: Editing the destination by hand during a dry run hides repeatability problems. If you do manual fixes, log them as steps or backlog items.
- Only checking counts: Counts can match while meaning is wrong (authors swapped, taxonomy missing, HTML stripped). Pair counts with sampling.
- No idempotency plan: If re-importing creates duplicates, you cannot safely iterate. Decide on stable keys (source IDs, canonical URLs) and “upsert” behavior.
When NOT to do this
Dry runs are high leverage, but not always the right first step. Consider postponing a full dry run if:
- Your content model is still moving daily: If fields and relationships are unsettled, run a short mapping workshop first, then dry run.
- You do not have an environment to import into safely: A dry run should not endanger production data. Set up a staging space or isolated project.
- You are migrating a tiny site: For a site with a few dozen pages, a manual rebuild plus redirect mapping might be lower risk than building migration tooling.
- You cannot allocate time for analysis: A dry run without triage time is just a slow way to discover problems you will not fix.
A copyable dry run checklist
Use this as a starting point and tailor it to your CMS and content types:
- Scope: List content types, count targets, exclusions, and a source snapshot reference.
- Mappings: Confirm field mapping document is current (versioned), including slug rules and taxonomy strategy.
- Keys: Define stable identifiers for upsert and de-duplication.
- Export checks: Verify export contains required fields, media references, and relationship data.
- Transform checks: Validate required fields are non-empty; normalize HTML; handle special blocks.
- Import checks: Confirm imported counts; review error logs; confirm retries do not duplicate items.
- QA sampling: Review at least 20 items across templates, including the “weird” ones.
- URL plan: Test a set of critical URLs and confirm redirect rules or stable slugs.
- Issue log: Record each issue with severity, owner, and whether it becomes a rule or a manual task.
- Next run: Define what must improve in the next dry run and how you will measure it.
Conclusion
A CMS migration dry run is a learning mechanism. It converts uncertainty into a plan: what to automate, what to clean up, what to accept, and what to delay.
If you keep your acceptance criteria measurable, document a runbook, and iterate with intent, your final cutover becomes a predictable execution step instead of a stressful discovery process.
FAQ
How many dry runs should we do?
Plan for at least two: one to discover issues and one to confirm fixes. Complex sites often benefit from three to four smaller runs, each validating a specific set of improvements (redirects, assets, taxonomy, formatting).
How big should the dry run scope be?
Start with a representative slice, not everything. Include your hardest content types and your most business-critical pages. Expand scope once your pipeline is stable and repeatable.
Is it okay to manually fix content during the dry run?
Yes, but treat manual fixes as data. Record what you changed and why, then convert repeated fixes into mapping rules or source cleanup tasks. Avoid “silent” edits that you cannot reproduce.
What metrics should we report after each dry run?
At a minimum: item counts by type, number of errors/warnings, number of sampled items reviewed, and a categorized issue list (blocker/major/minor/by design). If URLs matter, add redirect pass rate for a defined URL set.