301 redirect
A 301 redirect permanently sends visitors and search engines from an old URL to a new one. It is the standard tool for relaunches, domain moves and URL changes. Here is how it works, how to set it up and how to avoid the classic mistakes.
What is a 301 redirect?
301 Moved Permanently is an HTTP status code defined in RFC 9110. When a browser or crawler requests the old URL, the server does not deliver content but answers with the status code and a Location header containing the new address:
GET /old-page/ HTTP/1.1
Host: example.com
HTTP/1.1 301 Moved Permanently
Location: https://example.com/new-page/
The browser then requests the new URL automatically. Visitors hardly notice anything, apart from the changed address bar. The important word is permanently: you tell every client that the old URL will not come back and that references to it should be updated.
What a 301 does for SEO
According to Google Search Central, a 301 has two effects:
- It passes PageRank to the target. Backlinks to the old URL keep their value. (By the way, this is true for all redirect types, including 302.)
- It is a strong canonicalization signal. Google will usually replace the old URL with the new one in the index and in search results. This is the actual difference from a 302, which is only a weak signal. The comparison is explained in detail in 301 vs. 302.
Rankings do not transfer instantly. Google has to recrawl the old URL, see the redirect and process the new page. For single pages this often takes days, for a large site move weeks. During that time it is normal for old and new URLs to appear side by side.
When to use a 301
- Changed URLs: a new URL structure after a relaunch, a renamed slug, a removed
.htmlextension. - Domain move: every old URL to the matching URL on the new domain (see the domain migration checklist).
- Protocol and host: HTTP to HTTPS and www to non-www (or the other way round).
- Merged content: several thin articles combined into one comprehensive guide.
- Deleted page with a real successor, for example an old product replaced by its new version.
Do not use a 301 for temporary situations (maintenance, campaigns, A/B tests: use 302) or for deleted pages without an equivalent replacement (answer 404 or 410 instead).
How to set up a 301 redirect
Where you configure the redirect depends on your stack. The closer to the server, the faster and more reliable. Here are the most common variants in short, with links to the detailed platform guides.
Apache (.htaccess)
For a single page, mod_alias is enough:
Redirect 301 /old-page/ https://example.com/new-page/
Note that Redirect is a prefix match: /old-page/anything is redirected to /new-page/anything as well. If you only want the exact URL, use RedirectMatch:
RedirectMatch 301 ^/old-page/$ https://example.com/new-page/
For a whole domain, mod_rewrite is the usual choice. It keeps the path and the query string:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^old\.example\.com$ [NC]
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
Always write R=301 explicitly: a bare [R] sends a 302. Also avoid mixing Redirect and RewriteRule for the same URLs, since the two modules are processed independently and the result is hard to predict. Details and many more patterns are in the .htaccess guide, or you can use the .htaccess redirect generator.
nginx
In nginx, use return. It is faster and easier to read than rewrite:
# single page
location = /old-page/ {
return 301 https://example.com/new-page/;
}
# whole domain, keeps path and query string
server {
listen 80;
listen 443 ssl;
server_name old.example.com;
# ssl_certificate ... (a valid certificate is still required for HTTPS requests)
return 301 https://example.com$request_uri;
}
More in the nginx redirect guide and the nginx redirect generator.
PHP
If you cannot touch the server configuration, you can redirect in the application. Send the header before any output and stop the script afterwards:
<?php
header('Location: https://example.com/new-page/', true, 301);
exit;
Without the third parameter, PHP sends a 302. And without exit, the rest of the script keeps running, which can lead to unexpected side effects.
Other platforms
CMSs, CDNs and hosting platforms have their own mechanisms: redirect plugins in WordPress, redirect rules in Cloudflare, redirects() in Next.js, configuration files on Vercel and Netlify, and the URL Rewrite module in IIS. Watch out: Next.js and Vercel use 308 instead of 301 for permanent redirects. Google treats both the same, so that is fine.
Common 301 mistakes
- Accidentally sending a 302. Many tools default to 302 (PHP's
header(), Apache'sRedirectwithout a code,[R]without a number). Always check the actual status code. - Redirect chains.
http://example.com/old→https://example.com/old→https://www.example.com/old→https://www.example.com/new. Every hop adds latency, and Google follows at most 10 hops. Point every old URL straight to its final destination. See redirect chains. - Redirect loops. A points to B and B back to A, often caused by contradicting rules in the server config, a CMS and a CDN at the same time. The browser gives up with "too many redirects".
- Everything to the home page. Redirecting all old URLs to
/during a relaunch is convenient but bad for users, and Google tends to treat such redirects as soft 404s. Map each old URL to its closest equivalent. - Losing the path or query string. A domain redirect that sends every URL to the home page of the new domain, or drops
?id=123, breaks deep links and tracking. - Target does not return 200. A redirect to a page that answers with 404, a login page or another redirect wastes the signal. The final hop should always be a
200 OK. - Old signals left behind. Internal links, the XML sitemap,
rel="canonical"and hreflang tags should point to the new URLs directly, not rely on the redirect. - Removing redirects too early. Keep 301s for at least a year, and for URLs with backlinks ideally for good.
- Testing in a browser with a cached 301. Browsers cache 301 responses aggressively, so after changing a rule you may still see the old behaviour. Test new rules with a 302 first, or use a tool without a browser cache.
How to test a 301 redirect
The quickest way is our redirect checker: enter the old URL and you see every hop with its status code, target URL and response time, plus hints for chains, loops or temporary codes. You can also choose the user agent, for example Googlebot, to see what the crawler gets. For many URLs at once, for example after a relaunch, use the bulk redirect checker.
On the command line, curl shows the raw response:
curl -I https://example.com/old-page/
HTTP/2 301
location: https://example.com/new-page/
With curl -IL curl follows all hops and prints the headers of each response, so you can check that the chain ends with a 200.
A good test routine after setting up redirects:
- Status code is 301 (or 308), not 302.
- Exactly one hop from the old URL to the final URL, also starting from
http://and with or withoutwww. - The final URL answers with 200 and is the canonical URL.
- Path, trailing slash and query string are kept where they should be.
Frequently asked questions
- Does a 301 redirect lose link equity?
No. Google has confirmed that 301 redirects (like all other redirect types) pass PageRank. What can cost rankings is a poor target: if the new page does not match the old content, the old rankings will not carry over.
- How long does it take for Google to process a 301?
Google has to recrawl the old URL first. For single pages that is often a matter of days; for large sites with many URLs, a complete move can take weeks to months. Updating internal links and the sitemap speeds it up.
- Can I undo a 301 redirect?
On the server, yes: just remove the rule. But browsers that have already seen the 301 may have cached it and keep redirecting until the cache entry expires. Search engines will pick up the change on the next crawl. That is why you should only use 301 when the move is really final.
- Is a 301 redirect the same as a canonical tag?
No. A 301 sends users and crawlers to another URL, and the old page is no longer reachable. A
rel="canonical"tag leaves both pages accessible and only hints to search engines which one should be indexed. If the old URL should not be visited any more, use a 301.
Related guides
-
301 vs. 302 redirect
A 301 says "this URL has moved for good", a 302 says "look over there for now". The difference sounds small, but it affects which URL Google indexes, how long browsers remember the redirect and how easy it is to undo.
-
307 vs. 308 redirect
307 and 308 are the strict siblings of 302 and 301: they guarantee that a POST stays a POST. Here is what that means in practice, why you often see a 307 that your server never sent, and when a 308 is the better permanent redirect.
-
Meta refresh and JavaScript redirects
Not every redirect happens on the server. A meta refresh tag or a line of JavaScript can also send visitors to another URL. Here is how these client-side redirects work, how Google handles them and why they should only be your fallback.