Caching Cookie headers

“I can’t cache this piece of content because it has a Cookie header” any web developer/sysadmin following the so called “caching best practices”.

Well, turns out nowadays pretty much every piece of content has at least a cookie header and so does every single user. Does it mean it’s not possible to cache anything?
Absolutely NOT. We can cache anything we want to, we only need to pay some extra attention to it as we don’t want to deliver content to the wrong users.

We have two types of cookie headers:

  • cookie for tracking: those headers are used to track the user journey on a website or when browsing The Internet. These headers most of the time don’t bring private users information because they are mostly used to come up with personalized content, based on the browsed pages, for each specific consumer.
  • cookie bringing private users information: those cookies, instead, contain a lot of private information nobody wants to leak. I.e. they can be associated to credit cards credentials(you don’t want to leak those).

The good news it that with Varnish, using VCL, you can cache both of them. By logic, you will understand it is worth having an extra check for the second case.

Here’s the VCL

Caching tracking cookies with Varnish

sub vcl_recv {
    set req.http.Cookie-Backup = req.http.Cookie;
    unset req.http.Cookie;

  sub vcl_hash {
    if (req.http.Cookie-Backup) {
      # restore the cookies before the lookup if any
      set req.http.Cookie = req.http.Cookie-Backup;
      unset req.http.Cookie-Backup;


By default Varnish won’t cache content if a Cookie or a Set-Cookie header is present, that’s because it’s better “being safe than sorry” and Varnish won’t take responsibilities for caching with present cookies, but you can still instruct it to do so.

In vcl_recv when Varnish receives the request, we save the original Cookie header is a new Cookie-Backup header and unset the original headers. This allows Varnish to create an hash key or to lookup for an already existing object in cache, without unsetting the Cookie header the cache would be bypassed by default and no content cached, hence the little trick.
Once we are sure Varnish will either create a fresh hash key for a new object or lookup the cache for an already cached piece of content, we can set again the Cookie header and add it to the hashing scheme(in vcl_hash).

Caching a private cookie with Varnish

sub vcl_hash {
     if (req.http.Cookie && req.url ~ ”/user-cart”) { 
       # add Cookie in hash 

This second examples follow the same logic as the previous one adding the Cookie header to the scheme when creating a hash key for a new object to be inserted in cache or when using it to lookup an object already in cache.

The main difference here is that we want to run an extra check, making sure the requested URL is related to the user-cart of an e-commerce website which is where the payment happens and where you want to make sure not to be messy.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s