Using Varnish and Browser Caching Together: Is It Effective?

cachehttphttp-headersvarnish

I'm a bit confused about what the best practice is when using Varnish: I saw many sites where I know they were using Varnish, which had Cache-Control: no-store, no-cache, must-revalidate HTTP headers activated. Their website content is not changing since a long time – so why aren't they using Browser caching? Maybe they want to have a better control over the content, if they need to change something quickly, which would otherwise be in a stale condition in Browser cache?

So, basically I would like to know if I should leverage Varnish AND Browser caching, or only Varnish for a website, which serves content which does not change? Is there any rule here, what would be "best practice"? Usually I would have gone for Varnish AND Browser caching, but the aforementioned websites I saw got me confused about that.

Best Answer

You should use both and those are 2 entirely different things.

  • Browser cache is a cache in your computer. Its primary purpose is preserving bandwidth, reducing latency by using assets which were already seen / downloaded.
  • Varnish cache is a cache on the server where website is hosted. Its primary purpose is reducing strain of the server from running CPU intensive scripts (e.g. PHP)

The two caches can have different lifetime for a cached entry / different cache policy and this is fine. It depends on the nature of the resource you're caching.

Pages (HTML)

Just because you see Cache-Control: no-store, no-cache, must-revalidate when checking a website e.g. via curl, it does not mean that there is no Varnish and it does not cache things.

Take Magento 2 for example. Magento itself sends:

Cache-Control: max-age=86400, public, s-maxage=86400

This is what Varnish sees. So the page will be cached by Varnish appropriately for 1 day. However, in the Varnish VCL for Magento 2, it will modify Cache-Control on the way out, to ensure that browsers do not cache at all. So the response that you will see:

Cache-Control: no-store, no-cache, must-revalidate, max-age=0

Why this is so:

  • To ensure the heavy lifting of PHP engine is eliminated, Varnish caches pages and delivers them from its cache
  • Browsers have to always fetch fresh pages (we are talking about product pages and such), so they should not cache at all
  • When a product page is updated (by admin), Magento does the job of talking to Varnish to clear the cached page. For obvious reasons, it cannot say "remove me from cache" to browser caches, which is why the browsers should not cache the page

Static assets

In browser

You typically want to cache static assets by browser, this is why for this type of resources, you'd see Far Future Expires headers, like the following:

Expires: Sat, 03 Aug 2019 14:24:01 GMT
Cache-Control: public, max-age=30672000

In Varnish

For these resources, many people like to configure Varnish not to cache them. This is because there's no heavy lifting of PHP to emit those files by server so it makes little sense to have them cached on the server at all. Especially taking into account that Varnish cache uses RAM storage backend by default (You can partition your cache for static files though).