Avoid Custom mod_rewrite Rules with Varnish

When you are working on a website project running PHP on Apache, and you need to redirect a single device type to a different URL than the rest of your visitors, I’m sure the first thought that many of you would have is to utilize Apache’s mod_rewrite. It is a highly flexible URL rewriting engine that would allow you to rewrite with almost any combination of requirements to a just as complex set of URLs depending on the situation.

However, if you utilize a caching solution like Varnish, then this may not be a desirable solution. Lets say that that one device visits the url http://www.example.com/something/special and it causes a cache-miss. As a result, Varnish will pass the request on to the Apache web server which detects that you are using the special device, and it rewrites the request to deliver the appropriate special page for the special device. When the Apache web server returns its payload, Varnish takes that as the cacheable value for that specific URL. A few seconds later, a seperate, non-special device visits the page, and instead of getting the non-special payload, it gets the cached version of the special page. The exact opposite scenario could happen just as easily.

This occurs because Varnish’s main goal is to reduce the amount of traffic that makes it to your back-end web server. As a result, your Apache mod_rewrite rules are bypassed many times, rendering them useless when you could have multiple different returned results for the same URL requested.

One of the easiest and simplest ways around this is to move your rewriting of the device or browser specific rewrites into your Varnish configuration files. These support the same regular-expression powered custom rewriting abilities that you have with mod_rewrite, but without the caching layer messing things up.

Always make sure to do your rewriting as close to the client’s browser as possible. It makes things simpler, and can dramatically improve performance.

Related Posts

Jan 4, 2015
3 minutes

Top Job Applicants Never Stop Learning

From time to time, my job allows me to be a part of the hiring process for our technical positions. Unfortunately for some of the applicants, I repeatedly come away from these interviews amazed at the responses I get from pretty standard and basic technical questions related to Web Development.

Recently we were looking for a front-end web developer that was good at UX and design and proficient at HTML, CSS, and JavaScript. One of the things that we tend to ask everyone is to rate themselves on a scale of 1 to 10 as to how good they are with each technology. The majority of responses are in the 5-8 range with the corresponding answers to the questions about each techology falling about in the range you would expect. A couple of applicants were brave enough to rate themselves at a 9.5 out of 10 on HTML, CSS, and JavaScript, leading us to believe they were “exceptional applicants”.

Mar 29, 2014
2 minutes

301 Redirecting in Varnish

In Magento, you can set your secure and non-secure URLs explicitly. This works as expected in most cases, but can cause some issues when you have to specify full URLs or need to make any AJAX requests. When using the Nexcess Turpentine extension to enable Magento and Varnish to work together and you wish to only support traffic at www.example.com and not example.com, you would need to enable the setting in the Turpentine module to normalize the host.

Apr 23, 2014
2 minutes

Magento appending __SID to URLs

When trying to fully optimize a Magento website to run as fast as possible, I tend to opt for turning on all of the caching options in Magento, and then put the Varnish caching server in front of the web server with the Turpentine plugin. However, when you do this with some configurations, you start seeing the __SID query string parameter added to the end of the site’s url. Unfortunately, when the Turpentine plugin sees the __SID query string in the URL, it means that this page request will bypass the cache and load it directly from the server, slowing things down.