Comparison
HTTP 301 vs 302 vs 307 vs 308: Which Redirect Should You Use?
HTTP has four redirect codes for what looks like the same job — pointing the client at a new URL. The differences are subtle but matter: getting them wrong can break POST requests, confuse SEO, or leave stale bookmarks pointing at the wrong resource for years.
The two axes are permanence (does this change forever, or just now?) and method preservation (should a POST stay a POST after the redirect, or silently become a GET?).
TL;DR
| 301 | 302 | 307 | 308 | |
|---|---|---|---|---|
| Permanent | Yes | No | No | Yes |
| Preserves method | Historically: no (often GET) | Historically: no (often GET) | Yes | Yes |
| Cacheable | By default | Not by default | Not by default | By default |
| SEO impact | Full link equity transferred | Weak / preserves original ranking | Weak / preserves original ranking | Full link equity transferred |
The options in depth
301 Moved Permanently
The classic permanent redirect. Browsers cache it aggressively.
301 tells the client the resource has moved forever. Browsers and search engines cache it aggressively — often for months or even permanently. This is what you want when consolidating a domain or removing a URL structure.
Historical quirk: browsers were allowed (and often did) change a POST into a GET when following a 301. Do not rely on POST bodies surviving a 301.
Good for
- ·Old page → new page permanently (SEO 100% link equity transfer)
- ·HTTPS canonicalization (http:// → https://)
- ·Domain migration
Avoid when
- ·Redirecting a POST or PUT endpoint (use 308)
- ·You might want to move it back later — 301 is nearly impossible to unwind due to browser caching
302 Found
The classic temporary redirect. Not cached by default.
302 is temporary — the resource is at the new URL now, but might not be later. Browsers re-check the original URL on each request rather than caching the redirect.
Like 301, historical implementations often changed POST to GET. If you must preserve the method for a temporary redirect, use 307 instead.
Good for
- ·Short-term redirects (maintenance page, A/B test, feature-flagged experiment)
- ·OAuth-style flows where the location may change
Avoid when
- ·Redirecting a POST or PUT (use 307)
- ·The move is actually permanent (use 301)
307 Temporary Redirect
Modern temporary redirect that preserves the request method and body.
307 was introduced to fix the 302-changes-POST-to-GET behavior. It guarantees the method and body are preserved — a POST stays a POST, a PUT stays a PUT.
Use 307 whenever you would use 302 on a non-GET endpoint. For GET endpoints, 302 and 307 behave identically in practice.
Good for
- ·Temporary redirects on POST / PUT / DELETE endpoints
- ·API gateway or reverse proxy redirects that must not silently downgrade the method
Avoid when
- ·The move is permanent (use 308)
308 Permanent Redirect
Modern permanent redirect that preserves the request method and body.
308 is 301 fixed. Same permanent-caching behavior, but the method is preserved. This is the correct code for permanently moving a POST / PUT endpoint.
Good for
- ·Permanent redirects on non-GET endpoints
- ·REST API versioning where the whole surface moves (v1 → v2)
Avoid when
- ·Very old HTTP clients that predate RFC 7538 (2015) — rare in 2025 but check embedded devices
Which one should you pick?
→ Is the move permanent AND all callers use GET?
301. Simplest and most compatible.
→ Is the move permanent, and some callers use POST / PUT?
308. Preserves method + permanent caching.
→ Is the move temporary AND all callers use GET?
302. Not cached, so you can reverse it easily.
→ Is the move temporary, and some callers use POST / PUT?
307. Preserves method + temporary.
Common pitfalls
- ⚠Never 301 during a maintenance window — browsers cache it and users may never come back until they clear cache.
- ⚠Redirect chains cost latency. Combine redirects (http → https → www → new domain) into a single hop when possible.
- ⚠Do not redirect API endpoints — API clients often do not follow redirects, or handle them incorrectly. Return a machine-readable error instead.
- ⚠Loops: if A redirects to B and B redirects to A, browsers give up after ~20 hops with an error.
Frequently Asked Questions
Does Google treat 301 and 308 identically for SEO?
Yes. Both pass full link equity and are treated as permanent moves. 302 and 307 are treated as temporary and preserve the original URL's ranking.
How do I test which redirect status is being returned?
curl -I <url> shows the status. Or use curl -Lv to follow the chain and see each hop. Browsers hide the status; DevTools' Network tab shows it too.
Can I redirect POST to GET intentionally?
Yes — 303 See Other is the correct code for “POST succeeded, now go GET the result”. This is the POST-Redirect-GET pattern.