Redirect Chains and How to Flatten Them

Nobody deploys a five-hop redirect. Chains accumulate.

In 2021 someone redirects /blog/post to /articles/post. In 2023 a replatform moves everything under /resources/, so /articles/post now redirects to /resources/post. In 2025 the trailing-slash convention changes and /resources/post redirects to /resources/post/. A link earned in 2020 now takes four requests to arrive, and no single person made that decision.

Why length matters

Not because of a per-hop equity tax — see 301 versus 302 on why that number is folklore. The real costs are more prosaic and more concrete.

Crawlers stop following at some point. Google documents that it follows a limited number of redirect hops per crawl attempt — on the order of a handful — and treats anything beyond that as an error for that attempt. It may resume from where it stopped on a later crawl, so a long chain isn’t necessarily fatal, but it converts a one-step resolution into a multi-crawl one. A chain that’s near the limit today breaks the day someone adds a hop.

Latency is real and additive. Each hop is a full round trip. Four hops on a mobile connection is a visible delay before anything renders, and the user waiting through it is a human who clicked your earned link.

Chains break in ways single redirects don’t. Every hop is a separate rule in a separate system that someone can delete, reorder, or shadow. A one-hop redirect has one point of failure; a four-hop chain has four, spread across teams.

They hide loops. A loop is just a chain that closes, and in a long chain nobody notices the closure until requests start returning errors.

They’re evidence. A long chain usually means nobody has audited URL structure in years, which correlates with other things being wrong.

Finding them

One URL, from the command line:

curl -sIL https://example.com/blog/post | grep -E '^(HTTP|location)'

Each HTTP/… line is one hop. Two lines (a 301 and a 200) is a clean single redirect. Five lines is a problem.

Across the site, you need a crawler. Any site auditing tool that reports “redirect chains” will do — the report you want lists the start URL, each hop, and the final status. Two things worth doing that people skip:

  • Crawl your own internal links too, not just external entry points. Internal links pointing at redirected URLs are the easiest chains to fix, because you own both ends.
  • Crawl the URLs in your backlink export. Those are the paths that earned links point at, and they’re the ones where a chain costs you something. Any tool’s referring-URL export works as an input list.

From logs. If you have access to request logs, a filter on 3xx responses grouped by requested path shows you what’s actually being hit — which is not the same as what your rules say, because rules in different layers shadow each other.

Flattening

The principle is simple: every redirect should point at the final destination, not at another redirect.

Take the chain above:

/blog/post      → 301 → /articles/post
/articles/post  → 301 → /resources/post
/resources/post → 301 → /resources/post/

Flattened:

/blog/post      → 301 → /resources/post/
/articles/post  → 301 → /resources/post/
/resources/post → 301 → /resources/post/

Three rules, each one hop. Note that you keep all three source rules. This is the mistake people make when they “clean up” redirects — deleting the intermediate rules turns /articles/post into a 404, and there may be links pointing at it. The intermediates are entry points in their own right. You’re not removing hops from a path, you’re re-pointing each entry to the end.

When the chain crosses systems

The awkward real-world version: hop one is a Cloudflare rule, hop two is in nginx, hop three is in the application’s route table. Three owners, three deploy processes.

Order of operations that avoids breakage:

  1. Map the current state first. For every source URL in the chain, record the final destination that the full chain resolves to today. That’s your target map — you’re preserving current behaviour, just removing the intermediate steps.
  2. Start at the outermost layer and work in. Re-point the edge rules first, since they intercept before anything else and their new targets will be honoured immediately.
  3. Then the origin, then the application.
  4. Re-test every source URL after each layer. Not just the first one in the chain — all of them.

Doing it in the other order means the inner layers are corrected but the edge is still sending traffic through the old path, and you can’t tell whether your fix worked.

The one-generation rule

Going forward, adopt a rule that prevents recurrence: when adding a redirect, check whether the target is itself a redirect source, and if so, point at its target instead. One grep against your redirect config at write time prevents the whole class of problem.

If your redirects live in a file, this is enforceable in CI — a small script that resolves every rule’s target against the rule set and fails the build if any target appears as a source. Cheap, and it holds the line permanently.

The mistakes worth naming

Redirecting everything to the homepage. A common “fix” for a batch of 404s. From the search engine’s perspective a redirect to an irrelevant page is treated much like a 404 — a soft 404 — so it doesn’t preserve anything, and from the user’s perspective it’s worse than an error page because it silently loses their intent. Redirect to the closest genuinely equivalent page, or serve an honest 404 with useful navigation.

Chains created by trailing-slash and protocol normalisation. The classic four-hop accident: http://example.com/pagehttps://example.com/pagehttps://www.example.com/pagehttps://www.example.com/page/. Every one of those rules is individually reasonable. Combine them and an external link on the wrong variant takes four hops. Fix by normalising in one rule that handles protocol, host and slash together.

Assuming the config is what’s served. Rules get shadowed by earlier rules, by other layers, and by platform defaults. Always verify with a request.

Removing old redirects to tidy up. Old redirects are load-bearing. Unless you’re certain nothing links to a path and nothing has for years, leave the rule in place. A redirect rule costs approximately nothing; a broken inbound link costs whatever the link was worth.