Magento 2 comes stock with a full page caching feature. However, it's not clear how the framework determines which URL end-points need to be cached. For example, if I create a simple controller that acts as a JSON endpoint

$data = ...;
$result = $this->resultJsonFactory->create();       
return $result->setData($data);

The system seems smart enough to know not to cache this.

curl -I 'http://magento2.example.com/my/custom/endpoint'
X-Magento-Cache-Debug: MISS

I've been able to track the built in caching functionality to this method (used by the built-in plugin)

#File: lib/internal/Magento/Framework/App/PageCache/Kernel.php
public function process(\Magento\Framework\App\Response\Http $response)
    if (preg_match('/public.*s-maxage=(\d+)/', $response->getHeader('Cache-Control')->getFieldValue(), $matches)) {
        $maxAge = $matches[1];
        if ($response->getHttpResponseCode() == 200 && ($this->request->isGet() || $this->request->isHead())) {
            $tagsHeader = $response->getHeader('X-Magento-Tags');
            $tags = $tagsHeader ? explode(',', $tagsHeader->getFieldValue()) : [];

            if (!headers_sent()) {
            $this->cache->save(serialize($response), $this->identifier->getValue(), $tags, $maxAge);

Which seems to examine the response object, and only cache requests if they're a HTTP 200, either a GET or HEAD request. It also uses the Max-Age Cache-Control header to ensure values are saved in the cache for an appropriate amount of time.

So, it's clear from this code that something instructs the system (i.e. sets cache headers on the response) to cache the request. What's not clear is where this happens during Magento's request flow, and which requests gets full page caching and which do not.

  • For me, X-Magento-Cache-Debug is always MISS. Any idea what it could be?
    – MagePsycho
    Oct 9 '17 at 13:23

Response is marked as cacheable in \Magento\PageCache\Model\Layout\LayoutPlugin::afterGenerateXml only in case if there are no blocks in the layout of current page marked with cacheable="false" attribute, like this:

<block class="Magento\Checkout\Block\Registration" name="checkout.registration" template="registration.phtml" cacheable="false"/>

By default all CMS, product and category pages should be cacheable, their layouts were refactored so as not to contain non-cacheable blocks.

Also keep in mind, there is a bug related to usage of cacheable="false" on product pages described here.

  • 2
    Thanks! More on some other important full page cache points here. magento-quickies.alanstorm.com/post/134802803800/…
    – Alan Storm
    Dec 8 '15 at 18:29
  • But what about when if i need in custom product extended block ? because if i am put cacheable="false" in xml then it will give error in varnish varnish failed on marketplace submission
    – Himanshu
    Dec 22 '18 at 11:14

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.