In this week’s episode of Two-Minute Tech Tuesday, we're explaining how the total lifetime of a cached object is calculated.
The total lifetime of an object is often associated with its time to live, or TTL, which can be set through a Cache-Control header, through VCL, or by relying on the default value of 120 seconds. However the lifetime is not equal to the TTL, there's much more to it. The actual total lifetime of an object is the sum of the TTL, the "grace" value and the "keep" value.
LIFETIME = TTL + GRACE + KEEP
The TTL's default value is two minutes and refers to the freshness of an object. The "grace" value — which's default value is ten seconds — is the allowed staleness once the object has expired. The "keep" value is how long we need to keep the object around after all of that for potential conditional requests.
Let's say we set the TTL to an hour, the "grace" value to 100 seconds and the "keep" value to 500 seconds. This makes the total lifetime 4200 seconds. We can do this through the following VCL code:
vcl 4.1 ;
sub vcl_backend_response {
set beresp.ttl = 1h;
set beresp.grace = 100s;
set beresp.keep = 500s;
}
The TTL value actually represents the remaining time to live, and changes every single second. Once it drops to zero, the content is no longer fresh, and it needs to be revalidated with the origin. Luckily, the revalidation can be done asynchronously while stale content is served, as long as there is grace time left.
This means that as long as the sum of the TTL and the grace value is greater than zero, stale content can be served.
When the sum falls below zero, we've gone out of grace, and we need to do synchronous revalidation, which means that the client has to wait for the content.
But what about "keep"?
The keep value will ensure that the object is kept around even if it's expired and out of grace. This is helpful when performing conditional requests because the cached response may contain values that are useful for conditional requests. Some examples being, the etag, which is a unique fingerprint of that version of the object or the Last-Modified Date that represents the last change.
These values that identify the object can be sent in a subsequent request under either an If-None-Match header or an If-Modified-Since header.
When Varnish sends an If-None-Match header when revalidating and the value matches the etag that the origin was about to send, we can conclude that nothing has changed. Meaning, we don't need to send over the full payload, we can send a 304 Not Modified status with an empty body. Varnish will recognize that and use the Cache-Control value to reset the timer, making the object fresh again.
Now you know how to calculate the total lifetime of an object. Keep in mind, if the sum of the remaining TTL, "grace" value and "keep" value is zero or less, the object is no longer kept around. If you want to keep the object for conditional requests, you need to set a "keep" value, either by overriding the default_keep as a runtime parameter, or by setting it in VCL.
We'll see you back next week for yet another video on Varnish content, presented to you in two minutes or less. Can't wait another week? Check out our Developer Portal for more tips and tutorials.