Skip to content
intermediate Phase 69 · Cache Advanced

Full Page Cache — FPC Mechanism and Hole Punching

Understanding Magento 2 Full Page Cache: FPC mechanism, hole punching, ESI integration, and private content handling

45m
1 problems
Topic Progress 0%

FPC Mechanism

How FPC Works

1. First request: Magento generates full HTML
2. FPC stores complete page in cache
3. Subsequent requests: serve cached HTML
4. Private content loaded via AJAX/ESI

FPC Configuration

// Enable FPC
php bin/magento config:set catalog/frontend/flat_catalog 1

// Check FPC status
php bin/magento cache:status | grep fpc

// Clear FPC
php bin/magento cache:clean fpc

FPC Storage

// FPC stored in cache backend (Redis recommended)
// Default: var/cache/page_cache/
// Redis: database 1

// Check FPC size
redis-cli -n 1 dbsize

FPC and Cache Tags

Magento sends cache tags with FPC:

X-Magento-Tags: store,catalog_product_123,catalog_category_45

When a product is saved, only pages tagged with that product are invalidated.

Hole Punching

What is Hole Punching?

Hole punching allows specific blocks to be rendered dynamically within a cached page.

// Mark block as dynamic (non-cacheable)
public class MiniCart extends \Magento\Checkout\Block\Cart\Minicart
{
    public function __construct(
        // ...
        array $data = []
    ) {
        $data['cacheable'] = false;  // Hole punch this block
        parent::__construct($context, $data);
    }
}

AJAX-Based Hole Punching

// Load dynamic content via AJAX
fetch('/customer/section/load/?sections=cart')
    .then(response => response.json())
    .then(data => {
        document.querySelector('.minicart-wrapper').innerHTML = data.cart.html;
    });

Customer Sections API

// Sections loaded via AJAX
// /customer/section/load/?sections=cart,wishlist,compare

// Returns:
{
    "cart": { "html": "...", "summary_count": 5 },
    "wishlist": { "html": "..." }
}

Block-Level Hole Punching

// Via layout XML
<block class="Vendor\Module\Block\Dynamic"
       name="dynamic.block"
       template="dynamic.phtml"
       cacheable="false"/>

ESI Integration

What is ESI?

Edge Side Includes allow Varnish to assemble pages from multiple cached fragments.

<!-- ESI tag in HTML -->
<esi:include src="/block/minicart" />

Magento ESI Configuration

<!-- default.xml -->
<block class="Magento\Checkout\Block\Cart\Minicart"
       name="minicart"
       template="Magento_Checkout::cart/minicart.phtml">
    <arguments>
        <argument name="ttl_path" xsi:type="string">checkout/cart/minicart_ttl</argument>
    </arguments>
</block>

Varnish ESI Support

sub vcl_recv {
    if (req.http.X-ESI) {
        set req.backend_hint = magento;
    }
}

sub vcl_backend_response {
    if (beresp.http.X-ESI) {
        set beresp.do_esi = true;
    }
}

ESI vs AJAX Hole Punching

Aspect ESI AJAX
Server-side Yes (Varnish) No (Browser)
Latency Lower (edge) Higher (round trip)
Complexity Higher Lower
Caching Per-block caching Per-request
SEO Better Same

FPC Best Practices

When to Make Blocks Non-Cacheable

// Customer-specific blocks
public function __construct(
    // ...
    array $data = []
) {
    $data['cacheable'] = false;  // Mini cart
    parent::__construct($context, $data);
}

FPC Performance Tuning

// Increase FPC TTL
php bin/magento config:set system/full_page_cache/ttl 86400

// Check FPC hit rate
redis-cli -n 1 info keyspace

Debugging FPC

# Check if FPC is enabled
php bin/magento cache:status | grep fpc

# Clear FPC
php bin/magento cache:clean fpc

# Check FPC tags
redis-cli -n 1 keys '*page*'

Common FPC Issues

Issue Cause Fix
Dynamic content not updating Block is cacheable Set cacheable=false
FPC not working Cache disabled Enable fpc cache type
Slow FPC Large pages Optimize block rendering
Memory issues Too many cache entries Increase Redis memory

Practice Problems

0 / 1 solved
FPC Hole Punching

A product page has FPC enabled but the add-to-cart button needs to be dynamic. Implement hole punching.

Quiz

1. What does FPC cache?

Question 1 options

2. How do you make a block dynamic within FPC?

Question 2 options

3. What is ESI?

Question 3 options

4. How does Magento load dynamic customer content?

Question 4 options

Flashcards

Question

What does FPC cache?

Answer

Complete rendered HTML pages for fast serving from cache

Question

How to make a block dynamic?

Answer

Set cacheable=false in constructor $data array

Question

What is hole punching?

Answer

Allowing specific blocks to be rendered dynamically within cached pages

Question

What is ESI?

Answer

Edge Side Includes for assembling pages from cached fragments at the edge

Question

How to load cart content with FPC?

Answer

AJAX to /customer/section/load/?sections=cart

Revision Notes

Key Takeaways

  • 1. FPC caches complete HTML pages for fast serving
  • 2. Hole punching allows dynamic blocks via cacheable=false
  • 3. AJAX loads customer sections (cart, wishlist) dynamically
  • 4. ESI enables server-side assembly of cached fragments
  • 5. FPC invalidation uses cache tags for targeted clearing
  • 6. Redis database 1 is typically used for FPC storage

Interview Tips

  • Explain how FPC works and what it caches
  • Describe hole punching techniques (AJAX and ESI)
  • Discuss when to make blocks non-cacheable
  • Know the customer sections API for dynamic content

Cheat Sheet

FPC Cheat Sheet

Mechanism:

  1. First request: generate HTML
  2. Cache complete page
  3. Serve from cache
  4. Dynamic content via AJAX/ESI

Hole punching:

$data['cacheable'] = false;

AJAX sections:
/customer/section/load/?sections=cart

ESI:
<esi:include src="/block/minicart" />

Commands:

  • cache:clean fpc — clear FPC
  • cache:status — check FPC
  • Redis db 1 — FPC storage

Tags: X-Magento-Tags header