This is a worked example, not a client result
It shows the investigation order, the finding format and the reasoning we use on real projects, built from a pattern we encounter repeatedly. The figures are illustrative. We publish client numbers only when they are real, measured, and the client has agreed to them being published.This is a worked example. It shows how we review a migration and what we look for, built from a pattern we encounter repeatedly. The figures are illustrative. We publish client numbers only when they are real, measured and the client has agreed to them being published.
Executive summary
A retailer was six weeks from a replatform. The engineering team had produced a redirect map covering 96% of old URLs, and the project board recorded that as done.
We rebuilt the same question as "what percentage of the value is covered". The answer was 41%. The map had comprehensively covered the long tail — where URL patterns were regular and easy to match — and missed the category pages, bestsellers and editorially-linked pages that produced most of the organic revenue, because those had irregular legacy URLs that no pattern caught.
Business problem
The company had lost significant organic traffic in a previous migration three years earlier and had never fully recovered. The brief was explicitly "do not let that happen again", but the project was being managed on a completeness metric that could not detect the failure mode.
Baseline
We built one list of every old URL with what it was worth:
- Full crawl of the old site.
- Search Console pages and queries, 16 months.
- GA4 landing pages, sessions, conversions and revenue.
- Backlink export, by target URL.
- Internal conversion value per page from the client's own reporting.
Each URL got a composite score from organic clicks, conversions, revenue, referring domains and query value. Then we sorted by score and cut into deciles.
This is the whole method, and it takes about three days. It is the difference between a redirect map and a protection plan.
Investigation
- Score every URL. Not classify — score. A URL that produced £40,000 of revenue and one that produced nothing are not both "a product page".
- Test the proposed map against the scored list. Programmatically, not by sampling. For each scored URL: is there a destination, is it a single hop, is it a 301, and is the destination a 200?
- Report coverage weighted by value, per decile. The decile view is what makes the failure visible. Aggregate coverage of 96% and top-decile coverage of 38% are the same map.
- Inspect what the gaps had in common. Almost all of them were legacy URLs from two platforms ago — irregular paths that no pattern rule matched, which is precisely why they had accumulated links and authority over the years.
- Check the rest of the migration surface: metadata, canonicals, structured data, internal links, sitemaps, robots on both environments, and analytics continuity.
Evidence
| Check | Result |
|---|---|
| Old URLs crawled | 54,300 |
| Covered by proposed map (by count) | 96.1% |
| Covered by proposed map (by value score) | 41.4% |
| Top-decile URLs with no destination | 2,140 |
| Redirect chains of 2+ hops | 3,880 |
| 302s where a 301 was intended | 1,410 |
| Staging indexable at time of review | Yes — robots.txt allowed all |
| Conversion tracking on new build | Present, firing twice on checkout |
Two of those findings — indexable staging and double-firing conversions — had nothing to do with redirects and would each have caused their own problem.
Root cause
The map was generated by pattern-matching the new CMS export against the old one. Pattern matching works where URL structure is regular. The most valuable pages on this site were the least regular, because they were the oldest.
The deeper cause was the metric. "96% of URLs covered" is a number that reassures a project board and cannot detect this failure. Nobody chose the wrong metric deliberately; it was simply the number the tooling produced.
Actions
- Rebuild the map from the value-scored list, highest decile first. Rules where a pattern genuinely exists; explicit pairs for the irregular legacy URLs. Acceptance: 100% destination coverage for deciles 1–3, single hop, 301, destination returns 200.
- Flatten every chain to a single hop. Acceptance: no scored URL resolves in more than one redirect.
- Convert intended-permanent 302s to 301s. Acceptance: crawl of the scored set returns no 302 except where a 302 is deliberate and documented.
- Close staging.
robots.txtdisallow plus HTTP authentication. Acceptance: staging returns 401 to an unauthenticated request. - Fix the duplicate checkout conversion before launch, not after, so the post-launch numbers are comparable to the pre-launch baseline.
- Carry metadata, canonicals and structured data across on the templates that carry the top three deciles. Acceptance: field-by-field staging crawl diff against production.
- Write launch-day pass/fail criteria and rollback triggers, agreed and signed off before launch week.
Implementation
Four weeks of the remaining six, running alongside the build. The redirect rules were tested on staging against the real scored URL list — not a sample — which is only possible because the list existed as a file rather than as a concept.
Launch day was a checklist with owners and pass/fail criteria, worked in real time. The rollback triggers were defined in advance, which meant the question on the day was "did criterion 4 fail" rather than "does anyone feel nervous".
Result
What we measure, and when:
- Share of scored URL value retained at day 30, against the pre-migration baseline. This is the headline number for any migration and it is the one we report.
- Redirect coverage and chain rate on the scored set, checked on launch day and again at day 3.
- Indexation of critical pages at day 7 and day 30.
- Analytics continuity — no gap, no duplicate conversions, so the before and after are actually comparable.
A short dip while the new URLs are recrawled is normal and expected. A sustained loss is not, and it is what this work exists to prevent.
What we learned
- Coverage by count is the wrong metric and it is the default one. Every migration should report coverage weighted by value, by decile. It takes a day of work to make possible.
- The most valuable URLs are usually the least regular. They are old, which is why they have links, which is why pattern rules miss them.
- A migration review always finds something that is not about redirects. Indexable staging and double-firing conversions would each have caused real damage on their own.
What happens next
Post-launch, the URL inventory and redirect rules become living documentation for the next change — which is usually only a year or two away. The clients who stop losing traffic to migrations are the ones who keep the scored inventory current rather than rebuilding it in a panic each time.
The data behind it
Redirect coverage before and after re-mapping, by URL value decile
Illustrative. Coverage counted by URL looked fine; coverage weighted by value did not.
- CMS-export map
- Value-scored map
View the data as a table
| Item | CMS-export map | Value-scored map | Change |
|---|---|---|---|
| Decile 1 (highest value) | 38% | 100% | +62% |
| Decile 2 | 44% | 100% | +56% |
| Decile 3 | 61% | 100% | +39% |
| Decile 4 | 79% | 99% | +20% |
| Decile 5 | 92% | 99% | +7% |
| Deciles 6–10 (long tail) | 99% | 99% | 0% |
Source: Illustrative reconstruction of the pattern this review follows