The B2B client had ~4,000 URLs, three legacy CMS generations, and a launch date tied to a conference. Rankings were not optional.

The playbook (compressed)

  1. Inventory with crawl + logs + GSC. We tagged money URLs explicitly—about 180.
  2. Mapping one-to-one where possible; consolidation where thin. No “catch-all” redirect to home.
  3. Staging crawl of redirects with Link header checks and hreflang where EU mattered.
  4. Release in waves: templates first, long tail second, monitoring after each wave.

The two things that almost broke it

Parameterised legacy URLs hidden in affiliate bookmarks—404 spike until we caught the pattern.
XML sitemaps listing retired paths “for completeness,” confusing crawl budget for weeks.

Where this breaks down

When marketing rewrites slugs for “brand” post-migration without a map. When nobody owns GSC during cutover week.

Our read

Migrations are change management. We treat them like payments systems: rehearse, measure, roll back a wave if signals move wrong.