When no explicit TTL (Time To Live) is set and the backend server doesn't provide cache-control headers, Varnish Cache follows specific default behaviors that every developer should understand.
# Default behavior when no TTL is specified
sub vcl_backend_response {
if (beresp.ttl <= 0s) {
set beresp.ttl = 120s; # Default fallback
set beresp.uncacheable = true;
}
}
The actual default TTL in Varnish depends on several factors:
- If the backend provides a valid Cache-Control header, Varnish respects it
- Without Cache-Control headers, Varnish uses a default of 120 seconds
- For objects marked as uncacheable (ttl <= 0), Varnish won't cache them by default
You can override these defaults in your VCL file in several ways:
# Method 1: Set default TTL for all responses
sub vcl_backend_response {
if (!beresp.http.Cache-Control) {
set beresp.ttl = 1h; # 1 hour default
}
}
# Method 2: Different TTLs based on content type
sub vcl_backend_response {
if (beresp.http.Content-Type ~ "text/html") {
set beresp.ttl = 5m;
} elsif (beresp.http.Content-Type ~ "application/json") {
set beresp.ttl = 30m;
}
}
For more sophisticated caching strategies, consider these approaches:
# Grace period configuration
sub vcl_backend_response {
set beresp.grace = 1h;
set beresp.ttl = 5m;
}
# TTL based on request characteristics
sub vcl_recv {
if (req.url ~ "^/static/") {
set req.http.X-Static = "1";
}
}
sub vcl_backend_response {
if (bereq.http.X-Static) {
set beresp.ttl = 1d;
}
}
To verify your TTL settings are working as expected:
# Add debugging headers
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
set resp.http.X-Cache-TTL = obj.ttl;
} else {
set resp.http.X-Cache = "MISS";
}
}
This will help you monitor how long objects remain in cache before being evicted.
When no explicit TTL (Time To Live) is set in your VCL configuration and the backend server doesn't provide any Cache-Control
headers, Varnish Cache follows a specific default behavior. The default TTL in Varnish is 120 seconds (2 minutes). This is defined in Varnish's built-in VCL.
The default TTL is actually set in Varnish's built-in vcl_backend_response
subroutine. You can view this by running:
varnishadm param.show default_ttl
This will output something like:
default_ttl
Value is: 120.000 [seconds] (default)
Minimum is: 0.000
There are several ways to override this default behavior:
1. Setting TTL in vcl_backend_response
sub vcl_backend_response {
if (beresp.ttl <= 0s) {
set beresp.ttl = 1h; # Default to 1 hour if backend specifies no TTL
}
}
2. Conditional TTL Based on Content Type
sub vcl_backend_response {
if (beresp.http.Content-Type ~ "text/html") {
set beresp.ttl = 30m;
} elsif (beresp.http.Content-Type ~ "(image|css|js)") {
set beresp.ttl = 1w;
}
}
- Always consider your content type when setting TTL values
- For dynamic content, shorter TTLs (minutes to hours) are appropriate
- Static assets can have much longer TTLs (weeks to months)
- Use grace mode to serve stale content while revalidating
To verify your TTL settings are working as expected, use:
varnishlog -g request -q "ReqUrl ~ '^/your/path'"
Look for the TTL
and Expires
fields in the output.
Varnish respects Cache-Control
headers from your backend. You can combine this with your VCL:
sub vcl_backend_response {
# Respect backend Cache-Control if present
if (beresp.http.Cache-Control ~ "max-age") {
return (deliver);
}
# Otherwise apply our default
set beresp.ttl = 24h;
}