TTL and Grace Time in Varnish Cache

Or: how to deliver cached content fast while doing a background refresh, or while your backend is down


Almost every cache solution has a time-to-life feature after which an object completely expires. Of cource Varnish has that too, but it goes one step further, and that's so awesome to use for these two use cases:

Deliver stale content while refreshing in the background

If you set a page to expire after 1h, and that very same page gets visited after 1h and 1s, that page is expired, your backend has to be requested for a fresh version, your visitor waits, and waits, and waits, and finally, it's there, great.

Now imagine the same scenario with Grace time of 1h: If you set a page to expire after 1h, and that very same page gets visited after 1h and 1s, that page is expired, your backend has to be requested for a fresh version, BUT your visitor gets delivered the stale version of the expired content WHILE the refresh takes place in the background. No more waiting time.

The only bad thing is: the first visit for that expired page gets old content. But on the plus side: your visitor does not have to wait.

This is especially important if you have a very traffic intensive page, with a lot of moving parts, maybe even some edge side includes (ESI) doing their job, and small TTLs. You just don't want your visitors to wait, you want the pages to be delivered blazingly fast. Grace time will help you with that.

Deliver stale content while your backend is down

Another "Let's imagine"-scenario: Your backend is down because of maintenance, overload, probe failues, errors, whatever. If your visitor requests a page which is already in grace land, but your backend is down, it will be delivered anyway. That's why it makes sense to set a high grace time. BUT, as always: It depends on your use case, if at all, and how much of grace time you like to use, so be strategic about it. But most of the time it helps to have a high grace time. Just make sure that your uptime monitoring tools don't hit cached content in case of backend failure. But that's for another article...

So let's do it

Setting grace time is quite easy. Either you do it via responding with the correct cache headers:

{htmlentities(Cache-Control: public, s-maxage=3600, stale-while-revalidate=7200)}

This means a TTL of 1h and Grace time of 2h.

Or you do it in your Varnish configuration in the backend response part:

{htmlentities(sub vcl_backend_response {
  set beresp.grace = 2h;
})}

There is more

For more indepth information, head over to a nice tutorial about Object lifetimes from Varnish Software or even the docs or the Two-Minute Tech Tuesdays - Grace Mode