Blog

Web Development articles

301 vs 302 Redirects: Which One to Use and Why

301 vs 302 redirect: when each is correct, how they affect SEO and browser caching, where 307 and 308 fit, and server examples for Nginx, Apache and PHP.

4 min read Web Development

Redirects quietly hold websites together. They send visitors from old URLs to new ones, from HTTP to HTTPS, and from one domain to another. The two you will use most are 301 and 302, and choosing between them is a frequent source of confusion. The 301 vs 302 redirect decision comes down to one question: is this move permanent or temporary? The answer affects how browsers cache the redirect and how search engines index your pages.

The short answer

CodeMeaningUse when
301 Moved PermanentlyThe old URL is retired; use the new one from now onDomain changes, HTTP to HTTPS, renamed pages, merged content, non-www to www
302 FoundThe resource is temporarily elsewhere; keep using the original URLShort promotions, maintenance pages, A/B tests, sending logged-out users to a login page
308 Permanent RedirectLike 301, but the request method must not changePermanent moves of API endpoints or form targets that receive POST
307 Temporary RedirectLike 302, but the request method must not changeTemporary moves where POST must stay POST

How browsers treat each one

This is the part that catches people out. A 301 is cacheable by default. Once a browser has seen it, it may remember the redirect and go straight to the new URL next time without asking your server at all. That is efficient, but it means a 301 set by mistake can persist in visitors' browsers after you remove it from the server. Clearing it typically requires each user to clear their browser cache.

A 302 is not cached unless the response explicitly says it can be (with Cache-Control or Expires headers). The browser checks with the server each time, so you can change or remove it whenever you like.

Practical rule: when testing a redirect you are not yet sure about, use a 302 first, then switch to 301 once you are confident.

How search engines treat each one

A 301 tells search engines to replace the old URL with the new one in their index and to consolidate signals, such as links pointing at the old URL, onto the new address. A 302 tells them the original URL is still the one to index and show.

Search engines do try to interpret intent, and Google's documentation notes that both kinds are followed and that it uses redirects as one signal among several when picking the canonical URL. But sending a clear signal is far better than relying on a search engine to guess. If a "temporary" 302 has been in place for a year, it is not temporary; change it to a 301.

Why 307 and 308 exist

Historically, many browsers changed a POST request into a GET when following a 301 or 302, dropping the submitted data. Rather than break existing behaviour, the HTTP standards added 307 and 308, which require the client to repeat the request with the same method and body. For ordinary web pages, which are fetched with GET, 301/302 and 308/307 behave the same. For APIs and form endpoints, prefer 308 and 307.

Common scenarios

  • Moving to HTTPS: 301 (or 308) from every http:// URL to the matching https:// URL.
  • Choosing www or non-www: 301 from one to the other, keeping the path.
  • Changing domain: 301 each old URL to its equivalent on the new domain, page by page, not everything to the new home page.
  • Seasonal sale page: 302 from /offers to /offers/diwali-sale while the sale runs.
  • Site maintenance: better served as a 503 status with a Retry-After header than redirecting every page.
  • Language or country detection: 302, since the right destination depends on the visitor.

Setting up redirects

Nginx

# Whole site from HTTP to HTTPS
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://example.com$request_uri;
}

# Single page, permanent
location = /old-page { return 301 /new-page; }

# Temporary
location = /offers { return 302 /offers/diwali-sale; }

Apache (.htaccess)

Redirect 301 /old-page /new-page
Redirect 302 /offers /offers/diwali-sale

# HTTP to HTTPS with mod_rewrite
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

PHP

header('Location: https://example.com/new-page', true, 301);
exit;

Note that PHP's header('Location: ...') without a status code sends a 302 by default, a common source of accidental temporary redirects.

Redirects to avoid

  • Chains: http://example.com → https://example.com → https://www.example.com. Redirect straight to the final URL in one hop.
  • Loops: A redirects to B, B redirects to A. Often caused by a CDN connecting to the origin over HTTP while the origin forces HTTPS.
  • Meta refresh and JavaScript redirects for permanent moves. They work in browsers, but server-side 301s are clearer to search engines and faster for visitors.
  • Redirecting everything to the home page during a redesign. Map old URLs to their closest new equivalents; use 404 or 410 where nothing equivalent exists.

Testing your redirects

Check the actual status code and every hop, not just where you end up. Our HTTP header checker shows each redirect in the chain. From the command line:

curl -sIL http://example.com/old-page | grep -iE '^(HTTP|location)'

After a domain or hosting move, combine this with a DNS propagation check so you know whether visitors are reaching the new server's redirect rules at all.

Key takeaways

  • Use 301 (or 308) for permanent moves and 302 (or 307) for genuinely temporary ones.
  • Browsers cache 301s, so test with 302 first if you are unsure.
  • 307 and 308 preserve the request method; prefer them for APIs and forms.
  • Redirect in a single hop to the closest equivalent page, and verify with a header checker.

Need help with this?

Netifi helps businesses around the world with Web Development. Tell us what you are working on.