Kevin Gleeson
Kevin Gleeson

Reputation: 133

How to Set Varnish Cache-Control Headers

I am hoping someone can advise on the proper method for getting Varnish to send cache-control headers. Currently, my configuration is sending "Cache-Control: no-cache" to clients.

Thanks in advance to anyone who might be able to help...

Upvotes: 11

Views: 44047

Answers (3)

Mike Ciffone
Mike Ciffone

Reputation: 371

In 2024 this is proper:

sub vcl_backend_response {
    if (beresp.status == 200) {
        set beresp.ttl = 5m; # Adjust as needed
    }
    set beresp.http.X-Varnish = bereq.xid;
}
sub vcl_deliver {
    if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT"; # These can be custom
    } else {
        set resp.http.X-Cache = "MISS";
    }
    set resp.http.Age = req.http.Age; # it might set automatically
    set resp.http.X-Varnish = req.http.X-Varnish; # Set X-Varnish
}

Upvotes: 0

Rudd-O
Rudd-O

Reputation: 116

Varnish ignores Cache-Control: nocache as per the documentation. Here is evidence confirming that:

http://drupal.org/node/1418908

To get that result, you should detect the header Cache-Control .nocache. from your backend, and then invalidate the cache, set the backend response to not cacheable, or issue max-age: 0 in the other header (I forget the name right now).

Upvotes: 4

ivy
ivy

Reputation: 5559

Your back-end is sending "Cache-Control: no-cache" to Varnish which implies two things:

  • Varnish will not store the response in the cache (so a next lookup will fail)
  • Your clients (browsers and intermediate proxies) will not cache responses (and request them over and over).

The solution is simple: remove the cache-control headers after fetching the response from the back-end (and before storing them in the cache).

In your vcl file do:

sub vcl_fetch {
  remove beresp.http.Cache-Control;
  set beresp.http.Cache-Control = "public";
}

You can choose to only do this for certain urls (wrap it in ( if req.url ~ "" ) logic) and do way more advanced stuff.

Upvotes: 15

Related Questions