I have a headers/cache issue in my lamp [centos] website.


[root@localhost httpd]# httpd -v
Server version: Apache/2.2.23 (Unix)
Server built:   Nov 25 2012 15:03:00

[root@localhost httpd]# php -v
PHP 5.5.22 (cli) (built: Feb 20 2015 04:04:46)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2015 Zend Technologies
    with Zend OPcache v7.0.4-dev, Copyright (c) 1999-2015, by Zend Technologies


session.cache_limiter = public
session.cache_expire = 535680


<IfModule mod_expires.c>
    # enable expirations
    ExpiresActive On
         <FilesMatch "\.(php)$">
                ExpiresDefault "access plus 1 month"
                Header set Cache-Control "max-age=32140800, public"
                Header unset ETag
                Header unset Last-Modified
                FileETag None

Meta tags:

<meta HTTP-EQUIV="cache-control" CONTENT="public, max-age=32140800">

The Issue:

  1. Load the page for the first time (named si.php here)
  2. Clean access_log:

    [root@localhost httpd]# > access_log
  3. Press F5 in firefox/chrome:

    [root@localhost httpd]# cat access_log - user [25/Jun/2015:04:16:19 +0100] "GET /path/si.php HTTP/1.1" 200 642 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36"
  4. Observe Http headers with live http headers firefox extension:
    GET /path/si.php HTTP/1.1
    User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate
    DNT: 1
    Cookie: __utma=254085576.10126650.1407082841.1422764987.1429480306.10; __utmz=254085576.1407082841.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); PHPSESSID=1cuf6d8764vu2i2u1hin4pg665
    Authorization: Basic cmVjZqR0ZTq1c2VyMQ==
    Connection: keep-alive
    Cache-Control: max-age=0
    HTTP/1.1 200 OK
    Date: Thu, 25 Jun 2015 03:18:04 GMT
    Server: Apache
    X-Powered-By: PHP/5.5.22
    Expires: Fri, 01 Jul 2016 03:18:04 GMT
    Cache-Control: max-age=32140800, public
    Vary: Accept-Encoding,User-Agent
    Content-Encoding: gzip
    Content-Length: 643
    Keep-Alive: timeout=15, max=13
    Connection: Keep-Alive
    Content-Type: text/html; charset=utf-8

Why on earth is the max-age=0 header sent? Firefox and Chrome display both the same behavior. This is an extra 170ms I currently cannot afford.

What is even weirder is the 200 http response code. I don't modify the page at all, it should at the very least return a 304...


Ok, as accepted answer proposes, solution is to:

  1. not open a fresh browser (might not retrieve from cache)
  2. not pressing f5
  3. not just pressing enter in address bar

After the page has been visited a first time in this browser instance, any subsequent normal visit will be from cache:

enter image description here


When you hit F5 in a browser, you are instructing the browser to ask the sever and any proxies in the path for new content. That Cache-Control request header does just that. It does not get added during normal navigation.

Also, PHP has no way of knowing that your content didn't change, especially if it is making a database call. It will never return a 304 for a request unless you add code that makes it do so under whatever conditions. The reason you set a cache-control response header is so the browser won't even make a request at all if the resource is in cache.

Stop hitting F5, browse normally, and watch the traffic with Fiddler or similar tool. You'll find that when you visit your PHP page, then go somewhere else, then come back without hitting F5 that your browser shows your PHP page without even requesting it from the server at all. You're changing that normal caching behavior by hitting F5!

  • You are right. Pasting the url from another page displays (from cache) in the chrome console... You know, I had read something about that. A guy suggested to just press enter in the url instead of pressing f5, to prevent that behavior, but it didn't work for me so I had left that aside. But this time I just tried to browse "normally" and it worked.
    – Sebas
    Jun 26 '15 at 5:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.