Sub-second TTLs in Varnish Cache

Sub-second TTLs in Varnish Cache

Typically the backend instructs Varnish how long to cache content through the Cache-Control header. The resolution here is relatively coarse - seconds. I'll show you how to create rules for caching with sub-second precision.

The TTL (beresp.ttl, actually) already has subsecond precision. So, we can set the TTL to any decimal value. However, when parsing Cache-Control we adhere to RFC2616 and interpret is an integer. So, in order to have decimal precision we need a way to pass a decimal number to Varnish. 

First things we need is to load the std module. It gives us the duration function which makes it possible to work with, obviously, durations. Now we can just pick the TTL out of a random header and set the TTL. VCL:

import std;
sub vcl_fetch {
   #  Set TTL to whatever x-max-age tells us or 120s
   set beresp.ttl = std.duration(beresp.http.x-max-age + "s", 120s);
}
 
Now, we could enhance this somewhat. I would like it to not be so blunt. This code will override Cache-Control blindly. If some backend objects still would use Cache-Control that would be silly. Also, it would be nice to se the TTL set on an object.
 
import std;
sub vcl_fetch {
   if (beresp.http.x-max-age) {
      set beresp.ttl = std.duration(beresp.http.x-max-age + "s", 120s);
      # Set a response header.
      set beresp.http.x-subsecond-max-age = beresp.ttl;
   }
}

Can we improve this further?

 

Add comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Type the characters you see in this picture. (verify using audio)
Type the characters you see in the picture above; if you can't read them, submit the form and a new image will be generated. Not case sensitive.

Comments

Are you saying that beresp.ttl can be set to a decimal number of seconds, possibly less than 1, by whatever mechanism we choose? I think that needs to be more clearly stated in the article, if so.

Per Buer's picture

Yes. You can set beresp.ttl to a decimal number. Could very well be less than 1.

I was thinking about using some inline C (stolen from: http://open.blogs.nytimes.com/2010/09/15/using-varnish-so-news-doesnt-br... ), but I'm glad to have found this article first.

I'm going to add "X-Varnish-TTL" or similar response header, and allow my (Drupal) instance to set those for some paths, while keeping Cache-Control intact (for client-side caches and proxies).