A 301 redirect tells browsers and search engines that a URL has moved for good; a 302 says the move is temporary. Visitors land on the new page either way. The difference shows up in search results and caches: with a permanent redirect, Google treats the new URL as the one to index and consolidates signals there, while a temporary redirect keeps the old URL in play. 307 and 308 are the temporary and permanent versions that guarantee the request method, such as POST, is not changed along the way.
To see exactly which status codes a URL returns and how many hops it takes, run it through the redirect checker. When you are designing the new URLs, the slug generator turns titles into clean, lowercase paths. The URL encoder and decoder makes old percent-encoded addresses readable, and the text diff checker compares two versions of a redirect map line by line before you deploy it.
The redirect status codes compared
Status code semantics are defined today in RFC 9110, HTTP Semantics, published in 2022. Five codes in the 3xx range cover nearly every real-world case:
| Code | Name | Permanent? | Method preserved? | Typical use |
| 301 | Moved Permanently | Yes | Not guaranteed; POST may become GET | Domain change, new URL structure |
| 302 | Found | No | Not guaranteed | Short promotions, maintenance pages |
| 303 | See Other | No | Always switches to GET | Result page after a form submission |
| 307 | Temporary Redirect | No | Yes | API endpoint moved for a while |
| 308 | Permanent Redirect | Yes | Yes | API or form endpoint moved for good |
The method column is a historical accident. In the HTTP/1.0 era most browsers re-sent a POST as a GET after a 301 or 302, and the specification eventually accepted that behavior. 307 arrived with HTTP/1.1 and 308 with RFC 7538 so that servers could demand the method and body stay intact. For ordinary page views, which are GET requests, 301 and 308 behave the same.
When a 301 redirect is the right call
If the old address will never come back, the answer is almost always a permanent redirect. Typical cases:
- Domain moves: every page on the old domain goes to its counterpart on the new one.
- HTTP to HTTPS, plus settling on either the www or the bare hostname.
- URL restructuring: for example from
/product.php?id=42 to /products/steel-flask.
- Content consolidation: merging two thin articles on the same topic into one stronger page.
Whatever the reason, map each old URL to its closest equivalent. Pointing hundreds of deleted pages at the home page is tempting, but Google may treat such redirects as soft 404s, which means the old page is dropped and nothing is passed along. If a page has no real replacement, an honest 404 or 410 is the better answer.
Where 302 and 307 belong
Temporary redirects are for situations where the original URL will return: a few days of maintenance, a sold-out product sending visitors to its category, or an A/B test splitting traffic between variants. Entry pages that pick a language or region version for each visitor also tend to use 302, because the destination differs from person to person.
The common mistake runs the other way: a permanent move made with a 302 because that is what a plugin or framework emits by default. Google may eventually treat a long-standing 302 as permanent, but that is an opaque process you do not control. If you mean permanent, send a permanent code.
308 for APIs and form endpoints
If you are moving an API endpoint or a form handler permanently, use 308. A POST that hits a 301 can turn into a GET in some clients, the body disappears, and the server receives an empty request. In logs this shows up as data that never arrives, which is miserable to debug. The same logic applies to temporary moves: prefer 307 over 302 for anything that is not a plain page view.
What a 301 redirect does for SEO
Google's documentation on redirects describes permanent redirects (301 and 308) as a strong signal that the target should be canonical, and temporary ones (302 and 307) as a weak signal. In practice the new URL replaces the old one in results after a permanent redirect, while the old URL may linger after a temporary one. Google has said for years that 3xx redirects do not lose PageRank; the real losses come from redirecting to irrelevant pages and from long chains.
A migration checklist that holds up in practice:
- Build a one-to-one map of old and new URLs, one pair per line.
- Implement each redirect at the server, as a single hop straight to the final destination.
- Update internal links, XML sitemaps and canonical tags to the new URLs instead of relying on the redirects.
- Keep the redirects in place for at least a year, which is what Google's site move guide recommends. Longer does no harm if other sites still link to the old addresses.
- Watch the indexing and crawl reports in Search Console over the following weeks.
Redirect chains and loops
A chain is any path that takes more than one hop to reach the final page. The classic example is built from rules added over the years by different people:
| Hop | Request | Response |
| 1 | HTTP, shop.example/sale | 301 to the HTTPS version |
| 2 | HTTPS, shop.example/sale | 301 to www.shop.example/sale |
| 3 | HTTPS, www.shop.example/sale | 302 to the version with a trailing slash |
| 4 | HTTPS, www.shop.example/sale/ | 200 OK |
Every hop is a full request and response, and if the hostname changes there may be an extra DNS lookup and TLS handshake as well. On a slow mobile connection each one can add tens or hundreds of milliseconds before the page even starts loading. Google's documentation says Googlebot follows up to 10 redirect hops; beyond that the page may not be crawled at all. Notice the 302 in hop 3: a single temporary code in an otherwise permanent chain muddies the signal for the whole path.
Loops and ERR_TOO_MANY_REDIRECTS
In a loop the chain never ends: A points to B and B points back to A. Chrome stops with ERR_TOO_MANY_REDIRECTS, and Firefox reports that the page is not redirecting properly. The usual causes:
- A CDN or reverse proxy talks to the origin over plain HTTP while the application sends every HTTP request to HTTPS. The origin always sees HTTP, so the rule fires forever.
- One rule in the server configuration strips www while a CMS setting adds it back.
- A language or consent gateway redirects based on a cookie it never manages to set.
Collapsing a chain into one hop
- Run the starting URL through the checker and note each hop's status code and target.
- Identify the URL that finally returns 200; that is the real destination.
- Rewrite your rules so the first request goes straight there, for example by combining the HTTPS and www rules into one.
- Point internal links at the final URL, never at an intermediate one.
- Re-check after deploying, and test in a private window so a cached 301 in your own browser does not fool you.
How to check a redirect chain
Browsers follow redirects silently and only show you where you ended up. To see the path you need something that walks it one hop at a time. Knowing how the redirect checker on this site works helps you read its output correctly:
- The site's server, not your browser, requests the URL and lists each hop's status code and target in order.
- It follows at most 10 redirects; a longer chain ends with an error rather than a result.
- Only public http and https addresses are accepted. Ports other than 80, 443, 8080 and 8443, private network ranges, localhost and cloud metadata addresses are blocked for security.
- The page body is never downloaded, so meta refresh tags and JavaScript redirects are invisible; only redirects sent by the server as 3xx responses appear.
- Checks are rate-limited to 15 per minute.
Because the request comes from the server's location, without your cookies or login, sites that redirect by country, language or session may show a different chain than the one you see in your own browser. That is not a bug on either side; the site is simply treating two visitors differently.
Checking from the command line and DevTools
In a terminal, curl -sIL shop.example prints the headers of every hop; -I asks for headers only and -L follows redirects. Some servers answer header-only requests differently, so if something looks off, compare with a normal request. In the browser, open the Network panel, tick Preserve log and reload. If you see a line reading 307 Internal Redirect, that is the browser upgrading to HTTPS by itself because of an HSTS policy; the server never sent a 307.
Writing the rule on the server
On Apache, a single page needs one line: Redirect 301 /old-flask /products/steel-flask. On nginx the equivalent is location = /old-flask { return 301 /products/steel-flask; }. A relative path in the Location header is allowed by the standard; it is resolved against the current URL. Choosing short, lowercase slugs you will not want to change again is the cheapest way to avoid writing yet another rule next year.
Frequently asked questions
How long should a 301 redirect stay in place?
Google's guidance for site moves is at least a year. If other sites still link to the old URLs, keep the rules indefinitely; a redirect costs the server next to nothing, and removing it throws away whatever those links were worth.
I used a 302 for a permanent move. What now?
Search engines may keep the old URL indexed longer and show the new one late. Change the status code to 301 and that is enough; nothing else needs undoing. Re-check the chain afterwards.
Why does my browser still follow a redirect I removed?
Permanent redirects are cacheable, and browsers cache them aggressively. After fixing a wrong 301, your own browser may keep obeying the old one. Test in a private window or clear the cache.
Can a meta refresh or JavaScript redirect replace a 301?
Google can follow both, but a server-side redirect is the clearer and more reliable signal. Since they live in the page body, they also stay invisible to header-based checkers.
Large migrations usually live in a spreadsheet of old and new URLs; CSV vs JSON explains the quoting and delimiter traps you hit when exporting that map. For the other things that slow a page down before it renders, see what minification is and image optimization for SEO.