Search

Custom cache policy to reduce network transfer Tutorial

Introduction

This tutorial shows how to configure Varnish with a custom cache policy to increase cache hit ratio and reduce network transfer from Amazon S3 when using it as a backend.

Prerequisites

  • One or more servers running Varnish with Amazon S3 as a backend. The basic setup tutorials explain how this can be done.

Step 1 - Add a caching policy

The caching policy can be set by using custom response headers from Amazon S3 or it can be set in VCL. This tutorial shows how to use the mechanisms TTL, grace and keep to configure the caching policy in VCL.

As objects expire from the cache and need to be refreshed, Varnish can use conditional requests to revalidate these objects without having to transfer their actual content from S3, even after the TTL of the objects has expired. This mechanism reduces the network transfer from S3.

Basic cache policy

The following VCL adds a caching policy that allows conditional requests for an extensive period of time. All objects get the same caching policy.

sub vcl_backend_response {
    # For the duration of beresp.ttl since an object was inserted into the
    # cache, it will be delivered from the cache without revalidating with S3.
    set beresp.ttl = 2h;

    # For the duration of beresp.grace since the ttl of an object expired, the
    # object will be delivered from the cache while an asynchronous refresh
    # from S3 is triggered. This is a compromise that allows a recently expired
    # object to be delivered from the cache with low latency while it is being
    # refreshed in the background.
    set beresp.grace = 1h;

    # For the duration of beresp.keep since the grace of an object expired, the
    # object will be kept in the cache to allow synchronous conditional
    # requests. This will reduce bandwidth consumption between Varnish and S3
    # since only objects that have actually changed need to be transferred.
    # Objects that have not been changed will be reused from the cache.
    set beresp.keep = 180d;
}

Cache policy per content type

If different types of objects need to have different caching policies, it is possible to set the caching policy per content type as reported by S3 using the content-type response header:

sub vcl_backend_response {
    # Cache image objects (such as image/png and image/jpeg) for one hour, then
    # do conditional requests for a year to refresh images as needed.
    if (beresp.http.content-type ~ "^image") {
        set beresp.ttl = 1h;
        set beresp.grace = 2h;
        set beresp.keep = 1y;
    }
 
    # Cache video objects (such as video/mp4) for 30 days, then do conditional
    # requests for a year.
    else if (beresp.http.content-type ~ "^video") {
        set beresp.ttl = 30d;
        set beresp.grace = 1h;
        set beresp.keep = 1y;
    }

    # Any other objects are cached for five minutes, then conditional requests
    # will be done for a year. This will ensure that objects that are updated
    # in S3 will be updated in the cache shortly after even if cache invalidation
    # is not enabled.
    else {
        set beresp.ttl = 300s;
        set beresp.grace = 60s;
        set beresp.keep = 1y;
    }
}

Step 2 - More efficient handling of conditional requests

Varnish Enterprise comes with an optimization for more efficient handling of conditional requests. This is useful in environments with a high rate of conditional requests per second. This optimization is enabled like this:

import utils;

sub vcl_backend_response {
    # More efficient handling of responses to conditional requests.
    # https://docs.varnish-software.com/varnish-enterprise/vmods/utils/#fast_304
    if (beresp.was_304) {
        utils.fast_304();
    }
} 

Refer to the utils module documentation for more information.

Next steps

The configuration above can be expanded with more functionality, as covered by the other Varnish tutorials for Amazon S3.