PHPackages                             wubinworks/module-cache-warmer - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Caching](/categories/caching)
4. /
5. wubinworks/module-cache-warmer

ActiveMagento2-module[Caching](/categories/caching)

wubinworks/module-cache-warmer
==============================

A Free Magento 2 Extension designed for CDN and Varnish cache warming. Warm up URLs located in sitemaps, as well as static content, media content and dynamic catalog images. Run manually or schedule by cron expression. This extension is easily customizable with dispatched events and the CLI command is ready to be embedded in deployment scripts.

1.0.0(1y ago)71.3k—7.1%OSL-3.0PHPPHP &gt;=7.1

Since Jun 23Pushed 1y ago1 watchersCompare

[ Source](https://github.com/wubinworks/magento2-free-cache-warmer)[ Packagist](https://packagist.org/packages/wubinworks/module-cache-warmer)[ Docs](https://www.wubinworks.com/free-cache-warmer.html)[ RSS](/packages/wubinworks-module-cache-warmer/feed)WikiDiscussions master Synced yesterday

READMEChangelog (1)Dependencies (2)Versions (2)Used By (0)

Magento 2 Free Sitemap Based Cache Warmer Extension
===================================================

[](#magento-2-free-sitemap-based-cache-warmer-extension)

***A Free Magento 2 Extension designed for CDN and Varnish cache warming. Warm up URLs located in sitemaps, as well as static content, media content and dynamic catalog images. Run manually or schedule by cron expression. This extension is easily customizable with dispatched events and the CLI command is ready to be embedded in deployment scripts.***

[![Magento 2 Free Sitemap Based Cache Warmer Extension](https://camo.githubusercontent.com/7e2545aa862a8b55d5879dc2d656a625077723a1416839cb7ad56955b23a3317/68747470733a2f2f7777772e777562696e776f726b732e636f6d2f6d656469612f7368617265642f63616368652d7761726d65722f63616368652d7761726d65722e6a7067 "Magento 2 Free Sitemap Based Cache Warmer Extension")](https://www.wubinworks.com/free-cache-warmer.html)

Introduction
------------

[](#introduction)

Magento 2 comes with [*Full Page Cache*](https://experienceleague.adobe.com/en/docs/commerce-admin/systems/tools/cache-management#full-page-caching) out-of-the-box. Users can choose *"Built-in Cache"*, *"Varnish Cache"* or *"CDN"*(requires installing the CDN's free extension).
However, no matter which caching application is employed, **Magento 2 still lacks the ability to let the caching application serve *"Warm Cache"***. In other words, a web page feels slow when it is visited the first time. The reason is at that time, the CDN didn't have the *warm cache* yet.
Adobe Commerce Cloud does have a [*Post-deploy cache warming environment configuration*](https://experienceleague.adobe.com/en/docs/commerce-on-cloud/user-guide/configure/env/stage/variables-post-deploy#warm_up_pages), but it is not a Magento extension and not user friendly. It only offers limited features. For example, it can neither warm up static content nor keep the populated cache warmed.

The goal of this extension is to become an ultimate solution to suit the needs of cache warming for a Magento store. It focuses on real-world business use cases by covering [widely used content types](#_why_sitemap_based) including blog posts and keeps [automation](#_deployment_automation) in mind.

Feature Highlights
------------------

[](#feature-highlights)

- Support 4 *Content Types*
- Warm up HTML pages located in sitemaps or [URL list files](#_url_list_example)
    [![Sitemaps](https://camo.githubusercontent.com/807dd44d64ed473f1ab87449f6473153d1b8f68fdc3ff09a6241e68f5c219ee7/68747470733a2f2f7777772e777562696e776f726b732e636f6d2f6d656469612f7368617265642f63616368652d7761726d65722f736974656d61702d7572692e706e67 "Sitemaps")](https://www.wubinworks.com/media/shared/cache-warmer/sitemap-uri.png)
- Warm up `static` and `media` content(i.e., files in `pub/static` and `pub/media` directories) with configurable filters
    *Those contents are typically, JS, CSS and image files.*
    [![Static and Media content](https://camo.githubusercontent.com/d963077e5334f0afe38c6f8a81718441d9204a934bf2b9b7e64a450a260f9071/68747470733a2f2f7777772e777562696e776f726b732e636f6d2f6d656469612f7368617265642f63616368652d7761726d65722f7374617469632d616e642d6d656469612d636f6e74656e742e706e67 "Static and Media content")](https://www.wubinworks.com/media/shared/cache-warmer/static-and-media-content.png)
- Warm up [Dynamic Catalog Images](#_dynamic_catalog_image)
    *(This content type requires Magento &gt;= 2.4.2)*
- Schedule tasks by predefined or user-defined `cron` expression

    - [*Which frequency should I use and how to keep the cache warmed?*](#_cache_lifetime)
- A button to schedule a task to be run in the next minute
    *It can be considered as a non-blocking "Run Manually"*
- Control task duration by setting `global timeout` and request sending `concurrency`
- GUI task status display with progress information
- Custom [HTTP proxy](#_http_proxy) for environments with restricted outbound connections
    *The user can also disable [HTTP proxy](#_http_proxy) entirely or just use the system one*
- Internal HTTP client tweaking
    *Available configurations: Timeout, Download Size Limit(Security Concern), Retries, Retry Delay*
    *The purpose of these configurations is to prevent getting stuck in the cache warming process*
    [![Internal HTTP client tweaking](https://camo.githubusercontent.com/e4395e9e9a80141a5ca4bc6693874c3934746ae94052411a3ceb6bcf0ae69959/68747470733a2f2f7777772e777562696e776f726b732e636f6d2f6d656469612f7368617265642f63616368652d7761726d65722f696e7465726e616c2d687474702d636c69656e742e706e67 "Internal HTTP client tweaking")](https://www.wubinworks.com/media/shared/cache-warmer/internal-http-client.png)
- CLI command with progress details
    [Usage](#_command_line_usage)
    [![CLI command with progress details](https://camo.githubusercontent.com/146e4806710664bac3320f2bbb8400ff30d40d7df6eb4ca94c23fa14527c09e5/68747470733a2f2f7777772e777562696e776f726b732e636f6d2f6d656469612f7368617265642f63616368652d7761726d65722f636c692d776974682d70726f67726573732d6d657465722e706e67 "CLI command with progress details")](https://www.wubinworks.com/media/shared/cache-warmer/cli-with-progress-meter.png)
- [Deployment Automation](#_deployment_automation)

Why Sitemap Based?
--------------------------------------------------------------

[](#why-sitemap-based)

Instead of retrieving URLs from the standard *"3 content types"* (i.e., *product, category and CMS*) internally, it is more practical to extract URLs from sitemaps. In this way, content types introduced by third-party extensions such as blog posts, product tags are covered as well. Any custom content which includes itself into the sitemap can be warmed up.
In addition, our design gives the user more freedom and flexibility. The user can specify multiple sitemaps as [Sitemap URIs](#_sitemap_uri), which means the sitemap to feed the *Cache Warmer* can be [automatically generated by Magento's built-in feature](https://experienceleague.adobe.com/en/docs/commerce-admin/marketing/seo/sitemap-xml) and/or managed by external tools. The user can even use *gzipped* sitemap.

Why URL List?
-------------

[](#why-url-list)

A URL list is simply a text file containing line separated URLs. For most systems, generating such a file is extremely straightforward.

A typical use case is when the store has like more than 10,000 products. Warming up the entire store will cost a huge amount of resource and time. The recommended way is to pick some products from the entire store by the user's own criteria and then put their URLs in a `txt` file to feed the *Cache Warmer*.
To be more specific, for example, the user can export products from the "Top Sellers" category to a CSV file and get their `url_key`s to build full URLs. Then the user saves those URLs to a `top-sellers.txt` file which will be used as a [Sitemap URI](#_sitemap_uri).

*Supported [Sitemap URI](#_sitemap_uri) and [Sitemap Formats](#_supported_sitemap_formats)*

Sitemap URI
-------------------------------------------------

[](#sitemap-uri)

#### Security Warning

[](#security-warning)

The "Sitemap" can be on local or remote servers and acts as a "user input".
*It is the user's responsibility to make sure the content of the sitemap is controlled only by the user.*

#### Supported Schemes

[](#supported-schemes)

- `http://`
- `https://`
- `file://`

#### Supported Sitemap Formats

[](#supported-sitemap-formats)

- `XML` sitemap
- [Line separated text file(URL list)](#_url_list_example)
- `GZIP`ped file of the above two
- `robots.txt` containing `Sitemap:` directives

#### Sitemap URI Example

[](#sitemap-uri-example)

```
# Line starting with # is treated as comment.
#
# -- Sitemap --
https://www.example.com/sitemap.xml
#
# -- Line separated URL list --
https://www.example.com/hot-urls-list.txt
#
# -- Local file --
file:///var/app/pub/sitemap.xml
#
# -- Gzipped Sitemap --
https://www.example.com/sitemap.xml.gz
#
# -- Robots --
https://www.example.com/robots.txt
```

#### URL List Example

[](#url-list-example)

A `.txt` file with content like:

```
https://www.example.com/product1.html
https://www.example.com/product2.html
...
```

Static and Media Content
------------------------

[](#static-and-media-content)

The *Cache Warmer* scans `pub/static` and `pub/media` directories and build all URLs for those files.

#### File Exclusion

[](#file-exclusion)

- Files with size larger than the "Maximum File Size" will be excluded. The "Maximum File Size" value should be smaller than the [CDN's maximum cacheable file size limit](#_maximum_cacheable_file_size_limit)
- Unix-like hidden files(file name starting with a `.`) and files in hidden directories are always ignored for security concerns
- Files with the following extensions are ignored because they **cannot be cached by CDNs**
    (There are many reasons can be found in Magento's codebase, such as [here](https://github.com/magento/magento2/blob/a04b0efee5ee80ae981130002b0eeeec0e3c6538/pub/static/.htaccess#L81-L83), [here](https://github.com/magento/magento2/blob/dc87600a0ab002bb2b7ef573fe78cfc951edb36c/pub/media/.htaccess#L82-L84) and [here](https://github.com/magento/magento2/blob/dc87600a0ab002bb2b7ef573fe78cfc951edb36c/app/code/Magento/PageCache/etc/varnish6.vcl#L184-L193))

```
zip gz gzip bz2 csv xml
```

#### Static Content

[](#static-content)

- Static content must be deployed first before warming it up
- All [deployment strategies](https://experienceleague.adobe.com/en/docs/commerce-operations/configuration-guide/cli/static-view/static-view-file-strategy) are supported by this extension
- Only store frontend static content will be warmed up

Dynamic Catalog Images
----------------------------------------------------------------------

[](#dynamic-catalog-images)

#### Requirements

[](#requirements)

- Magento &gt;= 2.4.2

Magento 2.4.2 introduced a new feature -- [Image optimization based on query parameters](https://experienceleague.adobe.com/en/docs/commerce-admin/catalog/catalog/catalog-urls#configure-catalog-media-url-format) for catalog images.

#### Configuration Location

[](#configuration-location)

```
Stores > Settings > Configuration > Url Options > Catalog media URL format
```

This feature can let product use *Dynamic URLs* with resizing parameters.

#### Dynamic Product Image URL Example

[](#dynamic-product-image-url-example)

```
https://www.example.com/media/catalog/product/p/r/product-image.jpg?width=350&height=500&store=main&image-type=small_image
```

The *Cache Warmer* is capable of "calculating" all of those URLs.

#### Important Notes

[](#important-notes)

*This content type will be automatically disabled at runtime if the Magento version does not meet the requirements or the above configuration is not set to "Image optimization based on query parameters".*

*Images of disabled products are excluded.*

CDN Caching Behavior
--------------------

[](#cdn-caching-behavior)

### Cache Lifetime

[](#cache-lifetime)

The cache warming is not a "one-time job", CDN cache has lifetime. They have a **TTL**(Time-To-Live) configuration, but this configuration is usually used as a fallback. In most cases, the TTL is informed by HTTP response headers which can be controlled by the web application(i.e., Magento).

*However, somemany CDNs do not "respect" the specified TTL. According to their documentation, less popular content will be removed before its TTL expires and this is an **expected behavior**.*
*For example, we observed that on Fastly, if a web page is not accessed for 2 hours, it will be removed from their cache even the TTL is 1 day.*

**To keep the populated cache warmed, adjust the *"Frequency"* configuration properly.**

### Maximum Cacheable File Size Limit

[](#maximum-cacheable-file-size-limit)

CDNs always have a maximum cacheable file size limit. This limit can be found in their documentations and varies from CDN to CDN, plan to plan. Files larger than this limit cannot be cached by CDN, hence there is no need to warm up those files.

**To exclude those large files, set the [*"Maximum File Size"*](#_file_exclusion) value properly.**

How Long Does The Process Take?
-------------------------------

[](#how-long-does-the-process-take)

This extension already makes use of simultaneous requests to speed up the cache warming process.

The time it takes mainly depends on how many products the store has and the web server's performance. If the store has a lot of blog posts, CMS pages, this will become an affecting factor as well.

*In our test case, the process takes around 20 ~ 40 minutes to finish for a store having around 1000 products and concurrency set to 25.*

Bonus Feature
-------------

[](#bonus-feature)

Output failed URLs collected from the cache warming process with [Error Codes](#_error_codes) to a `CSV ` file

*This feature demonstrates how to customize this extension by utilizing its [dispatched events](#_dispatched_events).*
*The [Error Codes](#_error_codes) can help diagnose problems, especially problems in sitemaps.*

### Error Codes

[](#error-codes)

CodeExplanationTypical Causes-30Unknown internal HTTP client errorExtension or its dependencies' bug\[1\]-20Invalid internal HTTP client option errorCustomization bug-10Unknown error10Connection error- Connection timeout\[2\]
- Server refused connection

20Invalid request or response errorRequest
- Domain name unresolvable\[2\]
- Malformed URL input

Response
- Response size is too large(Check internal HTTP client configuration)

303XX redirect loop error- Incorrect web server configuration
- Incorrect [URL Rewrite](https://experienceleague.adobe.com/en/docs/commerce-admin/marketing/seo/url-rewrites/url-rewrite) configuration

&gt;=100*HTTP status code*1. *Negative error codes should not occur. Negative error code indicates there is probably a bug in this extension or its dependencies or its customization.*
2. *The cause can be on the [HTTP proxy](#_http_proxy) server side. For example:*

- *The connection timeout may be caused by an incorrect HTTP proxy server address*
- *The HTTP proxy server may not be able to resolve domain name*

*If you saw negative error codes but did not customize this extension, please [report](#_report_issues) the error to improve this extension.*

Command Line Usage
---------------------------------------------------------------

[](#command-line-usage)

```
php bin/magento ww:cache-warmer:run [--try-number TRY-NUMBER]
```

This command is designed for *"Run Manually"*.

`ww:cache-warmer:run` can be shorten to `ww:cw:run`.

`--try-number` is optional and for debug purpose only. It limits how many URLs will be picked out from each *"Content Type"*. This option can be used to perform a quick test of sitemaps and configurations.

Deployment Automation
---------------------------------------------------------------------

[](#deployment-automation)

It is a good practice to place the command in deployment scripts.
Once the extension is properly configured, you can forget about it and the CDN cache will stay warm constantly.

HTTP Proxy
-----------------------------------------------

[](#http-proxy)

The user can just use the system-provided HTTP proxy server or a custom one.

This feature is also capable of handling the following situations.

- The system has a default HTTP proxy and the user wants to use a different one
- The system has a default HTTP proxy and the user wants to bypass it

#### HTTP Proxy Mode

[](#http-proxy-mode)

ModeExplanationSystemRespect environment variables such as `http_proxy`, `HTTPS_PROXY` and `NO_PROXY`DisabledCompletely ignore environment variablesCustomUse custom HTTP proxy address and ignore `NO_PROXY` environment variableLogging
-----------------------------------------

[](#logging)

Task run results are logged at

```
/var/log/wubinworks_cachewarmer.log
```

Free Forever
------------

[](#free-forever)

You DON'T need to worry that some features are not free or this repository will be silently deleted or even the entire extension becomes a paid one.

You can use this extension in your projects as an ***open dependency***.

*License: [Open Software License (OSL 3.0)](https://github.com/wubinworks/magento2-free-cache-warmer/blob/master/LICENSE.txt)*

*Although this is a Free extension, it is aiming to be professional, fit most business scenarios and become a complement of Magento's Page Caching feature. If you have good ideas about this extension, do not hesitate to [share](#_report_issues) them.*

Installation
------------

[](#installation)

#### Requirements

[](#requirements-1)

- Magento 2.3 or 2.4

*Important Notes: this extension is not tested on Magento 2.3, but you can give a try and any [feedback](#_report_issues) is appreciated.*

#### Install via `composer`

[](#install-via-composer)

```
composer require wubinworks/module-cache-warmer
```

*This extension requires dependencies that Magento 2 does not come with by default.*
*Installing to `app/code` will not work.*

#### Configuration Location

[](#configuration-location-1)

```
Stores > Wubinworks > Free Cache Warmer
```

Report Issues
-----------------------------------------------------

[](#report-issues)

### General Issues

[](#general-issues)

- Bugs
- Ideas and questions
- Translation contribution and correction

Use [Github Issues](https://github.com/wubinworks/magento2-free-cache-warmer/issues).

### Security Issues

[](#security-issues)

Use the [Contact Form](https://www.wubinworks.com/contact?from=github&title=Security%20Issue&extension=Wubinworks_CacheWarmer).
**NEVER OPEN A SECURITY ISSUE PUBLICLY**

### Customization Issues

[](#customization-issues)

Please [contact us](https://www.wubinworks.com/contact?from=github&title=Customization&extension=Wubinworks_CacheWarmer) directly.
The *"Github Issues"* is only for problems residing in the extension itself.

For Developers
--------------

[](#for-developers)

### Translation

[](#translation)

#### Current Available Languages

[](#current-available-languages)

- English
- Japanese

#### Translation Contribution

[](#translation-contribution)

- Translation [contribution or correction](#_report_issues) is welcome.
- [Translation Contributors](https://github.com/wubinworks/magento2-free-cache-warmer/blob/master/AUTHORS.md#translations)

### Dispatched Events

[](#dispatched-events)

- `wubinworks_cachewarmer_cron_run_before`
    Area: `crontab`
    By observing this event, the developer can perform custom actions such as interacting with the CDN's API before running the task. The developer can also obtain the schedule information and implement custom logic to make a final decision whether to run or skip the task.

```
/** @var \Magento\Framework\Event\Observer $observer */

// Get schedule model
/** @var \Magento\Cron\Model\Schedule $schedule */
$schedule = $observer->getSchedule();

// Skip entire task
$observer->getEventData()->setSkipTask(true);

// Set OPTIONAL skip task message
$observer->getEventData()->setSkipTaskMessage(
    'This message will be logged and displayed as the task progress message when task was skipped.'
);
```

- `wubinworks_cachewarmer_cachewarmer_on_progress`
    Area: `global`
    By observing this event, the developer can get the task progress information and its current processing result.

```
/** @var \Magento\Framework\Event\Observer $observer */

// Get run type
var_dump($observer->getRunType());
// 'CRON' or 'CLI'

// Get progress information
var_dump($observer->getProgress()->getData());

// Get current item
/** @var \Magento\Framework\DataObject $currentItem */
$currentItem = $observer->getCurrentItem();

var_dump($currentItem->getUrl());
var_dump($currentItem->getStatus()); // 'success' or 'error'
var_dump($currentItem->getCode()); // Check "Error Codes" section
```

- `wubinworks_cachewarmer_cachewarmer_run_after`
    Area: `global`
    By observing this event, the developer can get the final results of the task, such as URLs with invalid responses. Then the developer can implement custom logic to handle those results.

```
/** @var \Magento\Framework\Event\Observer $observer */

// Get run type
var_dump($observer->getRunType());
// 'CRON' or 'CLI'

// Get Cache Warmer report
/** @var \Wubinworks\CacheWarmer\Model\CacheWarmer\Report $report */
$report = $observer->getReport();

// Get failed sitemaps
var_dump(reset($report->getFailedSitemaps()));

// Get failed URLs
var_dump(reset($report->getFailedUrls()));
```

Miscellaneous
-------------

[](#miscellaneous)

- The purpose of this extension is to warm up CDN/Varnish cache. Any other usage is considered out of development scope.
- The *Cache Warmer* only works for the ***current Magento instance***. This is also a security concern. If you found any URLs are not warmed up, please check the [log](#_logging).
- This extension supports multiple store setup and by default the *Cache Warmer* runs for all stores. There is a hidden configuration that can exclude certain stores.

♥
-

[](#)

If you like this extension or this extension helped you, please ***share*** it and ***★star☆*** [this repository](https://github.com/wubinworks/magento2-free-cache-warmer).

You may also like:
[Magento 2 Disable Customer Extension](https://github.com/wubinworks/magento2-disable-customer "Magento 2 Disable Customer Extension")
[Magento 2 Disable Customer Change Email Extension](https://github.com/wubinworks/disable-change-email "Magento 2 Disable Customer Change Email Extension")
[Magento 2 Price Formatter Extension](https://github.com/wubinworks/magento2-price-formatter "Magento 2 Price Formatter Extension")

###  Health Score

30

—

LowBetter than 62% of packages

Maintenance49

Moderate activity, may be stable

Popularity25

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity32

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

375d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/7de965a6287fb784969afeb4b173521d3cb59c6b873b7248263abb9fc098eddd?d=identicon)[wubinworks](/maintainers/wubinworks)

---

Top Contributors

[![wubinworks](https://avatars.githubusercontent.com/u/127310257?v=4)](https://github.com/wubinworks "wubinworks (1 commits)")

---

Tags

automationcache-warmercache-warmingcdncrondeployment-scripteasily-customizablefreefull-page-cachemagento2magento2-extensionmagento2-extension-freemagento2-moduleopen-dependencyperformance-optimizationsitemapautomationcronfreecdnSitemapmagento2magento 2 extensionfull page cachecache warmerPerformance Optimizationcache warmingdeployment scripteasily customizableopen dependency

### Embed Badge

![Health badge](/badges/wubinworks-module-cache-warmer/health.svg)

```
[![Health](https://phpackages.com/badges/wubinworks-module-cache-warmer/health.svg)](https://phpackages.com/packages/wubinworks-module-cache-warmer)
```

###  Alternatives

[nexxai/laravel-cfcache

A handful of Cloudflare cache helpers for Laravel

13314.7k](/packages/nexxai-laravel-cfcache)[meema/laravel-cloudfront

Easily &amp; quickly integrate your application with AWS CloudFront.

31128.3k](/packages/meema-laravel-cloudfront)[mmamedov/page-cache

PageCache is a lightweight PHP library for full page cache. It uses various strategies to differentiate among separate versions of the same page.

7913.3k1](/packages/mmamedov-page-cache)[spekkionu/assetcachebuster

Prefixes asset urls with a unique hash which will allow invalidation of asset files cached by the browser.

3243.4k](/packages/spekkionu-assetcachebuster)[redchamps/module-easy-cache-clean

Clean invalidated cache(s) easily in a Magento 2 store

2944.0k](/packages/redchamps-module-easy-cache-clean)[b13/proxycachemanager

TYPO3 Extension that automatically flushes cached URLs within a proxy / CDN.

10109.4k](/packages/b13-proxycachemanager)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
