Tips
Which redirect status code to use when you move a site
301 and 308 are permanent in the HTTP spec and in Google's redirect doc. 302, 303 and 307 are temporary in both. What each one means, quoted from the source.
For a URL that has moved for good, answer with a 301 or a 308. Both are permanent in RFC 9110, the HTTP standard, and Google’s redirect doc lists both as permanent. 302, 303 and 307 are temporary in both documents. A meta refresh is not an HTTP status code at all. Google reads an instant one as permanent and a delayed one as temporary.
The quotes below are from RFC 9110 and from Google Search Central’s Redirects and Google Search. We read both on 8 November 2026. Google’s page was last updated on 14 April 2026.
| Redirect | RFC 9110 | Google’s redirect doc | one-hop |
|---|---|---|---|
| 301 Moved Permanently | Permanent. A POST can turn into a GET | Permanent | Passes |
| 308 Permanent Redirect | Permanent. The method is kept | Permanent | Passes |
| 302 Found | Temporary | Temporary | Fails, unless you pass --allow-temporary |
| 303 See Other | Points to a different resource | Temporary | Fails, unless you pass --allow-temporary |
| 307 Temporary Redirect | Temporary. The method is kept | Temporary | Fails, unless you pass --allow-temporary |
| meta refresh, 0 seconds | Not defined there | Permanent | Fails: the old URL answers 200 |
| meta refresh, delay | Not defined there | Temporary | Fails: the old URL answers 200 |
What Google’s doc says permanent and temporary do
Google splits redirects into two groups, by what it shows in search results:
“Permanent redirects: Show the new redirect target in search results. Temporary redirects: Show the source page in search results.”
For a permanent redirect, “Googlebot follows the redirect”. Then “the indexing pipeline uses the redirect as a signal that the redirect target should be canonical”. For a temporary one, it follows the redirect but doesn’t use it as that signal. The doc adds that “the target page might still be indexed if other canonicalization signals are present.”
The doc orders its table “by how likely Google is able to interpret correctly”. Server-side redirects come first. For a page whose address has changed, it says “we recommend that you use a permanent server-side redirect whenever possible.”
301 and 308
RFC 9110 gives both the same meaning, in the same words (15.4.2, 15.4.9):
“[T]he target resource has been assigned a new permanent URI and any future references to this resource ought to use one of the enclosed URIs.”
The difference is the request method. On 301 the spec says “a user agent MAY change the request method from POST to GET”. A 308 doesn’t allow that. Page requests from browsers and crawlers are GETs, so for a site move the two do the same job.
The spec has one caution about 308. It “is much younger (June 2014) than its sibling codes”. So it “might not be recognized everywhere.” When we moved this site in September 2026, the map’s 1,911 redirects were all 301s. The migration write-up has the counts.
302 and 307
Both mean the move is temporary. 302 says the target “resides temporarily under a different URI”. The client “ought to continue to use the target URI for future requests” (15.4.3). 307 says the same and adds that the user agent “MUST NOT change the request method” (15.4.8).
Google’s doc gives a use for them: a service that is down for a while. A temporary redirect sends people to a page that explains it, “without compromising the original URL in search results.” That is not a site move.
303
303 is for answering a request with a different resource, usually after a form post. In the spec’s words (15.4.4):
“This status code is applicable to any HTTP method. It is primarily used to allow the output of a POST action to redirect the user agent to a different resource…”
It adds that “the new URI in the Location header field is not considered equivalent to the target URI”. Google lists it with the temporary redirects. It doesn’t fit a moved page.
Meta refresh
A meta refresh is a tag in the HTML, so the old URL answers 200 and the browser moves on after reading the page. RFC 9110 doesn’t cover it. Google’s doc says to use it when server-side redirects “aren’t possible to implement on your platform”. It treats the two kinds differently:
“Google Search interprets instant meta refresh redirects as permanent redirects.”
A refresh with a delay of more than 0 seconds counts as temporary. one-hop fails both, because it checks status codes and an old URL that answers 200 has not redirected.
Check the map after the move
A redirect map can be right row by row and still send each old URL through two or three hops. A server rule that adds a trailing slash first is enough to do it. one-hop reads your map and, by default, fails any row that isn’t a single 301 or 308 to a page that answers 200.
pip install one-hop
one-hop redirects.csv --base https://example.com
The technical SEO page covers how we run migrations for clients.