Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cache an object on Varnish, but tell the client not the cache it

Tags:

I am caching the product details page on Varnish, and then I purge the cache from the backend server whenever the product is updated. I want my clients to never cache this page on their side, but always ask from Varnish, so that I can serve them the most recent copy.

Currently, I have the below config for vcl_backend_response:

sub vcl_backend_response {
    unset beresp.http.Set-Cookie;
    #unset beresp.http.Cache-Control;
    #set beresp.http.Cache-Control = "no-cache";

    if (bereq.url ~ "^/products/\d+/details") {
        set beresp.ttl = 1h;
    }
}

But, using this config, client caches the response for 1 hour, and does not ask again, even the cache is purged on Varnish.

If I uncomment the cache-control related lines, this time Varnish does not cache the page and always asks for a fresh copy from the backend server.

Is this achievable in Varnish v6.0?

like image 456
fkoksal Avatar asked Dec 06 '18 02:12

fkoksal


People also ask

How do you know if Varnish is caching?

To verify that Varnish is proxying look for the existence of the X-Varnish header in the response. The Age header will be 0 on a cache miss and above zero on a hit. The first request to a page will always be a miss.

Does Varnish cache files?

June 29, 2017. Varnish Cache is a popular tool due to how quickly it delivers content from the cache and how flexible it can be. Using Varnish Cache's domain-specific language, Varnish Cache Configuration Language (VCL), users can cache both static and so-called “dynamic” content, also known as the HTML document.

How does Varnish caching work?

Varnish cache is a web application accelerator also known as caching HTTP reverse proxy. It acts more like a middle man between your client (i.e. user) and your web server. That means, instead of your web server to directly listen to requests of specific contents all the time, Varnish will assume the responsibility.


1 Answers

Yes, it's possible:

  • Define the logic for how long things are cached by Varnish inside the vcl_backend_response.
  • Define the logic for how long things are cached by browser cache inside the vcl_deliver.

So clients (browsers) can be instructed to cache with a different TTL than Varnish. The following will ensure that browsers will not cache response:

sub vcl_deliver {
    set resp.http.Pragma = "no-cache";
    set resp.http.Expires = "-1";
    set resp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0";
}

Moreover, if you can modify your app, you can resort to a much finer approach outlined in first solution here, that is sending a single Cache-Control header which defines caching TTL for shared caches (Varnish) and private caches (browser) differently:

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

The header above will instruct a browser to cache resource for 86400 seconds, while Varnish will cache for 31536000. This is because s-maxage only applies to shared caches. Varnish evaluates it, while browsers don’t.

like image 73
Danila Vershinin Avatar answered Oct 13 '22 08:10

Danila Vershinin