Varnish appears to be working but max-age=0

Toni Michel Caubet

isvarnishworking.com is letting me know that

Varnish appears to be responding at that url, but the Cache-Control header's "max-age" value is less than 1, which means that Varnish will never serve content from cache at this url.

The max-age value appears to be: 0

And this header info

The url we checked: myDomainHere.com
    HTTP/1.1 200 OK
Server: Apache/2.4.7 (Ubuntu)
X-Powered-By:   PHP/5.5.9-1ubuntu4.5
Set-Cookie: PHPSESSID=vgk7db66kh7nce8lpe5789u105; path=/
Expires:    Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control:  max-age=60, private, proxy-revalidate
Pragma: no-cache
Vary:   Accept-Encoding,User-Agent
Content-Encoding:   gzip
Content-Type:   text/html
Content-Length: 14192
Accept-Ranges:  bytes
Date:   Sat, 18 Jul 2015 09:31:55 GMT
X-Varnish:  324589322
Age:    0
Via:    1.1 varnish
Connection: keep-alive

I have this in .htaccess

 <FilesMatch "\.(js|css)$">
    Header set Cache-Control "max-age=604800, public"
</FilesMatch>
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
    Header set Cache-Control "max-age=604800, public"
</FilesMatch>
<FilesMatch "\.(html|htm|php)$">
    Header set Cache-Control "max-age=60, private, proxy-revalidate"
</FilesMatch>

So my question, Do I really have to change that max-age=0 in order to varnish perform better? If so, where would I Do this? I am using apache2 on a ubuntu digitalocean's droplet

-edit-

This is my /etc/varnish/default.vcl

# This is a basic VCL configuration file for varnish.  See the vcl(7)
# man page for details on VCL syntax and semantics.
#
# Default backend definition.  Set this to point to your content
# server.
#
backend default {
    .host = "127.0.0.1";
    .port = "8080";
}
#
# Below is a commented-out copy of the default VCL logic.  If you
# redefine any of these subroutines, the built-in logic will be
# appended to your code.
# sub vcl_recv {
#     if (req.restarts == 0) {
#       if (req.http.x-forwarded-for) {
#           set req.http.X-Forwarded-For =
#               req.http.X-Forwarded-For + ", " + client.ip;
#       } else {
#           set req.http.X-Forwarded-For = client.ip;
#       }
#     }
#     if (req.request != "GET" &&
#       req.request != "HEAD" &&
#       req.request != "PUT" &&
#       req.request != "POST" &&
#       req.request != "TRACE" &&
#       req.request != "OPTIONS" &&
#       req.request != "DELETE") {
#         /* Non-RFC2616 or CONNECT which is weird. */
#         return (pipe);
#     }
#     if (req.request != "GET" && req.request != "HEAD") {
#         /* We only deal with GET and HEAD by default */
#         return (pass);
#     }
#     if (req.http.Authorization || req.http.Cookie) {
#         /* Not cacheable by default */
#         return (pass);
#     }
#     return (lookup);
# }
#
# sub vcl_pipe {
#     # Note that only the first request to the backend will have
#     # X-Forwarded-For set.  If you use X-Forwarded-For and want to
#     # have it set for all requests, make sure to have:
#     # set bereq.http.connection = "close";
#     # here.  It is not set by default as it might break some broken web
#     # applications, like IIS with NTLM authentication.
#     return (pipe);
# }
#
NotGaeL

Do I really have to change that max-age=0 in order to varnish perform better?

Yes. You need to do it if you want it to perform at all.

If so, where would I Do this?

It seems you got everything right for caching static content, but you also seem to want to cache PHP script execution responses:

You are just missing session_cache_limiter and session_cache_expire, which should be the first lines executed on the requested PHP script, even before session_start().

If, for example, the content returned is private and you want to refresh it every minute, try something like:

session_cache_limiter('private');
session_cache_expire(1);

After that you should see a proper Cache-Control: max-age=60, private value on Varnish responses for requests for PHP generated content including those lines at the beginning of the script.

