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
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?
2. How do you make a block dynamic within FPC?
3. What is ESI?
4. How does Magento load dynamic customer content?
Flashcards
Question
What does FPC cache?
Click to reveal answer
Answer
Complete rendered HTML pages for fast serving from cache
Question
How to make a block dynamic?
Click to reveal answer
Answer
Set cacheable=false in constructor $data array
Question
What is hole punching?
Click to reveal answer
Answer
Allowing specific blocks to be rendered dynamically within cached pages
Question
What is ESI?
Click to reveal answer
Answer
Edge Side Includes for assembling pages from cached fragments at the edge
Question
How to load cart content with FPC?
Click to reveal answer
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:
- First request: generate HTML
- Cache complete page
- Serve from cache
- 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