HTTP 301 vs 308 — Permanent Redirect & Method Preservation Comparison
http 301 vs 308: both are permanent redirects, but 308 strictly preserves the request method (POST stays POST). When to choose each for APIs vs web pages.
Quick Cheat Sheet
| Aspect | 301 Moved Permanently | 308 Permanent Redirect |
|---|---|---|
| Permanence | Permanent | Permanent |
| Method preservation | MAY change POST → GET | MUST preserve method |
| RFC | 9110 (originally 1945) | 7538 (2015) |
| Body preservation | MAY drop | MUST preserve |
| Browser support | Universal | Universal (modern), buggy in old IE |
Why Both Exist
301 has been around since HTTP/1.0 and carries 30+ years of buggy implementations. The most consequential bug: many clients silently change POST to GET when following a 301, even though the original spec didn't allow this.
308 Permanent Redirect (RFC 7538) was specifically introduced in 2015 to fix this. It is a strict permanent redirect that MUST NOT change the request method or body.
When to Choose 308 Over 301
Use 308 when:
- The redirect is for an API endpoint that accepts POST/PUT/PATCH/DELETE
- You're moving a form submission URL (e.g.,
POST /v1/users→POST /v2/users) - You need guaranteed body and header preservation across the redirect
Use 301 when:
- The redirect is for HTML pages, GET-only resources (most web traffic)
- Maximum compatibility with old user agents matters
- You want SEO link equity transfer (both 301 and 308 transfer it, but 301 is more battle-tested in Google's eyes)
SEO: A Common Question
Google has confirmed both 301 and 308 transfer link equity equivalently for permanent redirects since 2016. There's no SEO penalty for 308. For browser-facing pages where method preservation isn't an issue, either works — most sites still use 301 for tradition and broader CDN/edge support.
Caching
Both are heuristically cacheable by default and treated as long-lived by browsers. Be careful — a wrong 308 is just as sticky as a wrong 301.
Real-World API Example
Suppose you've moved POST /api/v1/payments to POST /api/v2/payments:
- With 301, some HTTP clients will retry as
GET /api/v2/payments, which fails — the payment never goes through, but the client thinks the redirect succeeded. - With 308, all compliant clients re-issue the original
POSTwith the same body, and the call succeeds.
This is why API gateways and microservice meshes typically use 308 for versioned URL migrations.
Browser & Tooling Support
- All modern browsers (Chrome, Firefox, Safari, Edge) handle 308 correctly.
- Curl, wget, requests (Python), axios (Node), Go's net/http: all preserve method on 308.
- Internet Explorer ≤ 11 doesn't fully understand 308 (treats it as 200, breaking the redirect). Only relevant if you support IE.
Real-World Use Case
When deprecating /api/v1/* in favor of /api/v2/*, configure 308 redirects so that integration partners' POST /api/v1/orders requests transparently become POST /api/v2/orders without code changes. For a marketing site that renamed /pricing to /plans, 301 is fine — it's GET-only, and browser/CDN compatibility is broadest.
Look Up Any Status Code
Related Comparisons
HTTP 301 vs 302 — Moved Permanently vs Found Comparison
http 301 vs 302: 301 is permanent and transfers SEO link equity, 302 is temporary. Learn the right choice for redirects and how Google, browsers, and CDNs treat each.
HTTP 302 vs 307 — Temporary Redirect & Method Preservation Comparison
http 302 vs 307: both are temporary redirects, but 307 strictly preserves the HTTP method. When 307 fixes broken POST redirects in APIs and OAuth flows.
HTTP 303 vs 302 — See Other vs Found Status Code Comparison
http 303 vs 302: 303 is the canonical 'POST/Redirect/GET' code that always converts to GET, while 302 is ambiguous. Why 303 fixes form-resubmission in modern web apps.
HTTP 304 vs 200 — Not Modified vs OK (Caching) Comparison
http 304 vs 200: 304 is sent when a conditional GET hits an unchanged resource, saving bandwidth. Learn ETag, If-None-Match, and how 304 cuts CDN/origin costs.