How to Use Varnish Cache on a Web Hosting

Web Hostings benefit from a powerful cache system powered by Varnish. This allows you to distribute the content of your website to a larger number of visitors without using the resources of your web hosting or server.

For example, when a website visitor requests a file from your web server ‘foo.jpg’, this file is placed into the Varnish cache. When the next visitor requests the same image, the image is served from the Varnish cache, relieving your web server from replying to the request.

Check cache status

Caching is enabled by default and an expiration period of 120 seconds is set for all requests.

You can control how long an object should be cached, or whether it should be cached at all. You can also control whether different representations of the same object should be cached to respond to different request options. Learn more about controlling the cache below.

When you make an HTTP(s) request to a website hosted on Web Hosting or linked to a Web Accelerator, you will notice that the response will contain specific headers that indicate whether caching is enabled or not.

You can use a variety of tools to see the HTTP headers in the responses. For example, you can use your browser’s “Inspector” tool or the following command: curl -i http://example.com

All HTTP(s) requests, cached or not, go through our Varnish cache system, so you will always find the Via header (RFC2616) in the responses :

Via: 1.1 varnish

To determine whether your response is being cached, check if the Age: header has a value greater than 0. The following example shows a response that was served from the cache and was generated by the actual code 117 seconds ago:

Via: 1.1 varnish
Age: 117

Make multiple requests to the same address and see whether the Age: value increases, or stays at 0. If the object is not cached, the value will always be 0, meaning that it was served by the web hosting and not the Web Accelerator.

Otherwise, the value will increase until the cache expires as the object is being served by the Web Accelerator, or from your browser’s cache directly, or from an intermediary proxy system such as your ISP or corporate proxy. After expiration, or after a purge, the value will be 0 for the first response.

Modify Cache Period

The default period an item will remain in the cache is 120 seconds. If you’d like to change this, you can do so by adding the following header and varying the value of max-age (in seconds):

HTTP Cache-Control: max-age=200

Warning

For development or testing purposes, you can reduce the cache to 1 second, with max-age=1. With max-age=0, the cache will be disabled, but be aware that the performance of your web hosting will be reduced without the cache system in place, and thus is not recommended.

Example for PHP:

header("Cache-Control: max-age=1");

Example for an .htaccess file if it is a static website:

Header add Cache-Control "max-age=1"

Example in Node.js (Works with the standard HTTP libraries and with the Express framework):

function (request, response) {
    response.setHeader('Cache-Control', 'max-age=1');
}

Note

Advanced VPS users: The Web Accelerator takes care of s-maxage.

Purge Cache

Below are the various methods available for purging objects from the Varnish cache.

Purging Cache Using HTTP PURGE/PURGEALL Request

It is possible to purge a particular URL cache by sending an HTTP PURGE request. You can also purge the entire cache with an HTTP PURGEALL request.

Note

The PURGE and PURGEALL requests will only work from within your web hosting or server. For the moment, they cannot be issued remotely.

For example, you can connect to your web hosting or server using the SSH console and run a curl command:

$ curl -X PURGE http://www.example.com/test/index.html
$ curl -X PURGEALL http://www.example.com/

Alternatively,this PHP script that can be called from a browser to clear a particular URL cache:

<?php
/* purge.php
 * Purge a URL on this host
 */
header("Cache-Control: max-age=1"); // don't cache ourself

error_reporting(E_ALL);
ini_set("display_errors", 1);

// Set to true to hide varnish result
define("SILENT", false);

$path = isset($_GET["path"]) ? $_GET["path"] : "";

$purge_url = "http://" . $_SERVER["HTTP_HOST"] . "/$path";

if ( $ch = curl_init($purge_url) ) {
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PURGE");
    curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
    curl_setopt($ch, CURLOPT_NOBODY, SILENT);

    curl_exec($ch);
    curl_close($ch);
}
?>

Purging Cache from Web Interface

It is possible to purge the cache directly from your web hosting’s control panel.

Once logged in, find the “Varnish” section, and click on the link to purge all objects in cache.

If you see “200 = OK” then this means that the purge was successful.

Note

The PURGEALL command can only be performed every 120 seconds. This limitation is to prevent abuse of the cache CPU.

Purging Cache When Deploying a Git Branch

For web hostings using the built-in git repository, executing the deploy command will automatically perform a PURGEALL at the end of the deployment process.

mod_expires

Your web hosting includes the enabled mod_expires module in Apache2, which allows you to set custom expiration dates for cached items based on either the time the source file was last modified, or to the time of the client access.

You can use the directive ExpiresDefault to set an expiration time for all cached items, or you can set the expiration time for specific file-types using ExpiresByType.

For more information please see the `mod_expires Apache2 documentation`__.

Surrogate-key

You can manage groups of objects in the cache using the Surrogate-Key header. To register an object (for example, a web page or an image), simply include the header in your answer with a value that corresponds to the desired group. Then you will be able to purge the cache of this group by adding its header to the PURGE command.

For example, to add an object to a group with PHP :

header("Surrogate-Key: foo");

Or with Node.js:

function (request, response) {
    response.setHeader('Surrogate-Key', 'foo');
}

And then to purge all objects in this group:

curl -X PURGE -H 'Surrogate-Key: foo' http://www.example.com/

You can also associate an object with multiple groups and purge multiple groups at the same time. To do this, enter the names of groups separated by a space: Surrogate-Key: foo bar.

Cookies

As a general rule, requests containing cookies will not be served from the cache. Similarly, responses that write cookies with the set-cookie: header will not be cached by our platform.

To serve objects from the cache that take cookies into account, you can use a special prefix in their name: STYXKEY.

When our platform receives a request containing cookies with this prefix, it will serve the cached object if it exists and has not expired, or will cache the response of the server if it does not contain the set-cookie.

Here is an example of using a cookie with a key containing the STYXKEY prefix to remember the language of the user :

  1. A browser requests the root of your website (GET /).

  2. Your site or application answers with the header set-cookie: STYXKEY-lang=EN → the reply will not be cached, since set-cookie is used.

  3. The browser keeps the cookie and calls your website again (GET /).

  4. Your site or application detects the presence of the cookie STYXKEY-lang, so the value is EN, and responds with English language content and without the header set-cookie: → the answer will be cached by our platform.

  5. The browser requests your website another time (GET /).

  6. Our platform detects the cookie STYXKEY-lang=EN and serves the previously cached object.

Note that the prefix must respect the standard format of cookies.

To ensure that our platform takes into account your cookie, it is recommended to use STYXKEY followed by -, _ or ., and then the name of your specific key. For example, these cookie name formats will be taken into account :

STYXKEY_language=fr
STYXKEY-language=en
STYXKEY.language=de

While these formats will not be taken into account:

language-STYXKEY=en            # The cookie name must start with STYXKEY
STYX-KEY-language=en           # STYXKEY must be one word
styxkey_is_case_sensitive=true # STYXKEY must be in uppercase
STYXKEY=present                # STYXKEY must be a prefix and not a cookie name