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.

9 thoughts on “Efficient 301 Redirects

  1. Gary MadeoGary Madeo

    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

    Reply
  2. RaduRadu

    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.

    Reply
      1. RaduRadu

        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.

        Reply
  3. Pingback: Varnish 301 Redirect | Tiny Web Performance Insights

  4. GuillermoGuillermo

    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!

    Reply
    1. PothiPothi

      Hi,

      Both methods are supposed to work on Apache 2.4, if we have mod_rewrite and/or mod_alias enabled. Can you please check if they are enabled by running apachectl -M on your CentOS7 server?

      If they are enabled and if these method still didn’t work, I am glad to have a look into your server, if given a chance. In that case, please contact me.

      Thank you,
      Pothi

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *