301 vs 302 vs 307 vs 308: Which Redirect to Use
Choosing the wrong redirect can keep an old URL in Google for months or turn a form submission into a GET request that loses its data. Here is what each status code means, which one to use, and how to check that your redirects behave.
The four redirects at a glance
| Status | Permanent? | Keeps method and body? | Use for |
|---|---|---|---|
301 Moved Permanently | Yes | Not guaranteed (POST may become GET) | Moved pages, HTTP → HTTPS, domain changes |
302 Found | No | Not guaranteed | Short-term moves, A/B tests, maintenance |
307 Temporary Redirect | No | Yes | Temporary moves of API endpoints and forms |
308 Permanent Redirect | Yes | Yes | Permanent moves of API endpoints that receive POST |
For SEO, Google treats 301 and 308 as strong signals that the new URL should replace the old one, and passes ranking signals to it. 302 and 307 tell Google to keep the old URL indexed. Full details for every code are in the HTTP Status Codes reference.
Which one to choose
- Page moved for good (new slug, merged article, new domain) → 301.
- HTTP to HTTPS, www to non-www → 301 (or 308).
- Temporary (sale page, maintenance, geo or language routing) → 302.
- An API endpoint or form handler moved → 308 (permanent) or 307 (temporary), so POST data isn’t lost.
Avoid chains and loops
A chain is /a → /b → /c: each hop costs a round trip, and crawlers may stop following after several hops. A loop (/a → /b → /a) breaks the page entirely. After a migration, point every old URL directly at its final destination. Check any URL’s full path — every hop, status and timing — with the Redirect Checker, including whether the http, https, www and non-www versions all end up in the same place.
Copy-paste rules
Apache (.htaccess):
Redirect 301 /old-page /new-page
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Nginx:
location = /old-page { return 301 /new-page; }
server { listen 80; server_name example.com; return 301 https://$host$request_uri; }
Vercel (vercel.json): "permanent": true sends a 308, which Google treats like a 301.
{ "redirects": [ { "source": "/old-page", "destination": "/new-page", "permanent": true } ] }
Turn a spreadsheet of old → new URLs into rules for any server with the Redirect Generator, or build a full Apache config with the .htaccess Generator.
Migration checklist
- Map every old URL to the most relevant new one — not all to the home page, which Google treats as a soft 404.
- Use 301 (or 308) for permanent moves and keep them for at least a year.
- Update internal links and the sitemap to the new URLs, so redirects are only a safety net.
- Test a sample of old URLs, then watch Search Console’s Pages report for 404s.