301 Moved Permanently: how permanent redirects work

301 Moved Permanently sends visitors and crawlers to a new permanent URL and tells Google to consolidate ranking signals there.

Check a URL’s status code

301 Moved Permanently tells browsers and crawlers that a URL has a new, permanent address, given in the Location header. It’s the standard tool for site migrations, HTTPS moves, domain changes and merged pages, because it moves both visitors and search signals to the new URL. The glossary entry on the 301 redirect covers the concept; this page covers the status code itself.

What the spec says

Under RFC 9110, section 15.4.2, a 301 means the target resource “has been assigned a new permanent URI” and future references should use it. Two details matter in practice:

  • A 301 is cacheable by default, so browsers can remember it for a long time. A wrong 301 can stick in visitors’ browsers even after you remove it from the server.
  • For historical reasons, clients may switch a POST to GET when following a 301. If the method must be kept (forms, APIs), use 308 Permanent Redirect.

How Google handles 301 redirects

Google’s documentation on HTTP status codes says Googlebot follows the redirect and the indexing pipeline uses it as a strong signal that the target should be canonical. Over time the new URL replaces the old one in results and inherits its signals, including links. Google treats 308 the same way.

Googlebot follows up to 10 hops in a chain, but every extra hop costs time and crawl resources, so point each old URL straight at its final destination. For moves, Google’s site move guide recommends keeping redirects in place as long as possible, generally at least a year.

Common 301 mistakes

  • Chains and loops: http to https to www to trailing slash, four hops where one would do (see redirect chains).
  • Redirecting everything to the home page. Google may treat irrelevant redirects as soft 404s; send each URL to its closest equivalent.
  • Using a 302 for a permanent move, so the old URL lingers in results. Many frameworks default to 302.
  • Internal links and sitemaps still pointing at old URLs. Update them so crawlers reach final URLs directly.
  • Canonical tags that contradict the redirect, such as a target page whose canonical points back to the old URL.

How to set up a 301

Apache (.htaccess)

# One page
Redirect 301 /old-page/ https://www.example.com/new-page/

# Whole site to https://www in a single hop
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.example.com%{REQUEST_URI} [L,R=301]

Behind a CDN or load balancer that terminates TLS, %{HTTPS} may always be off, which creates a loop; test the forwarded protocol header instead.

Nginx

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://www.example.com$request_uri;
}

location = /old-page/ {
    return 301 /new-page/;
}

On WordPress and other CMSs, a redirect manager plugin or your host’s redirect settings do the same job without editing server files.

How to check your redirects

Run old URLs through the redirect checker to see every hop, its status and its Location, and to catch chains or loops. For a list of migrated URLs, the bulk HTTP status checker shows each code and redirect target, and the canonical checker confirms the destination is self-canonical. A clean 301:

HTTP/1.1 301 Moved Permanently
Location: https://www.example.com/new-page/
Content-Type: text/html; charset=iso-8859-1
Content-Length: 245

Frequently asked questions

Does a 301 redirect pass link value?

Yes. Google treats a 301 as a strong signal that the target is the canonical URL and consolidates signals, including links, onto it. That works best when the target is a genuine equivalent of the old page.

How long should I keep 301 redirects?

Google’s site move guidance says to keep them as long as possible, generally at least a year. Keep them longer if the old URLs still get links or traffic; removing them turns those visits into 404s.

Should I use 301 or 308?

For ordinary page moves, both work the same in Google Search. Use 308 when the request method must be preserved, such as POST requests to a moved form or API endpoint.