Skip to content
← All writing
Migrations1 July 2026Updated 7 October 20268 min read13 sources

How to build a redirect map for a site migration

A step-by-step method for listing every old URL, matching each one to the right new address, and testing the whole map before launch day.

By Mani Bharij, SEO & AI Search Consultant

In this postHover or tap a point
01020304050607

Chapter 011 min

Set up the spreadsheet before you collect anything

Most migration losses come from the redirect map. Old URLs get missed, pattern rules send pages to the wrong place, legacy redirects stack into chains, and nobody checks what the server returns until rankings start to slide. The map itself is not difficult to build. It takes care, a sensible spreadsheet and a test run before launch. This is the method I would use, from an empty sheet to a map you can sign off.

It assumes you already know what kind of move you are making and why the map matters. If not, start with the website migrations guide, which covers the types of migration and where the map fits in the wider plan.

Chapter 01 / 071 min

Set up the spreadsheet before you collect anything

Decide the columns first, so every URL lands in the same shape whichever source it came from. These are the columns I would use. Each one exists because someone later needs to filter or sort on it.

ColumnWhat goes in itWhy you need it
Old URLThe full old address, normalisedThe key for every lookup and every test
SourceWhere the URL was found: crawl, sitemap, analytics, Search Console, backlinks, logs, CMSShows which URLs only one source knew about
TemplateProduct, category, article, location, PDF and so onLets you write and check pattern rules per template
Clicks and sessionsOrganic clicks from Search Console and sessions from analyticsSets review priority
Linking domainsCount of referring domains from your backlink toolFinds deep pages with link value
New URLThe single destination, or blank if the page is retiredThe answer the developers build from
Match typeExact, pattern, manual, parent, or retireTells reviewers how much to trust the row
Status to serve301, 308, 404 or 410Makes retirements a decision instead of an accident
Owner and notesWho decided, and whyStops the same argument happening twice
Test resultStatus and final URL actually returned on stagingFilled in by the test run, never by hand
Redirect map columns and what each one is for
Chapter 02 / 071 min

Step 1: gather the old URLs from every source

Good starting points are your sitemaps, your server logs or analytics for the URLs with the most traffic, and your CMS, which can usually list every URL that hosts content.1 Add a full crawl and your backlink data to that. Each source misses something the others catch, and the URLs you miss are often the old ones with good links.

On a large site, pull Search Console page data through the Search Analytics API. A single API request returns up to 25,000 rows, with a default of 1,000, and you page through larger sets with the startRow parameter.2 Take the longest date range you can, because pages with seasonal traffic will not show up in the last three months.

Include images, PDFs and other downloads in the move too, since they may get search traffic or links of their own.1 They are easy to leave out because crawlers often skip them and analytics never records them as landing pages.

Before merging the lists, normalise every URL the same way: one protocol, one hostname, a consistent trailing slash, lower case if the old server treated case as equivalent, and tracking parameters stripped. Then remove duplicates and keep the Source column as a combined value, so a URL found by three sources shows all three.

Chapter 03 / 072 min

Step 2: match old URLs to new ones in three passes

Working in passes lets you clear most of the sheet quickly and spend your time on the rows that need judgement.

Pass one: exact matches from the data

Most CMS exports carry an identifier that survives the move: a product SKU, a post ID, an article slug. Join the old export to the new one on that identifier and you have a confident match for every item that exists on both sides. A shop selling garden furniture, for example, can match every product on SKU even if the product URLs change from /p/12345 to /garden-furniture/oak-bench. Mark these rows Exact.

Pass two: pattern rules for whole templates

Where a template has a clean pattern, one rule can cover thousands of rows. A blog moving from /blog/2019/04/post-name to /articles/post-name is the usual example. Write the rule, then apply it to the spreadsheet and check that every resulting new URL exists on the new site. Rows where the generated URL does not exist are your exceptions, and they go to the manual pass.

Know how your server handles the rule. On Apache, the plain Redirect directive matches a prefix and appends whatever follows it to the target, so a rule for /service also redirects /service/anything. RedirectMatch takes a regular expression for exact control. Apache also processes these directives in the order they appear, with the first match winning, so put specific one-to-one rules above broad patterns.3 Other servers have their own rules. On nginx, a rewrite with the redirect flag returns a temporary 302 and one with the permanent flag returns a 301, while the return directive takes the status code explicitly.4 Read the documentation for your server or platform before writing any patterns.

Pass three: manual review by priority

Sort what is left by clicks, then by linking domains. Every row with meaningful traffic or links gets a person deciding where it goes. This is where merged pages, renamed categories and rewritten guides are handled. Where several old pages have been consolidated into one new page, redirecting all of them to it is fine.1 Where a page has been split, send it to the new page that covers its main search intent, and link to the others from there.

Chapter 04 / 071 min

Step 3: decide what happens to pages with no equivalent

Every migration retires some pages: discontinued products, expired events, thin tag pages, old campaign landing pages. Each one needs an explicit decision in the Match type column. Redirecting many old URLs to one irrelevant destination such as the homepage can backfire, because Google might treat those redirects as soft 404s. Content you are not moving should return a 404 or 410.1

SituationWhat I would do
A product discontinued for good, with a category that sells close alternativesRedirect to that category, marked Parent
An old article with links, replaced by a newer article on the same subjectRedirect to the newer article
A page with links but no relevant successorReturn 410, and decide whether the topic is worth recreating
Thin or duplicate pages with no traffic or linksReturn 404 or 410
A seasonal page that will return next yearKeep it on the new site, even if it is light for now
Choosing what a retired URL should do (practitioner judgement)

