When configuring Varnish for production environments, we often face the memory-disk tradeoff. The malloc
storage backend offers blazing fast memory access but limited capacity, while file
storage provides larger capacity at the cost of slower disk I/O. For sites with relatively static content (like documentation portals or CMS-driven marketing sites), we can implement an elegant hybrid solution.
Varnish supports multiple storage backends simultaneously through its -s
parameter. The syntax allows specifying:
# Memory storage (1GB)
-s malloc,1G
# File storage (10GB)
-s file,/var/lib/varnish/storage.bin,10G
Here's a production-tested configuration that prioritizes memory while falling back to disk:
# /etc/default/varnish
DAEMON_OPTS="-a :80 \\
-T localhost:6082 \\
-s main=malloc,512m \\
-s secondary=file,/var/lib/varnish/varnish_storage.bin,5G \\
-p thread_pool_add_delay=2 \\
-p thread_pools=4 \\
-p thread_pool_min=100 \\
-p thread_pool_max=4000"
The main
store will be checked first for objects, followed by secondary
. Objects are promoted to faster storage when frequently accessed.
For optimal hybrid performance, add these VCL tweaks:
sub vcl_backend_response {
# Keep small assets in memory
if (std.integer(beresp.http.Content-Length, 0) < 1048576) { # 1MB
set beresp.storage = "main";
}
# Longer TTL for disk-stored items
if (beresp.storage == "secondary") {
set beresp.ttl = 48h;
}
}
Use these varnishstat commands to validate performance:
varnishstat -1 -f MAIN.n_lru_nuked # Memory evictions
varnishstat -1 -f SECONDARY.n_lru_nuked # Disk evictions
varnishstat -1 -f MAIN.cache_hit # Memory hit rate
- Allocate no more than 70% of available RAM to malloc storage
- Place disk storage on fast SSDs or NVMe devices
- Monitor disk I/O wait times (vmstat 1)
- Consider
persistent
storage for critical assets (Varnish 6+)
Varnish Cache offers multiple storage backends, with malloc
(memory) and file
(disk) being the most commonly used. While the documentation presents them as distinct options, creative configuration can achieve a hybrid approach.
Here's how to configure Varnish to use both storage types effectively:
# /etc/varnish/default.vcl
vcl 4.1;
backend default {
.host = "127.0.0.1";
.port = "8080";
}
sub vcl_init {
# Primary storage in memory (100MB)
new mem_cache = storage.malloc(100M);
# Fallback storage on disk (2GB)
new disk_cache = storage.file("/var/lib/varnish/storage.bin", 2G);
}
To implement a true hybrid approach with fallback behavior, you'll need to customize your VCL:
sub vcl_recv {
# Try memory cache first
if (storage.mem_cache.free() > 0) {
set req.storage_hint = "mem_cache";
} else {
set req.storage_hint = "disk_cache";
}
}
sub vcl_backend_response {
# Set TTLs differently for each storage
if (beresp.storage_hint == "mem_cache") {
set beresp.ttl = 2h;
} else {
set beresp.ttl = 24h;
}
}
- Memory Allocation: Start with 50-70% of available RAM for
malloc
- Disk Configuration: Use fast storage (SSD preferred) for file backend
- Monitoring: Track hit/miss ratios for each storage with
varnishstat
For more granular control, consider these VCL snippets:
sub vcl_hit {
# Promote disk cache hits to memory
if (obj.hits > 3 && obj.storage == "disk_cache") {
storage.mem_cache.put(obj);
}
}
sub vcl_backend_fetch {
# Prefer memory for small objects
if (std.integer(bereq.http.Content-Length, 0) < 1048576) { # 1MB
set bereq.storage_hint = "mem_cache";
}
}
Another configuration option using the newer Varnish syntax:
# Command line parameters
varnishd -s malloc,100M -s file,/var/lib/varnish/storage.bin,2G
Use these commands to verify your configuration:
varnishadm storage.list
varnishstat -1 -f MAIN.*