Craft seems to be setting headers to tell the browser not to cache anything it serves, which seems bad.
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Why it do dat?
Craft doesn't explicitly set any caching headers in the response, but you can control exactly how you want your caching headers to behave from your templates with the {% header %} tag.
For example:
{# Tell the browser to cache this page for 30 days #}
{% set expiry = now|date_modify('+30 days') %}
{% header "Cache-Control: max-age=" ~ expiry.timestamp %}
{% header "Pragma: cache" %}
{% header "Expires: " ~ expiry|date('D, d M Y H:i:s', 'GMT') ~ " GMT" %}
By default PHP has the session_cache_limiter() method set to nocache, which is probably what you're seeing.
As highlighted in Brad Bell's answer, those headers are likely set by PHP. By default PHP has the session_cache_limiter() method set to nocache. You can verify this in your Craft admin panel under Utilities > PHP Info > session.cache_limiter.
If you change this value to public, it will set a cache expiry according to the value of session.cache_expire (set to 180 by default). This is explained here in the PHP docs.
I did not heed Brandon Kelly's advice, and I set session.cache_limiter=public in my php.ini file. I do not know which unintended consequences he speaks of, but I like to live dangerously.
Here are the new headers I get:
Cache-Control: public, max-age=10800
Expires: Wed, 27 Nov 2019 11:54:38 GMT (180 minutes from now)
If you do this, it will break a few things in the admin. Admin pages won't always load properly because the wrong things will be cached. It works perfectly on the website though.
This had me confused for a while: if you're using Craft Nitro, the Nginx config adds Cache-Control: no-store, no-cache ... headers which cannot by overridden from PHP or Twig.
In Nitro 1.x you could SSH into the machine and edit the Nginx config to not add the headers. I haven't been able to get Nitro 2.0 to work and have switched to Docker Compose which is simpler and doesn't have this caching problem.
Request headers for a static (non-craft request):
– Tim Kelty Sep 18 '14 at 01:45Response headers for a static (non-Craft request):
Here's one from Craft:
– Tim Kelty Sep 18 '14 at 01:51Cache-Control: max-age=0– Tim Kelty Sep 18 '14 at 01:52exit('Hello');- no no-cache headers. Once I let Craft run though, I see them. Are you not seeing the Cache-Control/Pragma headers on your Craft installs? – Tim Kelty Sep 18 '14 at 04:59The whole reason this came up is I was playing around with Varnish w/ Craft and by default it bypasses when it gets a
– Tim Kelty Sep 18 '14 at 05:17Cache-control: no-cacheresponse.