Google’s crawlers treat a 404 and a 410 the same way: both tell Google the content does not exist, and an indexed URL is removed from the index.6 I would still use 410 for deliberate retirements, because it records intent in the server config and makes the retired rows easy to tell apart from mistakes in later reports. The HTTP standard draws the same line: a 404 does not say whether the absence is temporary or permanent, and a 410 is preferred when the server knows it is likely to be permanent.7

Chapter 05 / 071 min

Step 4: choose the status codes and check the defaults

Moved pages need permanent redirects. In HTTP terms, 301 and 308 are the permanent redirects and 302 and 307 the temporary ones, and 307 and 308 also stop the client changing a POST into a GET.7 Google’s indexing pipeline treats a 301 or 308 as a signal that the target should be canonical. A 302 or 307 is followed, but not used as that signal.8 Server-side redirects are the most reliable kind, and JavaScript redirects are a last resort, for when server-side and meta refresh redirects are not possible.8

Defaults catch people out here. Apache’s Redirect directive issues a temporary 302 unless you add the permanent keyword or a 301 status.3 Many plugins and platform redirect managers have similar defaults. The only check that counts is the status code the server actually returns.

Chapter 06 / 071 min

Step 5: test the whole map on staging

The URL Inspection tool suits individual URLs, and command line tools or scripts suit large numbers of them.1 For a migration you need the second. Request every old path in the sheet against the staging hostname, follow each redirect to the end, and write the results into the Test result column. A crawler can do the same job: Screaming Frog’s SEO Spider, in list mode with redirects always followed, exports every uploaded URL with its hops, loops and final status.9

Checklist0 of 5 done

The same failures appear later in Search Console’s Page indexing report, where a chain that is too long or a redirect loop shows as a redirect error, and pages that show a "not found" message without a 404 status code are reported as soft 404s.10 Catching them on staging is far cheaper than reading about them two weeks after launch.

After the bulk test, inspect a handful of the most valuable URLs one by one. Once the new site is live, the URL Inspection tool shows the canonical Google selected next to the one you declared, which is the quickest way to confirm that a redirect target is being treated as the canonical.11

Chapter 07 / 071 min

Step 6: hand the map over and keep it

Give developers the map as data: an export of Old URL, New URL and Status to serve for the one-to-one rows, plus the pattern rules written out with their exception lists. Ask for the rules back as deployed, and rerun the full test against production within minutes of launch.

Then keep the sheet. The redirects themselves should stay for as long as possible, and generally at least one year.1 Google’s John Mueller explained the reasoning in 2021: its systems need to see a redirect a few times before they record the change.12 A migration guide on Bing’s webmaster blog suggests one to two years.13 Over that year you will need it to update internal links, to answer questions about why a page went where it did, and to check new 404s in the logs against what was planned. A 404 for a row marked Retire is expected. A 404 for a URL that is not in the sheet at all means the inventory missed something, and it can usually be added to the map the same day.

Questions5 answered

Common questions

01How many URLs should a redirect map include?
Every old URL that has traffic, links or a place in the index, plus images and documents that get search traffic or links. Images and downloads belong in the move as well as pages.1 On large sites, pattern rules cover most rows and people review the valuable ones.
02Should I use 301 or 308 redirects in a migration?
Either. Google treats both as permanent and uses them as a signal that the target should be canonical.8 Use whichever your server or platform supports reliably, and check the status code it returns.
03Is it ever acceptable to redirect old pages to the homepage?
Only where the homepage is the true equivalent, such as an old homepage on a different domain. Redirecting many old URLs to an irrelevant page like the homepage might be treated as a soft 404.1
04Should retired pages return a 404 or a 410?
Google treats them the same way.6 I prefer 410 for deliberate retirements because it records the decision on the server and makes the rows easy to separate from accidental 404s.
05How do I test thousands of redirects?
With a crawler in list mode9 or a script that requests every old URL, follows the redirects and records the first status, the final URL and the number of hops. Scripts and command line tools are the right tools at that scale.1
References13 sources

Sources

  • Platform docs11
  • Regulator1
  • Reporting1
  1. 01Site Moves and MigrationsGoogle Search CentralPlatform docs
  2. 02Search Analytics: queryGoogle for DevelopersPlatform docs
  3. 03mod_aliasApache HTTP Server DocumentationPlatform docs
  4. 04Module ngx_http_rewrite_modulenginx documentationPlatform docs
  5. 05Redirections in HTTPMDN Web DocsPlatform docs
  6. 06How HTTP Status Codes Affect Google's CrawlersGoogle for DevelopersPlatform docs
  7. 07RFC 9110: HTTP SemanticsIETFRegulator
  8. 08Redirects and Google SearchGoogle Search CentralPlatform docs
  9. 09How To Audit Redirects In A Site Migration Using The SEO SpiderScreaming FrogPlatform docs
  10. 10Page indexing reportSearch Console HelpPlatform docs
  11. 11URL Inspection toolSearch Console HelpPlatform docs
  12. 12Google: Keep 301 Redirects In Place For A YearSearch Engine JournalReporting
  13. 13Website Migration with BingBing Webmaster BlogPlatform docs

Written by Mani Bharij, SEO & AI Search Consultant in London. More on this subject in the Website migrations guide.

Keep reading

Questions about any of this?

LinkedIn is the easiest place to reach me. Send a message or connect, and I will reply there.