Redirects and Link Equity
Date: 2026-08-16
A redirect tells everyone where something went. Get the type wrong and signals don’t transfer; chain them and each hop costs a round trip and some crawl budget; forget them and years of accumulated links point at 404s.
What it is
A redirect is a response instructing the client to request a different URL. Link equity is the accumulated ranking value from links pointing at a URL, which a redirect is supposed to pass along.
The types
| Code | Meaning | Passes signals | Method preserved |
|---|---|---|---|
| 301 | Moved permanently | Yes | No — POST becomes GET |
| 302 | Found, temporary | Treated as temporary; original stays indexed | No |
| 307 | Temporary, strict | As 302 | Yes |
| 308 | Permanent, strict | As 301 | Yes |
| meta refresh | Client-side | Poorly, if at all | — |
| JavaScript | Client-side | Only if rendered; not by AI crawlers | — |
Use 301 for anything permanent. The distinction that catches people is that 301 and 302 rewrite POST to GET, which breaks form submissions — 307 and 308 preserve the method, and are what you want on API routes.
Client-side redirects are a last resort. They’re slow, they cost a full page load, and non-rendering crawlers never see them — Rendering and SEO.
Chains and loops
BAD COST
http://example.com/old-product each hop is a full
→ https://example.com/old-product round trip: ~150ms
→ https://www.example.com/old-product on mobile
→ https://www.example.com/products/new
450ms before the real
4 requests, 3 redirects page starts loading
Chains cost latency directly — they’re the largest avoidable component of Time to First Byte — and each hop consumes crawl budget. Some engines stop following after a handful of hops.
Fix by flattening: every old URL should redirect to the final destination in one hop, not to the next link in a historical chain. After several migrations this requires actually auditing the redirect table rather than appending to it.
Loops are worse and are usually a conflict between two rules — a canonical host rule and a trailing-slash rule disagreeing.
Where equity leaks
- Redirecting everything to the homepage. A blanket rule for a discontinued range is treated as a soft 404, and passes nothing. Redirect to the nearest genuine equivalent, or return 404 honestly
- Redirecting to a
noindexpage, which is a contradiction - 302 for a permanent move, so the old URL stays indexed and the new one never accumulates
- Chains, which dilute at each hop
- Removing redirects after “enough time”. External links don’t expire. Keep them indefinitely — they cost almost nothing
Out-of-stock and discontinued products
The ecommerce-specific case, and it’s a genuine judgement call:
| Situation | Response |
|---|---|
| Temporarily out of stock | Keep the page, 200. Show alternatives and a back-in-stock signup |
| Permanently discontinued, close equivalent exists | 301 to the equivalent |
| Permanently discontinued, no equivalent | 301 to the parent category, or 404 if the category is a poor match |
| Never existed | 404 or 410 |
Deleting a product URL throws away every link it ever earned. For a product that’s been listed for years, that’s real accumulated value, and the cost of redirecting is one row in a table.
Returning a 200 with “product not found” is the worst option — it’s a soft 404, it wastes crawl budget, and it leaves a dead page indexed.
Implementation
- At the edge or CDN for large redirect tables, so they don’t touch the origin — Edge Computing
- In server config for pattern rules
- In the application only for logic that genuinely needs application state
- Never in a tag manager. A client-side redirect from a container is slow, breaks for non-rendering crawlers, and is invisible to whoever debugs it later
For a migration, generate the map from a crawl of the old site rather than from the sitemap — the sitemap won’t contain the URLs that accumulated links years ago. See Site Migrations and SEO.
Auditing
curl -sIL https://example.com/old-url | grep -E "^HTTP|^location"
Shows every hop and its status. A site crawler will do this in bulk and flag chains, loops and redirects to error pages — worth running before any launch and periodically afterwards, since redirect tables accumulate silently.