301 vs 302 Redirects: Which Should You Use?
Permanent vs Temporary? Learn when to use 301 resets for SEO juice and when to use 302s for maintenance and A/B testing.
The Core Concept#
In HTTP, a redirect is a way for a server to say: "The resource you are looking for is not here, go check there instead."
The two most common status codes for this are 301 (Moved Permanently) and 302 (Found / Moved Temporarily). Choosing the wrong one can destroy your SEO rankings or cause aggressive browser caching issues that are hard to fix.
301: Moved Permanently#
A 301 redirect is a permanent instruction. It tells search engines and browsers:
"This page is gone forever. Forget the old URL and only use the new one from now on."
How it affects SEO
This is the Gold Standard for SEO when moving content. When Googlebot sees a 301:
- It removes the old URL from its index.
- It indexes the new URL.
- Crucially, it passes the "link equity" (PageRank) from the old URL to the new one. This means you don't lose your hard-earned reputation.
When to use 301
- Site Migrations: Moving from
example.comtonew-example.com. - Protocol Changes: Redirecting all
http://traffic tohttps://. - Canonicalization: Merging
www.site.comandsite.com. - Content Cleanup: You deleted an old blog post and want to redirect users to a newer, better version of that topic.
The Danger of 301
Because it is "permanent", browsers cache 301 redirects aggressively. If you mistakenly 301 redirect /login to /error, and then try to fix it on the server, users who already visited the site might still be redirected automatically by their browser cache for months. Always double-check before deploying a 301.
302: Found (Temporary Redirect)#
A 302 redirect is a temporary instruction. It tells clients:
"This page is momentarily unavailable, please use this other URL for now, but come back to the original one later."
How it affects SEO
Googlebot sees a 302 and understands that the original URL is still the "real" one.
- It keeps the old URL in the index.
- It does not pass link equity to the temporary page.
When to use 302
- A/B Testing: You want to test a new homepage design on 50% of users without hurting the ranking of your main homepage.
- Maintenance: Your site is down for updates, so you redirect visitors to a "Under Maintenance" status page.
- Geo-Targeting: Redirecting a user from
site.comtosite.com/frbased on their location, while keepingsite.comas the main global entry point. - Promotional Pages: Redirecting
/saleto a specific Black Friday landing page for a week.
307 and 308: The Modern Successors#
Technically, 301 and 302 allowed user agents to change the HTTP method (e.g., changing a POST request to GET after redirect). This was actually against the original spec but became standard behavior.
To fix this ambiguity, newer codes were introduced:
- 307 Temporary Redirect: Same as 302, but guarantees the HTTP method (POST remains POST) is preserved.
- 308 Permanent Redirect: Same as 301, but guarantees the HTTP method is preserved.
Recommendation: For SEO and standard web navigation (GET requests), 301 and 302 remain the standard and are perfectly fine. Only strictly use 307/308 if you are building complex APIs where preserving POST body data across redirects is critical.
Summary Checklist#
| Scenario | Recommended Redirect | Why? |
|---|---|---|
| Buying a new domain | 301 | Transfer all SEO value to new brand. |
| Seasonal Sale Page | 302 | You want the original URL to rank again later. |
| HTTP to HTTPS | 301 | Security best practice, permanent change. |
| System Down / Maintenance | 302 (or 503) | Temporary state. |
| A/B Testing | 302 | Don't confuse Google about which version is "real". |
Implementation in Express.js#
const express = require('express');
const app = express();
// Permanent (301)
app.get('/old-blog', (req, res) => {
res.redirect(301, '/new-blog');
});
// Temporary (302) - Default in Express
app.get('/promo', (req, res) => {
res.redirect('/current-promo'); // Defaults to 302
});
Using the right redirect is one of the easiest "quick wins" for technical SEO. Get it wrong, and you're fighting an uphill battle against your own server.
WebFiddle