DEV Community

Rahib Ali
Rahib Ali

Posted on

Redirect chains are silently slowing your site — here's how to find and fix them

You paste a URL into your browser. The page loads. Everything looks fine — but between your click and that final render, the browser may have silently hopped through two, three, or five redirects: http to https, bare domain to www, old path to new path, a trailing slash added along the way.

Browsers never show you this. They follow every hop automatically and render the destination. Redirect chains are invisible by design — and that is exactly why they quietly grow into a real problem.

Why a chain of redirects hurts

Latency. Every 301 or 302 is a full extra HTTP round trip: DNS, TLS handshake, request, response. One hop is noise. Four hops on a mobile connection is a noticeable delay before the first byte of the real page.

Crawl efficiency. Googlebot follows redirect chains, but it gives up after about 10 hops. A page that is only reachable through a long chain gets crawled less often — and Google's own documentation warns against chaining redirects where you can avoid it.

Link equity and canonicalization. A permanent move should be one clean 301 straight to the final URL. When old backlinks point at URL A, which 301s to B, which 302s to C, you are leaking both speed and signal at every step.

Search Console noise. "Page with redirect" and "Redirect error" reports are usually a chain problem, not a single-redirect problem.

See the chain: curl

The fastest honest view of a chain is in your terminal:

curl -IL https://example.com/old-page
Enter fullscreen mode Exit fullscreen mode

-I fetches headers only, -L follows redirects. The output shows every hop — status code plus the Location header it points to:

HTTP/2 301
location: https://example.com/new-page

HTTP/2 302
location: https://example.com/new-page/

HTTP/2 200
Enter fullscreen mode Exit fullscreen mode

That second hop is a 302 sending a permanent move to a trailing-slash variant — two separate mistakes visible in ten seconds of terminal output.

See the chain: DevTools

In Chrome or Firefox DevTools, open the Network tab, tick "Preserve log", and reload. Every request in the chain appears with its status code. This is the best option when you suspect client-side (meta refresh or JavaScript) redirects, which curl won't reveal — but it's tedious if you need to check more than a couple of URLs.

Trace chains in bulk: a tiny Node script

When a migration leaves you with hundreds of legacy URLs, clicking through each one isn't an option. This script follows a chain one hop at a time and prints it — using node:http/node:https directly, because fetch can't do this job: even with redirect: 'manual' it hands back an opaque redirect response (status 0, headers unreadable). Raw HTTP requests have no such filter:

// trace.mjs — usage: node trace.mjs https://example.com/old-page
// Zero dependencies. http.get / https.get never follow redirects,
// so each hop's real status code and Location header stay visible.
import http from 'node:http';
import https from 'node:https';

const get = (url) => new Promise((resolve, reject) => {
  const mod = url.startsWith('https:') ? https : http;
  mod.get(url, { headers: { 'User-Agent': 'redirect-tracer/1.0' } }, (res) => {
    res.resume(); // discard the body, we only need headers
    resolve({ status: res.statusCode, location: res.headers.location });
  }).on('error', reject);
});

let current = process.argv[2];

for (let hop = 1; hop <= 10; hop++) {
  const { status, location } = await get(current);
  const next = location ? new URL(location, current).href : null;

  console.log(`hop ${hop}: ${status}  ${current}${next ? `\n      → ${next}` : ''}`);

  if (!next || status < 300 || status > 399) break;
  if (hop === 10) { console.log('chain too long — stopping'); break; }
  current = next;
}
Enter fullscreen mode Exit fullscreen mode

Run it against a list of URLs from your sitemap or backlink export and you'll have a full chain audit in minutes. (MDN's guide to HTTP redirections has the full reference on status-code semantics if you want the details.)

The chains I keep finding in the wild

1. The protocol + host stack. http://example.com → https://example.com → https://www.example.com. Two hops before the site even starts loading. Fix: every variant should 301 straight to the canonical URL in a single hop.

2. Trailing-slash ping-pong. /page → /page/ → /page — usually two CMS rules fighting each other. Pick one canonical form and enforce it once.

3. Migration leftovers. old-domain.com/page → new-domain.com/page → new-domain.com/renamed-page → 200. Every legacy backlink pays three hops forever. Point the old URLs directly at their final destinations.

4. The accidental 302. A permanent move shipped as a 302 or 307 because it was the framework's default. Search engines keep indexing the old URL and never fully transfer the signal. If the move is permanent, it must be a 301.

5. Redirect loops. A → B → A, and the browser gives up with ERR_TOO_MANY_REDIRECTS. Almost always two conflicting rules — a www-forcing rule plus a non-www-forcing rule, or an http→https rule fighting an https→http one.

6. Chains ending in errors. The chain "works" in the browser but lands on a 404 or 500. Always check what the final hop returns, not just that the chain resolves.

A debugging workflow that actually works

  1. Trace the full chain — curl -IL for one-offs, the script above for bulk. When I want a quick visual answer without the terminal, I paste the URL into this free redirect chain checker, which follows every hop server-side and lists each status code and destination, with loop detection.
  2. Count the hops. More than two to reach the final page is worth flattening.
  3. Read the status codes. Permanent moves must be 301 — a 302/307 in the middle is a bug, not a preference.
  4. Verify the destination. Confirm the final URL returns 200 and isn't carrying a surprise noindex.
  5. Fix at the source. Point the original URL straight at the final destination, and update internal links, canonical tags, and sitemaps to skip the chain entirely. Redirecting to a URL that already redirects is how chains grow — one "quick fix" at a time.

Redirect chains accumulate because nothing complains about them: the browser hides them, users tolerate one extra hop, and each individual redirect looks harmless in isolation. Audit them after every migration, and spot-check your most-linked pages once in a while. The fix is almost always the same — one clean 301, straight to the destination.

Top comments (1)

Collapse
 
diazisme profile image
Manuel Diaz •

Excellent breakdown! Redirect chains are often overlooked because everything appears to work, yet they can negatively impact page speed, crawl efficiency, and SEO signals.

I especially appreciate the emphasis on fixing redirects at the source rather than adding another rule to an existing chain. Proactive audits, clean 301 redirects, and consistent canonical URLs are essential for maintaining a fast, scalable, and search-friendly website.

What strategies or tools do you recommend for detecting and preventing redirect chains during website migrations? I'd love to exchange insights with fellow developers and SEO professionals. Feel free to connect with me via WhatsApp! (+63 960 135 8469)