[update] Seeing your problem isn't solved yet, maybe you should try to use Apache mod_expires instead of manually setting the Cache-Control header: http://httpd.apache.org/docs/2.4/mod/mod_expires.html

That should answer your questions, but allow me to give you a few extra notes that may be useful to you and help you get a better understanding on how Varnish and the Cache-Control header relate to each other:

  • With the default configuration max-age=0 on the response indicates both to Varnish and to the browser that the response is not cacheable. Unless configured otherwise or explicitly allowed on the client's request, Varnish will not serve stale content:

A stale cache item will not be returned by any cache (proxy cache or client cache).

From https://tools.ietf.org/html/rfc7234#section-5.3:

If a response includes a Cache-Control field with the max-age
directive (Section 5.2.2.8), a recipient MUST ignore the Expires
field. Likewise, if a response includes the s-maxage directive
(Section 5.2.2.9), a shared cache recipient MUST ignore the Expires
field. In both these cases, the value in Expires is only intended
for recipients that have not yet implemented the Cache-Control field.

From http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3:

If a cache returns a stale response, either because of a max-stale directive on a request, or because the cache is configured to override the expiration time of a response, the cache MUST attach a Warning header to the stale response, using Warning 110 (Response is stale).

A cache MAY be configured to return stale responses without validation, but only if this does not conflict with any "MUST"-level requirements concerning cache validation (e.g., a "must-revalidate" cache-control directive).

If both the new request and the cached entry include "max-age" directives, then the lesser of the two values is used for determining the freshness of the cached entry for that request.

  • The main purpose of Varnish is to store in-memory cacheable responses (while they are fresh) so they can be sent to the same OR different clients without regenerating them, also facilitating load balancing if required.

  • Varnish will not serve stale content when requested fresh content (most common scenario) and even if it did, the browser would not be saving it and would generate a new request for a fresh page every time the user asked for that content, unnecessarily hitting the cache (with all the network activity involved) instead of rendering a locally stored copy, which would be quite inefficient and noticeably slower!

max-age Indicates that the client is willing to accept a response whose age is no greater than the specified time in seconds. Unless max- stale directive is also included, the client is not willing to accept a stale response.

Now, if you still see the browser sends a new request every time the content is loaded (check the network tab of your browser's developer tools or varnish logs), recheck everything. As a last resort you can also try to set the proper html meta tags, although html5 deprecates them and they shouldn't be necessary for any modern browser and it is not best practice so I would advise against it.

Also here is some good reading on doing proper cache control on content generated by PHP scripts that might interest you.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

No cache: Varnish age 0

What is the difference between max-age=0 and max-age=-1 in Cache Control?

Setting cache-control max-age using Apache not working

Setting a cookie with max age; max age is lost

OIDC client + Identity Server 4, setting max_age silent token reniew not working

Symfony 3.4 http cache , always Cache-Control: max-age=0, must-revalidate, private

"Cache-Control: max-age=0, no-cache" but browser bypasses server query (and hits cache)?

What's the difference between Cache-Control: max-age=0 and no-cache?

Express static server cache control with max-age=0,must-revalidate

Cookie with Max-Age = 0 and Expire = session survived after HTTP redirect?

Unable to find Max Age of a Player

Trigger to update age when inserted age < 0

css transition max-height back to 0 not working

Docker link between varnish and wordpress not working

Rxjs `distinctUntilChanged()` appears to not be working

Assertions and failures appears with 0

Google Signin request for age not working

<TextInput /> not working with numeric values(age)

Age filter for gridview not working properly

How to get RequestCachePolicy to respect max-age

ETags: Validation and Cache max-age

pyspark rdd taking the max frequency with the least age

Varnish Max Threads hit & backend and session connections issue

What's the age before __STDCPP_DEFAULT_NEW_ALIGNMENT__ appears

HTTP Cache-Control header max-age vs max-age, must-revalidate

Bootstrap appears not to be working with my columns

FragmentTransaction animation is working but appears glitchy

Connect Nginx and Varnish 6 via Unix Domain Socket not working

"I will guess your age" game not working properly