Efficient 301 Redirects

Traditionally, web sites use either www or non-www version to display their content to the visitors. Sub-domains are also becoming popular in recent times. When www is chosen as the preferred domain when installing WordPress (or after installing WordPress), whenever a visitor types non-www version of the site, WordPress redirects the visitor to the correct URL, the www version the site, through an internal 301 redirect. Google recommends this 301 redirect and Google WebMaster Tools has an option to set the preferred domain too.

In performance optimization, every tiny improvement helps to speed up and scale up the site. When 301 redirect is done by WordPress, it requires PHP to be processed. When 301 redirect is done at the server level, without using PHP, the process is more efficient, so requires less time to execute.

Let’s see how newbie webmasters traditionally set up 301 redirects in Apache and in Nginx…

Apache 301 redirect (non-www to www – traditional way)


<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^domainname\.com$ [NC]
    RewriteRule ^(.*)$ http://www.domainname.com/$1 [R=301,L]
</IfModule>

Apache 301 redirect (www to non-www – traditional way)


<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^www.domainname\.com$ [NC]
    RewriteRule ^(.*)$ http://domainname.com/$1 [R=301,L]
</IfModule>

Nginx 301 redirect (non-www to www – traditional way)


server {
    server_name domainname.com;
    rewrite ^/(.*)$ http://www.domain.com/$1 permanent;
}

Nginx 301 redirect (www to non-www – traditional way)


server {
    server_name www.domainname.com;
    rewrite ^/(.*)$ http://domain.com/$1 permanent;
}

As already mentioned, above methods are done at the server level that is more efficient than doing at the application level (read application = WordPress) and every bit of improvements helps. So, let’s break the tradition and see how we could achieve the same in a more efficient way, using Apache and Nginx.

In Apache, we need to split the virtualhost entries like below…

Apache 301 redirect (non-www to www – new, efficient, & the best way)


# Assuming that Apache listens on 127.0.0.1
<VirtualHost 127.0.0.1>
  ServerName domainname.com
  <IfModule mod_alias.c>
    Redirect permanent / http://www.domainname.com/
  </IfModule>
</VirtualHost>

<VirtualHost 127.0.0.1>
  ServerName www.domainname.com
  # other directives to process www.domainname.com
</VirtualHost>

Apache 301 redirect (www to non-www – new, efficient, & the best way)


# Assuming that Apache listens on 127.0.0.1
<VirtualHost 127.0.0.1>
  ServerName www.domainname.com
  <IfModule mod_alias.c>
    Redirect permanent / http://domainname.com/
  </IfModule>
</VirtualHost>

<VirtualHost 127.0.0.1>
  ServerName domainname.com
  # other directives to process domainname.com
</VirtualHost>

The above examples assume that mod_alias Apache module is present in the server. When in doubt, ask your host or server admin. For the following examples that use Nginx, no extra modules needed to make them work. The return directive is part of the standard Rewrite module in Nginx.

Nginx 301 redirect (non-www to www – new, efficient, & the best way)


server {
    server_name domainname.com;
    return 301 $scheme://www.domainname.com$request_uri;
}

Nginx 301 redirect (www to non-www – new, efficient, & the best way)


server {
    server_name www.domainname.com;
    return 301 $scheme://domainname.com$request_uri;
}

In the above examples, by using Redirect directive of Apache and return directive of Nginx, we can effectively avoid doing any capturing or matching at all and thus we can completely avoid evaluation of a regular expression.

If you are using Varnish, then I already published a blog post on how to do 301 redirects using Varnish.

Update: On March 11, 2017

Nekraj Bharitya asked a good question in the comments

Question: How can we check wheter my site is using 301 or 302 redirect?

Answer: We may use an online tool such as Redbot to check it.

16 Replies to “Efficient 301 Redirects”

  1. Hi,

    I included your rewrite rules, when I restart nginx I get the following warning:

    nginx: [warn] server name “$scheme://www.XXXXXXX.tld$request_uri” has suspicious symbols

  2. Using the “Redirect permanent” method causes a redirect loop because there is no condition to fulfill.
    At least that is what I get on my test Apache servers using Firefox and Chrome.

      1. No problem, glad I could help.
        Unfortunately, this new method requires that you have access to the server config file… something not usually permitted on shared hosts.

  3. Hello,
    Excellent article!
    However, it’s not working for me. I’m using apache 2.4 (in Centos 7), and am trying to use the www to non-www redirect. It’s working for http, but not for https.
    I’ve tested both options (traditional and new), with the same results.
    Any issue with apache 2.4 regarding this?

    Thanks!

    1. Sorry about that. I haven’t used Apache for a while. So, I haven’t tested it with the recent versions of Apache. Probably, something is indeed wrong with my example code.

Leave a Reply

Your email address will not be published. We use cookies to prevent spam comments. Required fields are marked *

css.php