Tiny WordPress Insights

Varnish 301 Redirect

Note (as of August 30, 2017): The original post was published for Varnish 3. A lot changed since then. Currently, we have a nicer way to achieve 301 redirects. Thanks!

Varnish is a powerful caching HTTP reverse proxy server. It can sit in front of Apache or Nginx and can cache the requests that are configured to be cached. Varnish offers a lot of flexibility on what to cache and what not to cache. However, it doesn’t offer any simple redirection by default. When it stands in front of a general purpose web server, it sends the requests to the backend (in our case, Nginx), and then sends the backend response to the browser. While this is the natural process, there are a couple of ways to reduce this round-trip and save a bit of time. After all, every millisecond counts!

Solution 1

We could increase the TTL to 52 weeks, like the following example…

sub vcl_fetch {
  if (beresp.status == 301) {
    beresp.ttl = 52w;
  }
}

In this method, only the first request goes to the backend. The consecutive requests to the same URL would probably never reach the backend (at least for the next 52 weeks), as the backend response has been cached by Varnish. You may change the TTL value to suit your particular scenario.

Solution 2

This uses a dirty trick! Here is how it’s done here in this site…

sub vcl_recv {
    if ( req.http.host ~ "^(?i)(www.)?tinywp.in" &&
            req.http.X-Forwarded-Proto !~ "(?i)https") {
    error 750 "Moved Permanently";
    }
}

sub vcl_error {
    if (obj.status == 750) {
    set obj.http.Location = "https://www.tinywp.in" + req.url;
    set obj.status = 301;
    return (deliver);
    }
}

In this method, Varnish offers 301 redirection using vcl_error logic. It still saves some milliseconds, rather than going to the backend and then to serve its response on each client request. Here, the error code 750 is just a temporary and imaginary status code (here’s the list of all valid HTTP status codes) used by Varnish, as mentioned in the comments below (thanks to Jesin for the question).

My preference is with the solution #1. You may use solution #2, depending on the use-case (ex: if you wish to save a bit of memory). If you have any other solution, please feel free to share it in the comments!

If you don’t use Varnish on port 80, then you may benefit from the new way of doing 301 redirects at the server level using Apache or Nginx.

Exit mobile version