Set ttl etc. explicitly using a request header


I’m building a fastly proxy to a backend service I don’t own because said service doesn’t offer great caching. The vcl does very little other than read a few properties in the url query string to activate various caching presets


if (req.url ~ "interval=weekly") {
   beresp.ttl = 7d;

What I would love to do is something like sending a Cache-Control header with the original request, setting this to Surrogate-Control on the response, and thus allowing the caching of the response to be completely configurable via the request. But I can’t figure out where and how I should do this, or even if it’s possible.

Is it possible?


If you’re already using a proxy to contact a service you don’t control, intercepting and rewriting the Surrogate-Control headers leaving the proxy would be my honest recommendation. Of course, I’d recommend OSS Varnish as the proxy system :slight_smile:


Strictly speaking within VCL, your proposed solution doesn’t work straight up. This is because Surrogate-Control is evaluated before vcl_fetch is run.

However, you can set the TTL based on any header, using a couple of functions. It would look something like:

if (req.http.Cache-Control ~ "max-age=([0-9]+)") {
  set beresp.ttl = std.integer2time(std.atoi(;

Note, I didn’t test this code, but I think it should work.


thanks @drwilco. Your solution was what I first thought of doing but couldn’t find any info on converting strings to times, hence considering using surrogate-control directly. I’ll try your solution now


For testing, is it possible to specify which fastly node a response should be routed to?


For reference, here is a working solution

One thing that held me up for ages - and I’m not sure where this is/should be documented - but req.http.Cache-Control could not be read within vcl_fetch, hence the proprietary Cache-Strategy header


Were you trying to read Cache-Control in the request or in the origin response?