references/migration-runbook.md
# Migration Cutover Runbook
A step-by-step runbook for the day of a content migration cutover. Pair this with `launch-runbook` for general launch protocol.
The runbook is read by tense people watching the clock. Optimize for clarity.
---
## Roles
Assign these before the day:
| Role | Responsibility | Person |
|---|---|---|
| Migration lead | Calls the cutover, makes go/no-go decisions | |
| Tech lead | Executes DNS and redirect changes | |
| QA lead | Runs verification scripts and manual checks | |
| SEO lead | Monitors search and indexing | |
| Comms lead | Sends notifications, updates status page | |
| Support lead | Watches tickets, escalates user reports | |
| Backup decision maker | Authorizes rollback if needed | |
---
## T-7 days: prep
- [ ] Inventory verified complete
- [ ] URL map signed off by SEO and content
- [ ] Destination tested in staging
- [ ] Sample of 50 redirects verified
- [ ] Rollback plan documented and rehearsed
- [ ] Cutover date and window communicated to all stakeholders
- [ ] Support team briefed on common questions
- [ ] DNS TTL lowered to 300 seconds (5 minutes)
- [ ] Monitoring dashboards built and tested
- [ ] Search console verified for both old and new domains (if domain change)
---
## T-1 day
- [ ] Final inventory pull (any new content added since the freeze?)
- [ ] Final URL map review
- [ ] Backup of source platform (full, restorable)
- [ ] Test rollback procedure in staging
- [ ] Confirm everyone on the team is available during the window
- [ ] Status page draft prepared
- [ ] Internal comms draft prepared
- [ ] Customer comms draft prepared (if applicable)
---
## T-2 hours
- [ ] All stakeholders in the cutover channel (chat or call)
- [ ] Status: source platform writeable lock (no new content during cutover)
- [ ] Final smoke test on staging
- [ ] Final confirmation: GO or NO-GO
NO-GO triggers:
- Critical bug found in destination
- Key person unavailable
- Source data integrity issue
- External factors (e.g., source platform outage)
If NO-GO, reschedule. Don't push through.
---
## T-0: cutover
Time-box each step. If a step takes 2x its expected duration, pause and assess.
### Step 1: Final source backup
Time: 5-15 minutes depending on volume.
```
[Specific backup commands or steps]
```
Verify backup integrity. Continue only on success.
### Step 2: Deploy destination to production
If the destination has been on staging only:
```
[Deploy commands]
```
Verify the destination is responding correctly on its production address (which may not yet have DNS pointed at it).
### Step 3: Deploy redirect rules
The redirect rules go on whatever the source platform uses to redirect (htaccess, edge worker, CDN rule, server config).
```
[Deploy redirect rules]
```
Test 5 redirects manually:
```bash
curl -I https://oldhost.com/path1
curl -I https://oldhost.com/path2
# Expected: 301 to https://newhost.com/path1
```
### Step 4: DNS cutover (if domain change)
Update DNS to point the new domain to the destination.
```
[DNS update steps]
```
Verify resolution from multiple regions:
```bash
dig +short newhost.com @8.8.8.8
dig +short newhost.com @1.1.1.1
```
DNS propagation usually completes within minutes (with the TTL lowered earlier). Some resolvers may lag.
### Step 5: Submit new sitemap
```
[Submit to search engines]
```
For Google: search console → sitemaps → submit.
For Bing: webmaster tools → sitemaps → submit.
### Step 6: Update internal references
If the source has links to itself (or hardcoded references), update the source to point at the new URLs (helps tools that haven't picked up the redirects yet).
If the source is being decommissioned entirely, this step is moot.
### Step 7: Update integrations
External integrations that reference URLs:
- Email templates with absolute URLs
- Social profiles with bio links
- Partner sites with deep links
- Marketing automation
- Analytics goals (URL-based goals may break)
- Saved CRM links
Update each. Document in the comms plan.
---
## T+15 minutes: smoke test
- [ ] Top 50 URLs from inventory each return correct status
- [ ] Redirects return 301 (not 302)
- [ ] Critical user flows work (signup, contact form, checkout if applicable)
- [ ] Search engines can crawl (robots.txt, sitemap)
- [ ] Analytics is firing on new pages
- [ ] Monitoring is showing the new endpoints
If any check fails: triage. Fix forward if simple; rollback if complex.
---
## T+1 hour: stakeholder check-in
- [ ] Status page updated
- [ ] Internal comms sent
- [ ] Customer comms sent (if applicable)
- [ ] Support has not seen unusual ticket volume
- [ ] Real-time analytics shows expected traffic patterns
---
## T+24 hours
- [ ] Search console shows crawls of new URLs
- [ ] Search console "Indexing" tab not showing major issues
- [ ] No spike in 404s or 5xx errors in logs
- [ ] Backlink-bearing pages confirmed to redirect correctly
- [ ] Monitoring dashboards normal
- [ ] No major customer reports
---
## Rollback decision criteria
Rollback if:
- Critical functionality broken on the destination
- Significant data corruption discovered
- Security issue introduced by the migration
- Search indexing catastrophically failing (rare; usually fixable forward)
Do NOT rollback for:
- Normal traffic dip (expected, recovers)
- Individual broken redirects (fix forward)
- Minor visual issues (fix forward)
- Slow pages (fix forward)
Rollback procedure:
### Step R1: Reverse DNS (if domain change)
```
[Revert DNS]
```
### Step R2: Disable redirect rules
Take redirects offline so source URLs serve source content again.
```
[Disable redirects]
```
### Step R3: Unlock source platform
Remove the writeable lock on the source.
### Step R4: Restore from backup if needed
If data corruption: restore. See `backup-and-disaster-recovery`.
### Step R5: Comms
- [ ] Status page updated (rolled back)
- [ ] Internal comms (rolled back, next steps)
- [ ] Customer comms if applicable (apology, next steps)
### Step R6: Schedule retrospective
Within 5 business days. See `after-action-report`.
---
## First-week monitoring
Daily checks:
| Metric | Target | Action if off |
|---|---|---|
| Top-10 page traffic | Within 80% of baseline | Investigate redirects, check indexing |
| Conversion rate | Within 90% of baseline | Investigate UX changes, check analytics implementation |
| 404 rate | Below 1% of requests | Add missing redirects |
| Crawl errors | Decreasing | Check robots.txt, sitemap, canonicals |
| Indexing rate | Increasing toward old volume | Submit URLs manually if stalled |
| Search rankings (top 20 keywords) | No cliff drops | Investigate canonicals, redirects, content parity |
---
## First-month monitoring
Weekly checks:
| Metric | Target |
|---|---|
| Total organic traffic | Recovering toward baseline (typically 4-8 weeks) |
| Indexed pages | At or above pre-migration count |
| Backlink-pointed-to pages | All resolving correctly |
| 410 vs 404 ratio | Pages that should be gone return 410, not 404 |
---
## After 90 days
- [ ] Full performance review vs pre-migration baselines
- [ ] Document what worked, what didn't (after-action report)
- [ ] Decommission source platform if not already done
- [ ] Renew source domain (long-term, even if not in use, to preserve redirects)
- [ ] Archive the migration documentation for future reference
---
## Common surprises
**Backlinks pointing to URLs not in inventory.** Old marketing pages, archived posts, removed-but-still-linked content. Add to the map after cutover.
**Trailing slash inconsistencies.** Server treats `/page` and `/page/` differently. One redirects, the other 404s. Fix with a normalizing redirect.
**Search engines slow to update.** Old URLs still appear in search for weeks. Normal. Don't redirect to homepage to "speed it up."
**Analytics goals broken.** URL-based goals don't match new URLs. Update the goals; backfill if possible.
**Hardcoded absolute URLs in email templates.** Old links in transactional emails. Update templates.
**Schema.org or canonical tags pointing wrong.** Crawlers follow canonical even after redirects. Verify canonical tags on the destination point to the destination.
**Sitemap caching.** Some platforms cache sitemaps aggressively. Force a refresh.
**robots.txt forgot the new sitemap.** Add the new sitemap to robots.txt.
---
## Post-cutover comms template
### Internal (to team)
Subject: Migration cutover complete
```
The migration to [new platform/URL/etc.] is complete as of [time].
Status:
- [N] redirects in place
- All critical flows verified
- Monitoring shows expected traffic patterns
We'll watch closely over the next 24 hours and the first week. Report any issues in [channel].
Next steps:
- [Specific monitoring action]
- [Specific follow-up]
Thanks to everyone who made this happen.
```
### External (to users, if applicable)
Subject: We've moved [or rebranded, or restructured]
```
Hi [name],
[Brief reason for the change.]
What this means for you:
- [Specific user-facing change 1]
- [Specific user-facing change 2]
Old links should redirect automatically. If you find a broken link, please let us know at [contact].
Thanks for your patience as we make this transition.
```
---
## Document the result
Within a week of cutover, write up:
- What was migrated
- What worked
- What broke and how it was fixed
- What we'd do differently
- Lessons for the next migration
This becomes input to `after-action-report` and to future migration playbooks.
SKILL.md
---
name: content-migration
description: "Move content between platforms, domains, or URL structures while preserving SEO equity, user bookmarks, and integrations. Use this skill when planning a CMS migration, replatforming, consolidating sites, changing URL structures, or merging content from multiple sources. Triggers on content migration, replatform, CMS migration, domain migration, URL restructure, redirect map, site merge, content consolidation, migration plan, post-migration drop. Also triggers when planning a launch that involves moving existing content."
category: cross-cutting
catalog_summary: "Platform migrations with SEO equity preservation"
display_order: 2
---
# Content Migration
Move content from one platform, domain, or URL structure to another without breaking SEO, user bookmarks, or downstream integrations. Stack-agnostic.
---
## When to use
- Migrating from one CMS to another (e.g., WordPress to a headless setup)
- Consolidating multiple sites into one
- Splitting one site into multiple
- Changing URL structures
- Domain migration (one brand to another, mergers, rebrands)
- Migrating from a custom build to a platform (or vice versa)
- Content audit-driven cleanup as part of a larger move
## When NOT to use
- A net-new site with no existing content (no migration needed)
- Single-page edits or content updates within an existing site (use `content-and-copy`)
- Performance or technical SEO improvements without URL changes (use `seo-technical`)
- Routine content audits (use `seo-content-audit`)
---
## Required inputs
- The source: current platform, current URL structure, current content inventory
- The destination: target platform, target URL structure, target capabilities
- The reason for migration (drives priority of what to preserve)
- Constraints (timeline, budget, downtime tolerance)
- Stakeholders (SEO, content, dev, comms, support)
---
## The framework: 6 phases
Every content migration follows the same arc. Skipping a phase is how migrations go badly.
### Phase 1: Inventory
You can't migrate what you don't know. Build a complete map of what exists.
For each piece of content:
- URL
- Title
- Content type (article, landing page, product, doc, etc.)
- Status (live, draft, archived, scheduled)
- Last modified
- Author or owner
- Traffic (last 12 months), or state the gap per the data-availability rule
- Backlinks (top external referrers)
- Internal links pointing to it
- Embedded assets (images, video, downloads)
Pull from: CMS export, XML sitemap, server logs, analytics, search console, backlink tool.
The inventory is a spreadsheet. It's the source of truth for the rest of the migration.
### Phase 2: Audit and decide
For each piece of content, decide:
- **Keep:** migrate as-is
- **Update:** migrate with edits (refresh, expand, fix)
- **Merge:** combine with another piece, redirect both old URLs to the new
- **Redirect:** don't migrate; redirect to a related page
- **Delete:** don't migrate, no redirect (use sparingly; only for clearly low-value pages)
This is `seo-content-audit` work. The migration is the time to do it; not the time to skip it.
For each "Update" or "Merge," document the specific changes.
### Phase 3: Map URLs
The URL map is the most important migration artifact.
| Old URL | New URL | Status code | Reason |
|---|---|---|---|
| /old/path | /new/path | 301 | Direct equivalent |
| /old/page-1, /old/page-2 | /new/merged | 301 | Merged content |
| /old/deprecated | /related/replacement | 301 | Closest replacement |
| /old/junk | (none) | 410 | Intentionally gone |
Rules:
- 301 (permanent redirect) for content that has a new home
- 410 (gone) for intentionally deleted content
- Avoid 404 (not found) where 410 is more accurate
- Never redirect everything to the homepage; specific is always better
- Map every URL with traffic or backlinks; lower-priority URLs can be patterned
For domain migrations, use a 1:1 path mapping by default (`old.com/page` → `new.com/page`) with specific overrides where structure changes.
### Phase 4: Build and stage
Build the destination. Don't skip a staging environment.
- Set up the new platform with the new content
- Implement the URL map (most platforms support a redirect file or rule)
- Verify a representative sample of redirects work
- Test critical user flows (signup, purchase, contact)
- Validate analytics, monitoring, and integrations
- Test from search engine perspective: robots.txt, sitemap, canonicals
If possible, get the destination crawled by Google before the cutover, so it's already indexed when redirects flip.
### Phase 5: Cut over
The actual switch. Plan it like a launch (and use `launch-runbook` alongside this skill).
Pre-cutover:
- Comms to stakeholders (date, expected impact)
- Comms to users if downtime expected
- Support team prepped for likely questions
- Lower DNS TTL the day before (1-3 days for safety)
- Backup of source platform (in case rollback is needed)
Cutover:
- Redirect rules go live
- DNS changes go live
- New sitemap submitted to search engines
- Old sitemap removed or updated
- Internal links audited and updated to point to new URLs (where possible)
- Status page or banner if user-visible disruption
Immediately post-cutover:
- Smoke test top 50 pages from the inventory
- Verify redirects are 301 (not 302)
- Verify search console for errors
- Watch real-time traffic for unexpected drops
- Watch error logs for missing assets, broken integrations
### Phase 6: Monitor and recover
The migration isn't done at cutover. The next 30-90 days reveal problems.
Watch:
- **Traffic:** expect a temporary drop (10-30% is common); should recover in 4-8 weeks. A persistent drop beyond that is a problem.
- **Indexing:** new URLs should be crawled and indexed. Check coverage in search console.
- **Rankings:** track top keywords. A position drop is normal; a position cliff is a sign of a redirect or canonical problem.
- **Backlinks:** check that linked-from-elsewhere pages still resolve to the right destination.
- **404s:** any URL getting 404s that should have been redirected? Add to the map.
- **User reports:** support tickets, social media. Are users finding their old links?
Common 30-day fixes:
- Add missed redirects from 404 patterns
- Update internal links you missed
- Re-submit sitemap if indexing stalls
- Investigate and fix any crawl errors
---
## Workflow
### Step 1: Set the scope
What's in scope? What's out? Write it down. Migrations expand if not bounded.
### Step 2: Build the inventory
Pull every URL, traffic, backlinks, internal links. The spreadsheet is the artifact.
### Step 3: Decide per piece
Keep, update, merge, redirect, delete. Document decisions.
### Step 4: Map URLs
The complete redirect map. Reviewed by SEO and content stakeholders.
### Step 5: Build the destination
In a staging environment. Real content (or representative content). Real redirects.
### Step 6: Test
- Sample of redirects (top 20 by traffic, top 20 by backlinks, edge cases)
- Critical flows (signup, checkout, contact)
- Analytics and monitoring
- Search-engine perspective (robots.txt, sitemap, canonicals)
### Step 7: Cut over
Following the cutover checklist. Have rollback ready.
### Step 8: Monitor
Daily for the first week. Weekly for the first month. Monthly through 90 days.
### Step 9: Document the result
What worked. What didn't. Lessons. (See `after-action-report`.)
---
## Failure patterns
**No URL inventory.** Migration team thinks they have everything. They don't. Old PDFs, archived posts, marketing landing pages with backlinks. Build the inventory.
**302 redirects instead of 301.** 302 is temporary. SEO equity doesn't reliably pass. Use 301 unless you have a specific reason.
**Redirecting everything to the homepage.** "We'll let users find their way." They won't. They'll bounce. Map specifically.
**Long redirect chains.** /a → /b → /c → /d. Each hop loses a little equity and adds latency. Collapse to /a → /d.
**Forgetting non-HTML URLs.** PDFs, images, downloads. They have URLs too. They have backlinks too. Include in the map.
**Forgetting query strings.** `/page?id=123` is a different URL than `/page`. Patterns or specific maps for query string variants.
**Ignoring trailing slashes.** `/page` and `/page/` are different to most servers. Pick one canonical form. Redirect the other.
**No staging.** The first time the migration runs is in production. Things break. Stage and test.
**Stage that's too different from production.** Different DNS, different CDN, different platform. Tests pass on staging, fail on production. Stage as close to prod as feasible.
**Leaving the source live.** Two sites serving the same content. Duplicate content, split equity, user confusion. Take down the source after confirming the destination is solid.
**Leaving the source domain unrenewed.** Domain expires, redirects break, traffic dies. Renew the source domain for a long time, even if you're not using it.
**Big-bang migration with no rollback plan.** Something goes wrong. Now what? Plan rollback before cutover.
**Cutover during a busy period.** End of quarter, holiday season, big campaign. Bad timing. Pick a quiet period.
**No comms.** Users find their bookmarks broken with no warning. Some won't come back. Communicate.
**Migration as a one-time event.** It's not done at cutover. Monitor for 30-90 days. Fix what surfaces.
**Treating migration as just a dev project.** SEO, content, support, comms all need to be involved. Cross-functional from day one.
---
## Output format
A migration plan document includes:
- **Scope:** what's in, what's out
- **Inventory:** the URL spreadsheet
- **Audit decisions:** keep, update, merge, redirect, delete
- **URL map:** old to new, with status codes
- **Architecture:** new platform setup, redirect implementation
- **Cutover plan:** the runbook for switch day
- **Rollback plan:** if it goes wrong
- **Monitoring plan:** what's watched, for how long
- **Comms plan:** internal and external
- **Owners and timeline:** who does what when
---
## If required data is unavailable
This skill's output depends on data, measurements, or tool results it cannot generate on its own. When a required input, tool, or data source is unavailable or unverifiable, the sanctioned output is the deliverable with the gap stated: what was needed, what was actually obtained or verified, and which parts of the output are affected. Fabricating, estimating, or interpolating a required number to complete the deliverable is never sanctioned. A stated gap is a complete answer.
---
## Reference files
- [`references/migration-runbook.md`](references/migration-runbook.md): Step-by-step runbook for cutover day, including pre-flight checks, the actual switch, immediate verification, and the first 24 hours of monitoring.