Reload Varnish VCL without losing cache data

Mattias Geniar, Sunday, December 14, 2014 - last modified: Wednesday, July 27, 2016

You can reload the Varnish VCL configuration without actually restarting Varnish. A restart would stop the varnishd process and start it anew, clearing all the cache it has built up in the meantime. But you can also reload the varnish configurations, to load your new VCL without losing the cache.

Beware though, there are times when you want to clear your cache on VCL changes: for instance, healthchecks on backend definitions can get pretty funky when a reload of the VCL would modify their IPs, and there are situations where when you change the vcl_hash routine, a restart is advised since the data in memory would never be used again (because of a hash-change). Having said that, there are plenty of reasons to reload a Varnish VCL cache without losing the data in memory.

Via init.d scripts

Not all init.d scripts have a reload option, and it can be disabled with the sysconfig settings if the RELOAD_VCL option is turned off, but if it's enabled, this by far the easiest way.

$ /etc/init.d/varnish reload

This will reload the VCL, compile it and make Varnish use the new version.

Via the Varnish Reload VCL script

Varnish ships with a command called varnish_reload_vcl (if you use the official RPM/Deb repos). You can use this via the CLI to make Varnish load the default.vcl file again into memory (assuming that is the VARNISH_VCL_CONF defined in the /etc/sysconfig/varnish file).

$ varnish_reload_vcl
Loading vcl from /etc/varnish/default.vcl
Current running config name is boot
Using new config name reload_2014-12-14T20:19:16
VCL compiled.

available      11 boot
active          0 reload_2014-12-14T20:19:16


The new Varnish VCL is loaded, without losing in-memory data.

Via a custom script

The varnish_reload_vcl is essentially a Bash-script, you can view the contents by looking into /usr/bin/varnish_reload_vcl. If you want to write something similar into your own scripts, here's a stripped/easier version of that script. It uses varnishadm to load the file and eventually switch the config to use it.


# Generate a unique timestamp ID for this version of the VCL
TIME=$(date +%s)

# Load the file into memory
varnishadm -S /etc/varnish/secret -T vcl.load varnish_$TIME /etc/varnish/default.vcl

# Active this Varnish config
varnishadm -S /etc/varnish/secret -T vcl.use varnish_$TIME

At any time, you can view the in-memory available Varnish VCL files using the vcl.list command. You can load/active one with the vcl.use command and you can compile a new one with vcl.load.

To view the available ones, run the following command.

$ varnishadm -S /etc/varnish/secret -T vcl.list
available       8 boot
available       0 varnish_1418585083

Eeach of those names can be activated with vcl.use.

 $ varnishadm -S /etc/varnish/secret -T vcl.use varnish_1418585083

Hi! My name is Mattias Geniar. I'm a Support Manager at Nucleus Hosting in Belgium, a general web geek & public speaker. Currently working on DNS Spy & Oh Dear!. Follow me on Twitter as @mattiasgeniar.

Share this post

Did you like this post? Will you help me share it on social media? Thanks!


Wilson Sun Tuesday, March 1, 2016 at 05:51 - Reply

The varnish_reload_vcl mentioned here reloads a vcl file into varnish. But there may be not this vcl file.

When varnish works with other system, vcl configure is dynamically generated by the front system and set with vcl.inline.
There is not a vcl file any more. In this case, we have to use vcl.inline.

the following is my varnish_vcl_reload shell script using vcl.inline. Any suggestions
are welcome. —

# reload active vcl
# Sometimes, vcl_init needs to be re-run by reloading the active vcl.
# For example, a geoip database is loaded in vcl_init. When the database is updated,
# vcl_init needs to be re-run.
# This script saves the currently active vcl to a shell variable, and reloads it to varnish
# Wislon Sun 

usage="$(basename "$0") [-n ident] [-t timeout] [-S secretfile] -T [address]:port

    -h  show this help text
    -n,t,S,T refer to varnishadm"

while getopts ':n:t:S:T:d:h' option; do
  case $option in
    n) ident=$OPTARG
    t) timeout=$OPTARG
    S) secretfile=$OPTARG
    T) addressport=$OPTARG
    h) echo "$usage"
    :) printf "missing argument for -%s\n" "$OPTARG" >&2
       echo "$usage" >&2
       exit 1
   \?) echo "illegal option: -$OPTARG" >&2
       echo "$usage" >&2
       exit 1

# Done parsing, set up command

if [ ! -z "$ident" ]; then
        VARNISHADM="$VARNISHADM -n $ident"

if [ ! -z "$timeout" ]; then
        VARNISHADM="$VARNISHADM -t $timeout"

if [ ! -z "$secretfile" ]; then
        VARNISHADM="$VARNISHADM -S $secretfile"

if [ ! -z "$addressport" ]; then
        VARNISHADM="$VARNISHADM -T $addressport"

# Check if we are able to connect at all
if ! $VARNISHADM vcl.list >> /dev/null 2>&1; then
        echo "Unable to run \"$VARNISHADM vcl.list\""
        exit 1

# find current config
current_config=$( $VARNISHADM vcl.list | awk ' /^active/ { print $3 } ' )

# save current config to a variable
vclcontent=` $VARNISHADM $current_config | sed 's/["\]/\\\\&/g' | sed ':a;N;$!ba;s/\n/\\\\n/g' `

timestamp=`date +%Y%m%d_%H%M%S`
$VARNISHADM vcl.inline "vreload$timestamp" '"'$vclcontent'"' >> /dev/null 2>&1
vstring=`varnishadm -n aeroflow vcl.list|grep "vreload$timestamp"`
if [ ! -z "$vstring" ]; then
   $VARNISHADM vcl.use "vreload$timestamp" >> /dev/null 2>&1
   $VARNISHADM vcl.discard $current_config >> /dev/null 2>&1
   echo "successfully reload current vcl config"
   exit 0
   echo "failed to save current vcl config"
   exit 1

Leave a Reply

Your email address will not be published. Required fields are marked *