Redirect Status Code Decision Tree: 301, 302, 307, and 308 Explained
A practical decision guide for choosing the right redirect code for short links, migrations, campaigns, and temporary pages
yas.sh Editorial Team — Engineering Guides

Why the redirect status code is a critical infrastructure decision
Most developers treat redirect status codes as an afterthought, defaulting to whatever their framework provides. However, the three-digit number attached to an HTTP redirect—301, 302, 307, or 308—is not a minor technical detail. It is an explicit instruction to the user's browser, to search engine crawlers, and to intermediate network nodes like CDNs and proxy servers. These entities interpret the status code differently, and choosing the wrong one can silently destroy your analytics tracking, drain your SEO equity, or break your application logic. A redirect status code dictates whether a browser caches the route, whether it changes the HTTP method from POST to GET, and whether Google combines the link equity of two different URLs. Understanding the exact mechanics of these codes is essential for building resilient web infrastructure.
Diagram: The redirect status code decision tree
┌──────────────────────────────┐
│ Is the move permanent? │
└─────┬──────────────────┬─────┘
YES NO
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Must preserve│ │ Must preserve│
│ HTTP Method? │ │ HTTP Method? │
└──┬───────┬───┘ └──┬───────┬───┘
YES NO YES NO
▼ ▼ ▼ ▼
[308] [301] [307] [302]
301 Moved Permanently: The SEO standard with a dangerous caching trap
The 301 status code tells the browser and search engines that the requested resource has been permanently moved to a new URL. For SEO, this is the gold standard. When Googlebot encounters a 301, it removes the old URL from its index and transfers approximately 90% to 99% of the PageRank to the new destination. However, the 301 has a massive, often overlooked operational trap: aggressive browser caching. When a browser receives a 301, it caches that redirect. If a user clicks the short link a second time, the browser bypasses your shortener server entirely and goes straight to the destination. For a URL shortener, this is catastrophic for analytics. If you use a 301, you lose the ability to track repeat clicks, and you lose the ability to change the destination URL in the future because users are no longer hitting your server. Reserve 301 redirects for permanent structural changes on your website, never for dynamic short links that require tracking.
302 Found: The short link lifeline
The 302 status code indicates that the resource is temporarily located at a different URL. Historically, there was confusion because early HTTP specifications (RFC 1945) referred to it as "Moved Temporarily," while modern specs (RFC 7231) call it "Found." Regardless of the naming history, the critical behavioral difference is caching. Browsers do not permanently cache 302 redirects. Every time a user clicks a 302 short link, their browser contacts your server. This allows the shortener to log the click, count it in analytics, and dynamically decide where to send the user. If you need to change the destination URL because a landing page moved, you can update it in your database, and the very next user who clicks the link will go to the new destination. This is why every production URL shortener that values analytics defaults to 302 redirects.
The 302 method mutation problem
While 302 is essential for short links, it has a dangerous flaw defined in the HTTP specification: method mutation. If a client sends a POST request to a URL that returns a 302, the specification explicitly states that the client must change the method to GET when following the redirect. This is a legacy behavior designed for old web forms, but it breaks modern REST APIs and web applications. If a user submits a form via POST to a short URL, and the shortener responds with a 302, the browser will convert the POST to a GET request when it hits the destination server. The destination server will likely drop the POST body, and the form submission will fail silently. If your short link might ever receive POST, PUT, or DELETE requests, you absolutely cannot use a 302 redirect.
307 Temporary Redirect: The method-preserving savior
To solve the method mutation problem of the 302, the HTTP specification introduced the 307 status code. A 307 explicitly guarantees that the client will preserve the original HTTP method and body when following the redirect. If a client sends a POST request to a 307 redirect, the client will send a POST request to the destination URL, complete with the original payload. Like the 302, the 307 does not trigger aggressive browser caching, making it safe for analytics tracking. If you are building a URL shortener that handles API traffic, webhook routing, or form submissions, 307 is the correct choice. It provides the temporary, non-caching behavior of a 302, but with the strict method preservation required by modern application architectures.
308 Permanent Redirect: The strict permanent move
The 308 is the permanent counterpart to the 307. It tells the browser and search engines that the move is permanent (transferring SEO equity like a 301), but it strictly preserves the HTTP method (like a 307). You use a 308 when you are permanently moving an API endpoint or a form submission URL to a new domain, and you cannot afford to have POST requests silently converted to GET requests. While 308 is supported by all modern browsers and search engines, it is rarely used in standard web page redirects because standard page navigation almost always uses GET requests. However, in enterprise API migrations, the 308 is an indispensable tool for preventing data loss during infrastructure transitions.
The anti-patterns: Meta refresh and JavaScript redirects
Never use HTML meta refresh tags or JavaScript window.location redirects for public-facing links. A meta refresh looks like this: <meta http-equiv="refresh" content="0;url=https://example.com">. These techniques are slow, create a terrible user experience (a flash of blank content before the redirect), and are heavily penalized by search engines. Google treats meta refreshes as a suspicious "sneaky redirect," especially if the timing is delayed by a few seconds to show ads before redirecting the user. Using JavaScript redirects breaks for users who have JavaScript disabled and completely destroys SEO crawlability because search engine bots often fail to execute JavaScript redirects reliably. Always use server-side HTTP headers (301, 302, 307, 308) for routing. They are instantaneous, secure, and universally understood by all clients and crawlers.
How CDN edge networks complicate redirect codes
If your infrastructure uses a CDN like Cloudflare, Fastly, or AWS CloudFront, the CDN acts as a massive, distributed cache sitting between the user and your shortener server. CDNs interpret redirect status codes aggressively. If your origin server sends a 301, the CDN will cache that redirect at the edge. Subsequent requests from different users in the same region will be served directly by the CDN, meaning your origin server never sees the clicks and your analytics drop to zero. If you use a 302, CDNs generally do not cache the redirect, but you must ensure your CDN configuration does not override your origin headers. Some CDN "performance" settings automatically convert 302s to 301s to reduce origin requests. You must explicitly disable any "301 auto-conversion" or "edge caching" rules on your CDN for your short link routes to preserve your analytics data.
The decision matrix: Choosing the right code
To summarize the technical realities into an operational rulebook, follow this decision matrix. If the redirect is for a marketing short link that needs click tracking and might change destinations, use 302. If the redirect is moving a public web page permanently and you do not care about tracking the individual hops, use 301. If the redirect is handling API traffic, webhooks, or form POST data temporarily, use 307. If the redirect is a permanent API migration that must preserve POST data, use 308. Never use meta refresh or JavaScript. If your infrastructure uses a CDN, verify that the CDN is configured to respect your origin server's status code without overriding it for caching optimization.
FAQ
Can I change a short link from a 302 to a 301 after a campaign ends to save server resources?
No. Once a 301 is issued, browsers cache it indefinitely. If you change to a 301, users will stop hitting your server, but you will also lose the ability to ever change that link's destination again or track future clicks. The server resource savings are negligible compared to the loss of control.
What happens if Googlebot encounters a 302 redirect that has been in place for three years?
Google's algorithms are smart enough to recognize that a 302 which has been active for a very long time is effectively permanent. Google may eventually pass the majority of link equity through the 302 and treat the destination as the canonical URL, but it will not remove the short URL from its index the way it does with a 301.
Why do some legacy APIs break when I change a redirect from 302 to 307?
Because legacy API clients were built assuming the flawed 302 behavior of mutating POST to GET. When you switch to a 307, the client is forced to send a POST to the destination. If the destination server is not expecting a POST (because it was relying on the 302 to convert it to a GET), the request will fail with a 405 Method Not Allowed error.
Do redirects pass the HTTP Referer header?
Yes, most browsers pass the Referer header when following a 301 or 302 redirect, which is how analytics tools know where the user came from. However, if the redirect crosses from HTTPS to HTTP, the browser will strip the Referer header for security reasons. Always ensure your short domain and destination domain both use HTTPS.
Is it possible to chain redirects (e.g., 301 to a 302)?
Technically yes, but it is a terrible practice. Every hop in a redirect chain adds latency, increases the chance of failure, and complicates debugging. Search engines may refuse to follow more than three or four chained redirects. Always configure your shortener to redirect directly to the final destination in a single hop.
Conclusion
Redirect status codes are precise engineering tools, not interchangeable placeholders. The difference between a 301 and a 302 is not academic; it determines whether your analytics platform sees 100% of your clicks or 0%. The difference between a 302 and a 307 determines whether your API integrations silently corrupt user data. By aligning your redirect logic strictly with the HTTP specifications—using 302 for tracked marketing links, 307 for API routing, and 301 exclusively for permanent structural changes—you build an infrastructure that is predictable, secure, and optimized for both human users and search engine crawlers.