Redirect chains: how they hurt SEO and how to find them
·4 min read
A redirect chain is a URL that passes through two or more redirects before it reaches a page that loads. Each hop costs the visitor another round trip and costs the crawler another request, and Google's crawlers follow at most 10 hops. Find chains by following the URL with curl -sIL or a redirect checker, then point every old URL straight at its final destination in one hop.
One redirect is normal. You moved a page, you 301 the old URL, done. The trouble starts when that old URL already redirected somewhere else, and nobody updated the first rule.
What a redirect chain looks like
A chain is any path with more than one 3xx response before the final 200. Here is the most common one, built entirely out of reasonable rules.
http://example.com/blog/post 301 -> https://example.com/blog/post
https://example.com/blog/post 301 -> https://www.example.com/blog/post
https://www.example.com/blog/post 301 -> https://www.example.com/blog/post/
https://www.example.com/blog/post/ 200Three redirects, three different owners. The HTTPS rule came with the certificate. The www rule lives in the CDN. The trailing slash comes from the CMS. Each one works alone, and together they make every old link to the bare http URL take three hops.
Chains also stack up across migrations. A 2019 URL redirects to its 2022 slug, which redirects to the 2024 section rename.
If the chain never ends because two rules send the URL back and forth, that is a loop, not a chain. The ERR_TOO_MANY_REDIRECTS guide covers how to find the two rules that disagree.
How redirect chains hurt SEO
Google's crawlers follow up to 10 redirect hops by default, per its HTTP status code documentation. Search Console lists "A redirect chain that was too long" as one of the causes of a Redirect error in the Page indexing report.
Ten hops sounds generous. Google still tells you to avoid chains. Its site move guide says to redirect to the final destination directly, and if you can't, to keep a chain at "ideally no more than 3 and fewer than 5" hops. The same page says chaining adds latency for users and that not every browser or user agent supports long chains.
The latency part is easy to underrate. Each hop is a full request and response, and a hop to a new host means a new DNS lookup and TLS handshake before the visitor sees anything.
Chains also hide mistakes. A single 302 in the middle of three 301s makes the whole path partly temporary, and an HTTPS URL that redirects back to HTTP before bouncing forward again is easy to miss when you only look at where you landed.
How to check where a URL redirects with curl
Use curl -sIL to print every hop's status line and Location header. -I asks for headers only, -L follows redirects, and -s hides the progress meter.
curl -sIL http://example.com/blog/post | grep -iE '^(HTTP|location)'For the chain above, the output reads like this.
HTTP/1.1 301 Moved Permanently
Location: https://example.com/blog/post
HTTP/2 301
location: https://www.example.com/blog/post
HTTP/2 301
location: https://www.example.com/blog/post/
HTTP/2 200Count the 3xx lines. More than one means a chain. To get the count and the final URL without reading headers, use curl's write-out variables.
curl -sL -o /dev/null -w '%{num_redirects} %{url_effective} %{time_redirect}s\n' http://example.com/blog/postnum_redirects is the number of redirects followed, url_effective is the last URL fetched, and time_redirect is the total time spent on the redirect steps, all per the curl manual. curl follows up to 50 redirects by default, so add --max-redirs 10 if you want it to fail where Googlebot would.
Test all four starting points of your homepage, http and https, with and without www. Then test a few old URLs from your last migration and any URLs linked from other sites. An HTTP redirect checker runs the same test and shows the hops as a table.
How to fix a redirect chain
Flattening a chain means every starting URL gets one redirect, straight to the final URL. Work through it in this order.
- Pick the canonical protocol, host and trailing slash once. For example,
https://www.example.com/path/. - Write one rule that sends every non-canonical variant there in a single hop. Combine the http, host and slash conditions instead of chaining three separate rules. The 301 vs 302 guide has nginx and Apache examples.
- Delete duplicate rules in other layers. If the server handles www, remove the CDN rule that does the same job.
- Rewrite old migration rules so each one targets today's URL, not the URL it pointed at when it was written.
- Update internal links, canonical tags and your sitemap to use final URLs, so your own site never triggers a redirect.
- Retest every starting URL with curl and confirm one 301 or 308, then a 200.
Use permanent status codes for every hop in a permanent move. A chain that ends in the right place through a 302 still tells Google the move might be temporary.
Trace your redirect chain and host versions
Our redirect chain and header checker follows a URL hop by hop, up to 10 redirects, and shows each hop's status code, whether it is permanent or temporary, its Location target and how long it took. It flags more than one redirect as a chain, and more than three as a long chain. It also flags loops, chains still redirecting after 10 hops, a redirect with no Location header, HTTPS falling back to HTTP, temporary redirects that change host, and hops slower than 3 seconds.
The same run requests the http and https versions of the bare domain and www, and reports whether they all land on one HTTPS origin. It checks response headers too, such as an X-Robots-Tag noindex on a hop. Each finding comes with the change to make. A run costs 10 credits. It follows HTTP redirects only, so a meta refresh or JavaScript redirect ends the trace at the page that returned 200.