HTTP gives you two kinds of redirect, and they are not interchangeable: they differ in caching behavior, in how search engines treat them, and in whether you can measure anything afterwards. This guide is the decision framework — for short links, for domain moves, and for content changes.
The semantics, precisely
| 301 Moved Permanently | 302 Found (Temporary) | |
|---|---|---|
| Meaning | This URL is permanently replaced | This URL is temporarily elsewhere |
| Browser caching | Aggressive — repeat visits skip the old URL | Not cached; every request follows the chain |
| Search engines | Consolidate signals onto the target | Keep both URLs; attribute with care |
| Analytics | First visit only | Every visit |
The practical consequence: a 301 turns off the measurement point. Browsers remember the mapping and resolve it locally; the shortener never sees the second, third, or tenth click.
The short-link rule: always 302
Short links exist to be measured. The platform must see every click — for totals, series, referrers, and bot filtering — and 301 caching breaks that at the browser level. The analytics pipeline depends on the redirect happening every time.
The SEO objection — "but 301 passes more link equity" — misunderstands the architecture. The short link is not the ranking page; the destination is. The destination carries its own canonical, metadata, and backlinks, and receives the visitor (and the crawler) via the 302. The understanding URL shortening guide covers the full chain.
The destination rule: 301 when the page really moved
On your own site, use 301 when a URL is permanently replaced:
old: example.com/blog/old-slug
new: example.com/blog/new-slug ← 301 from old to new
old: www.example.com → example.com ← 301 (canonical host)
old: http:// → https:// ← 301 (protocol upgrade)
After the move: keep the destination's canonical self-referential, submit the new URLs in Search Console, and monitor the transition window — 301s pass signals but the crawl-and-replace cycle takes time. The custom domain setup guide shows the same discipline applied to branded short domains.
The measurement consequences, in practice
Consider a campaign link shared in an email sent to 10,000 people:
| 301 | 302 | |
|---|---|---|
| First open | counted | counted |
| Second open (browser cache) | not counted | counted |
| Forwarded click | not counted | counted |
| Reported total | ~2,000 of 10,000 | ~4,500 of 10,000 |
The 302 number is the honest one. Any decision made on 301 totals — budget allocation, channel comparison, campaign kill/keep — is made on partial data. This is why conversion tracking and channel comparison both assume a 302 link layer.
Redirect chains and latency
Redirects stack: a short link → destination → (maybe) another redirect. Each hop costs latency and crawl budget. Keep chains to one hop, and keep each hop fast:
Bad: short.link/a → lander → old-page 301 → new-page
Good: short.link/a → new-page (one hop)
Edge-cached redirects answer in ~30–50ms; every extra hop multiplies. If you control the destination, fix the chain there rather than papering over it with another redirect.
The decision table
| Situation | Code | Why |
|---|---|---|
| Short link (analytics platform) | 302 | Keep every click measurable |
| Domain migration on your site | 301 | Consolidate signals permanently |
| HTTP → HTTPS | 301 | Permanent, security-relevant |
| A/B test between destinations | 302 | Switch targets without cache pollution |
| Temporary campaign swap | 302 | Restore the old target later |
| Permanent content move | 301 | Tell crawlers the URL is gone for good |
Conclusion
The redirect status code is a product decision, not a trivia detail: 301 for permanent moves you want consolidated, 302 for anything that must stay measurable. Short links belong to the 302 family — the destination does the ranking, and the link layer does the counting. Verify the behavior live on any yas.sh link: every redirect is 302, every click is recorded, and the API docs document the contract.
