millipress / millicache
The most flexible Full Page Cache for scaling WordPress sites. Enterprise-grade in-memory store with Redis, ValKey, Dragonfly, KeyDB, or any alternative.
Installs: 3
Dependents: 0
Suggesters: 0
Security: 0
Stars: 5
Watchers: 1
Forks: 0
Open Issues: 2
Type:wordpress-plugin
pkg:composer/millipress/millicache
Requires
- php: >=7.4
- millipress/millirules: ^0.4.0
- predis/predis: ^2.2
Requires (Dev)
- mockery/mockery: ^1.6
- pestphp/pest: ^2.0
- php-stubs/wp-cli-stubs: ^2.10
- phpcompatibility/phpcompatibility-wp: *
- phpstan/extension-installer: ^1.3
- phpstan/phpstan: @stable
- phpstan/phpstan-deprecation-rules: ^1.1
- roave/security-advisories: dev-latest
- swissspidy/phpstan-no-private: ^0.2.0
- szepeviktor/phpstan-wordpress: ^1.3
- wp-coding-standards/wpcs: ^3.0
Suggests
- ext-zlib: Allows MilliCache to compress the cache with zlib.
- dev-main
- v1.0.0-rc.3
- v1.0.0-rc.2
- v1.0.0-rc.1
- v1.0.0-beta.5
- v1.0.0-beta.4
- v1.0.0-beta.3
- v1.0.0-beta.2
- v1.0.0-beta.1
- dev-fix/release-changelog-commits
- dev-fix/release-changelog-previous-tag
- dev-feat/cli-clear-related
- dev-fix/remove-obsolete-encrypt-flag
- dev-ci/optimize-workflows
- dev-archive/pre-cleanup-2025-12
This package is auto-updated.
Last update: 2025-12-11 08:41:58 UTC
README
MilliCache is a fast & flexible full-page caching solution for WordPress. It uses in-memory key-value stores like Redis, Valkey, KeyDB, or Dragonfly as its backend to store cached pages. By leveraging in-memory storage capabilities, MilliCache is exceptionally fast, reliable, and scalable. Moreover, it allows for highly efficient and targeted cache invalidation, greatly increasing both efficiency and flexibility. This is especially important for the future of WordPress, as it enables more dynamic content and complex caching strategies — for example, with the use of the Block Editor.
Optimized for both WordPress Multisite and Single Site setups, MilliCache provides a versatile and robust caching solution for all types of WordPress environments.
Important
This plugin is currently in the Release Candidate stage and approaching a stable release. While suitable for testing in production-like environments, please exercise caution and report any problems you encounter.
Table of Contents
- Features
- Requirements
- Installation
- Configuration
- Cache Flags
- Clearing Cache
- WP-CLI Commands
- Debugging
- Hooks & Filters
- User Capability Management
- Testing
Features
- Lightning Fast: In-memory full-page caching using Redis or an alternative.
- Settings UI: Easy configuration and cache management through the WordPress admin.
- Cache RequestFlags: High efficiency by supporting complex cache logic and selective clearing.
- Expired Cache Handling: Regenerates cache in the background.
- Multisite Optimized: Ideal for WordPress Multisite and Multi-Network.
- Extensible: Provides various hooks & filters.
- Gzip Compression: Compresses cache to reduce memory usage.
- WP-CLI Commands: Manage cache via command line.
- Debugging: Provides cache information in headers.
- Scalable: Works with server clusters.
- Object Cache: Works with Redis object cache plugins like WP Redis & Redis Object Cache.
- Flexible Storage: Compatible with Redis Server, Valkey, KeyDB & Dragonfly.
Requirements
- PHP 7.4 or higher (PHP 8.x recommended for performance)
- A compatible in-memory storage server, either installed locally or accessible via network:
Storage Server Configuration
Make sure your storage server has enough memory allocated to store your cached pages. MilliCache compresses cached pages using gzip to reduce memory usage. However, you need to keep an eye on your cache size in the Dashboard to increase according to your hit rate.
For Redis, Valkey, and KeyDB, we recommend disabling persistence to disk and using the allkeys-lru eviction policy
to ensure the server can make more room for new cached pages by evicting old ones.
Here is an example configuration:
# Set maximum memory e.g. to 16 megabytes
maxmemory 16m
# Set eviction policy to remove less recently used keys first
maxmemory-policy allkeys-lru
Remember to restart your storage server after making changes to the configuration file.
Installation
-
Install via:
-
ZIP-File:
- Download the latest release.
- Upload the ZIP file in your WordPress admin area under
Plugins > Add New > Upload Plugin.
-
Composer:
$ composer config repositories.millicache vcs https://github.com/millipress/millicache $ composer require millipress/millicache
-
-
Activate the plugin in your WordPress installation.
-
Configure the plugin in your Dashboard
Settings -> MilliCacheor by defining constants in yourwp-config.php. -
Enable WordPress caching by adding to
wp-config.php:define('WP_CACHE', true);
Configuration
Configure MilliCache either in your Dashboard Settings -> MilliCache
or by setting constants in your wp-config.php file.
You can combine both methods, the constants overwrite the settings with higher priority.
# Optional: Set Settings with Constants define('MC_STORAGE_HOST', '127.0.0.1'); define('MC_STORAGE_PORT', 6379);
General Configuration
| Constant | Description | Default |
|---|---|---|
MC_CACHE_DEBUG |
Enable Debugging | false |
MC_CACHE_GZIP |
Enable Gzip Compression | true |
MC_CACHE_TTL |
Default Cache TTL (Time To Live) | DAY_IN_SECONDS |
MC_CACHE_GRACE |
Grace Period of stale cache for regenerating content | MONTH_IN_SECONDS |
MC_CACHE_NOCACHE_PATHS |
Paths which are not cached | [] |
MC_CACHE_NOCACHE_COOKIES |
Cookies which avoid caching | ['comment_author'] |
MC_CACHE_IGNORE_COOKIES |
Cookies that are ignored/stripped from the request | [] |
MC_CACHE_IGNORE_REQUEST_KEYS |
Request keys that are ignored | ['_*', 'utm_*', ...] |
MC_CACHE_UNIQUE |
Variables that make the request & cache entry unique | [] |
Note
MilliCache supports wildcard patterns and Regex for path, cookie and request key configurations, allowing for more flexible cache control: ['cookie_*', 'coo*_*', /^/(product|category)/.*/].
Storage Server Connection Configuration
| Constant | Description | Default |
|---|---|---|
MC_STORAGE_HOST |
Storage Server Host | 127.0.0.1 |
MC_STORAGE_PORT |
Storage Server Port | 6379 |
MC_STORAGE_PASSWORD |
Storage Server Password | '' |
MC_STORAGE_DB |
Storage Server Database | 0 |
MC_STORAGE_PERSISTENT |
Storage Server Persistent Connection | true |
MC_STORAGE_PREFIX |
Storage Server Key Prefix | mll |
Cache Flags
MilliCache supports cache flags to group and clear caches based on flags, useful for complex cache handling.
What are Cache Flags?
A single post or page can generate multiple cache entries because the cache keys change based on the request details, such as different cookies or query parameters. For example, the following URLs, although they refer to the same content, will have separate cache entries:
https://example.org/?p=123https://example.org/post-slug/https://example.org/post-slug/page/2/https://example.org/post-slug/?show_comments=1
These different cache entries are necessary because each URL might serve slightly different content.
However, they are all related to the same post or page.
To manage these related entries efficiently, MilliCache groups them using cache flags.
In this case, all entries might share a flag like post:123.
Cache flags allow you to:
- Identify cache entries
- Assign multiple flags to a cache entry for flexible grouping.
- Group entries logically under a common identifier.
- Target cache entries for clearing at once by targeting a specific flag.
- Provide extension points for custom flags from themes/plugins.
For example, to clear all cache entries related to a specific post,
you can use the flag post:123 with WP-CLI commands, the Settings UI or MilliCache's clearing functions.
Built-in Flags
Important
Flag prefixes are only added in multisite and multinetwork installations. Here's how the same flag appears in different WordPress setups:
| Installation Type | Example Flag Format | Examples |
|---|---|---|
| Single site | flag:value |
post:123, home, custom_flag |
| Multisite | site_id:flag:value |
1:post:123, 2:home, 3:custom_flag |
| Multinetwork | network_id:site_id:flag:value |
1:2:post:123, 1:3:home, 2:1:custom_flag |
When using WP-CLI or API functions, you must include these prefixes appropriately for multisite/multinetwork environments.
The basic built-in flags are:
| Flag | Description |
|---|---|
home |
Added to home & blog pages |
post:{post_id} |
Added to all posts, pages & CPT (Post ID) |
archive:{post_type} |
Added to all post type archive pages (Post Type) |
archive:{taxonomy}:{tax_id} |
Added to taxonomy archives (e.g. category or tag archives) |
archive:author:{author_id} |
Added to author archive pages (Author ID) |
archive:{year} |
Added to date archive pages for a specific year |
archive:{year}:{month} |
Added to date archive pages for a specific month |
archive:{year}:{month}:{day} |
Added to date archive pages for a specific day |
feed |
Added to all feed pages |
Flags dynamically adapt based on the content and current page context, ensuring maximum control and flexibility when managing the cache.
Adding Custom Cache Flags:
You can define your own cache flags to group entries based on specific conditions
by using the millicache_custom_flags filter.
For instance, if you want to group all posts containing a particular Gutenberg block:
-
Add a Custom Flag:
add_filter('millicache_custom_flags', function( $flags ) { if ( has_block('my-custom/block') ) { $flags[] = 'block:my-custom/block'; } return $flags; });
-
Clear the Cache Using the Custom Flag: Instead of clearing the entire cache, you can clear only the entries with the custom flag:
# Single site - clear all pages with the custom block wp millicache clear --flag="block:my-custom/block" # Single site - clear all posts and home page wp millicache clear --flag="post:123,home" # Multisite - clear all posts on site 1 wp millicache clear --flag="1:post:*" # Multisite - clear home pages across all sites wp millicache clear --flag="*:home" # Multinetwork - clear all content on network 2, site 3 wp millicache clear --flag="2:3:*"
This way, you efficiently manage your cache by only refreshing the parts that need updating, saving resources, and improving performance.
Clearing Cache
By default, MilliCache uses two key time settings to control cache behavior:
- TTL (Time-To-Live): Period when cache is considered fresh
- Grace Period: Additional time after TTL expires when stale cache can still be served
When a cache entry reaches its TTL, it becomes "stale" but isn't immediately deleted. Instead, MilliCache serves the stale copy to visitors while regenerating a fresh cache in the background. This ensures users experience no delay during cache regeneration.
Cache entries expire whenever necessary. For example, when a post is published or updated, the cache entry for the post and the front page is cleared. When a site option is updated, all cache entries of the site are cleared, and so on.
Using the Settings UI
The MilliCache Settings UI provides a user-friendly way to clear cache:
- Navigate to
Settings -> MilliCachein your WordPress admin - In the "Cache Management" section:
- Use "Clear All Cache" to remove all cached entries
- Use "Clear By Flag" to selectively clear the cache by specific flags
- View the current cache statistics (size, entry count)
This interface makes it easy to manage cache without writing code or running CLI commands.
Using the Adminbar
MilliCache integrates with the WordPress admin bar for quick cache management:
- While logged in as an administrator, the admin bar displays a "MilliCache" menu item
- Click on the menu to reveal options:
- Clear All Cache: Immediately clear all cached content
- Clear by Flag: Expand to see common flag options (Home, Current Page, etc.)
- Settings: Quick access to the MilliCache settings page
This provides convenient access to cache management functions from any page of your site without having to navigate to the settings page.
Using PHP Functions
MilliCache offers various methods to clear the cache by flags, URLs, or IDs programmatically. You can also create custom hooks to clear or expire the cache whenever needed.
The $expire parameter in cache-clearing methods is optional:
- Set to
true: Cache entries expire and regenerate in the background on the next request. - Default (
false): Cache entries are deleted immediately.
Decide whether to expire or delete cache entries based on your requirements and how time-critical the content is.
-
Reset Cache
To reset the full cache.
/** * @param bool $expire Expire cache if set to true, or delete by default. (optional) */ millipress_reset_cache( $expire );
-
Clear Cache
A convenient method to clear the cache based on different target types in a single call. This method automatically determines the target type by its format (URL, numeric Post ID, or cache flag).
/** * @param string|array $targets String or array of targets to clear: * - URLs (any valid URL that starts with your site URL) * - Post IDs (any numeric value will be treated as a post-ID) * - Cache flags (any non-numeric, non-URL string will be treated as a flag) * @param bool $expire Expire cache if set to true, or delete by default. (optional) */ millipress_clear_cache( $targets, $expire );
Example usage:
// Clear cache for multiple types of targets, such as post-IDs, flags, or URLs. millipress_clear_cache( [ 'home', // Treated as a flag 'post:123', // Treated as a flag 123, // Treated as a post-ID 'https://example.com/special-page/' // Treated as a URL ] );
In multisite installations, the method automatically limits flag-based clearing to the current site when called from a non-network admin context.
-
Clear Cache by Flags
To clear the cache by specific flags. Please note the wildcard support below.
/** * @param string|array $flags Flag or array of flags to clear. * @param bool $expire Expire cache if set to true, or delete by default. (optional) */ millipress_clear_cache_by_flags( $flags, $expire );
Wildcards
MilliCache supports wildcards when clearing cache by flags. The way these wildcards are used depends on your WordPress installation type.
-
*-WildcardsThe
*can be used to match any number of characters. Here are examples of different WordPress installations:Installation Type Example Pattern What It Matches Single site post:*All posts (matches post:1,post:123, etc.)Single site archive:*All archive pages (matches archive:post, etc.)Multisite 1:post:*All posts on site 1 Multisite *:homeHome page on all sites (matches 1:home,2:home)Multinetwork 1:*:post:*All posts on all sites in network 1 Multinetwork *:*:homeHome pages across all sites in all networks -
?-WildcardsThe
?matches exactly one character:Installation Type Example Pattern What It Matches Single site post:?Posts with single-digit IDs (1-9) Multisite ?:homeHome pages on sites with single-digit IDs Multinetwork ?:?:*All content on sites with single-digit IDs in networks with single-digit IDs
-
-
Clear Cache by URLs
To clear the cache by specific URLs.
/** * @param string|array $urls URL or array of URLs to clear. * @param bool $expire Expire cache if set to true, or delete by default. (optional) */ millipress_clear_cache_by_urls( $urls, $expire );
-
Clear Cache by Post IDs
To clear the cache of specific posts, pages, or CPTs.
/** * @param int|array $post_ids Post ID or array of Post IDs to clear. * @param bool $expire Expire cache if set to true, or delete by default. (optional) */ millipress_clear_cache_by_post_ids( $post_ids, $expire );
-
Clear Cache by Site IDs
To clear the cache of specific sites in a WordPress Multisite network.
/** * @param int|array $site_ids Site ID or array of Site IDs to clear. * @param int|null $network_id Network ID (optional). * @param bool $expire Expire cache if set to true, or delete by default. (optional) */ millipress_clear_cache_by_site_ids( $site_ids, $network_id, $expire );
-
Clear Cache by Network ID
To clear the full cache of each site in a given network.
/** * @param int|null $network_id Network ID (optional, defaults to current network). * @param bool $expire Expire cache if set to true, or delete by default. (optional) */ millipress_clear_cache_by_network_id( $network_id, $expire );
Managing Cache Flags
MilliCache provides functions to manage flags for the current request, which are used to tag cache entries for efficient clearing.
-
Add Flag to Current Request
Add a flag to the current request. Flags are labels attached to cache entries that allow for efficient cache clearing.
/** * @param string $flag The flag name (e.g., 'post:123', 'custom-flag'). */ millipress_add_flag( $flag );
Example usage:
// Check if we're using a specific page template if ( is_page_template( 'templates/landing-page.php' ) ) { $flags[] = 'template:landing-page'; }
-
Remove Flag from Current Request
Remove a flag from the current request.
/** * @param string $flag The flag name to remove. */ millipress_remove_flag( $flag );
-
Get Flag Prefix
Get the prefix for flags based on site and network IDs. In multisite environments, flags are automatically prefixed with site and network IDs.
/** * @param int|string|null $site_id Site ID (null for current). * @param int|string|null $network_id Network ID (null for current). * @return string The prefix string (empty string for non-multisite). */ $prefix = millipress_get_flag_prefix( $site_id, $network_id );
-
Prefix Flags
Prefix an array of flags with site/network prefix. Useful when you need to manually construct prefixed flags in multisite environments.
/** * @param string|array $flags Flags to prefix (string or array). * @param int|string|null $site_id Site ID (null for current). * @param int|string|null $network_id Network ID (null for current). * @return array Array of prefixed flags. */ $prefixed_flags = millipress_prefix_flags( $flags, $site_id, $network_id );
Example usage:
// Prefix flags for a specific site in a multisite installation $flags = [ 'home', 'post:123' ]; $prefixed = millipress_prefix_flags( $flags, 2 ); // For site ID 2 // Result in multisite: [ '2:home', '2:post:123' ]
WP-CLI Commands
Note
WP-CLI is not context-aware of the current site in a multisite installation.
Therefore, when using flags in a multisite setup,
you must explicitly include the site ID as a prefix (e.g., 1:home for site ID 1).
If you're running multiple networks and issuing site-specific commands,
you must also include the network ID (e.g., 1:2:home for network ID 1 and site ID 2).
Get Stats
Get cache statistics such as the number of cache entries and cache size. The optional flag parameter can be used to filter the cache entries by a specific flag.
$ wp millicache stats [--flag="<flag>"]
Clear Cache
Clear the cache for specific flags, post-IDs, URLs, site IDs, or network IDs.
The optional --expire flag can be used to regenerate the cache entries in the background on the next request.
$ wp millicache clear [--flag="<flag>"] [--id="<id>"] [--url="<url>"] [--site="<site>"] [--network="<network>"] [--expire]
--flag supports wildcards and can be a single flag or a comma-separated list of flags, as with --id, --url, --site and --network.
Debugging
Enable debug mode by setting MC_CACHE_DEBUG to true in your wp-config.php. This adds headers to the response:
define('MC_CACHE_DEBUG', true);
Inspect response headers using cURL or browser developer tools:
curl -I https://example.com
Headers include:
X-MilliCache-Flags: The cache flags for the current request.X-MilliCache-Status: The cache status of the current request.X-MilliCache-Expires: The left TTL of the current request.X-MilliCache-Time: The cache time for the current request.X-MilliCache-Key: The cache key of the current request.X-MilliCache-Gzip: If Gzip compression is enabled.
Hooks & Filters
MilliCache provides several hooks and filters to extend functionality. Some examples:
millicache_should_cache_request
If the current request should be cached.
add_filter(`millicache_should_cache_request`, function( $should_cache ) { // E.g. do cache 404 pages if ( is_404() ) { return true; } return $should_cache; });
millicache_flags_for_request
Filter to add additional cache flags when creating a cache entry for the current request. These flags are stored alongside the cache and determine when and how it can be targeted & invalidated. This hook runs with WordPress fully loaded, so you may use conditional logic based on user roles, templates, queries, etc.
add_filter('millicache_flags_for_request', function( $flags ) { // Add a flag if a specific block is used. if ( is_singular() ) { $post = get_post(); if ( has_block( 'plugin/slider', $post ) ) { $flags[] = 'has_slider'; } } return $flags; });
millicache_flags_related_to_post
Filters the list of cache flags that are considered related to a specific post. This hook is used during invalidation (e.g., when a post is updated or deleted) to determine which cache entries should be cleared. The returned flags are not saved, only used for lookups during cache clearing operations.
add_filter('millicache_flags_related_to_post', function( $flags, $post ) { // If the post is of the type 'my_cpt' if ( $post->post_type === 'my_cpt' ) { // All entries with the 'cpt:my_cpt' flag are related and should be cleared $flags[] = 'cpt:' . get_post_type(); } return $flags; });
millicache_settings_clear_site_hooks
Filters the list of action hooks that trigger a full site cache clear. When one of these hooks is fired anywhere in your codebase, MilliCache will automatically clear the cache for the current site.
The array key is the hook name, and the value is the priority at which MilliCache should attach its clearing logic.
add_filter('millicache_settings_clear_site_hooks', function( $hooks ) { // Add a custom hook with priority that clears the cache $hooks['my_custom_hook'] = 10; return $hooks; });
Example: do_action( 'my_custom_hook' );
millicache_settings_clear_site_options
Filters the list of site options that trigger a full site cache clear when their value changes.
This is useful for ensuring that updates to critical settings — such as theme options, layout toggles, or feature flags — automatically invalidate the cache.
Each option name in the array refers to a top-level option stored via update_option() or the Settings API.
add_filter('millicache_settings_clear_site_options', function( $options ) { // Add a site option that clears the cache $options[] = 'my_custom_option'; return $options; });
Example:
update_option( 'my_custom_option', 'new_value' ); // → MilliCache detects this change and clears the full cache for the current site
User Capability Management
MilliCache provides a filter hook to customize which user capability is required for cache clearing operations. This allows you to control who can clear cache based on your site's specific needs, while settings access remains restricted to administrators for security.
millicache_clear_cache_capability
Controls the capability required to clear cache via admin bar and REST API endpoints.
add_filter('millicache_clear_cache_capability', function( $capability ) { // Allow authors to clear cache (default: 'publish_pages' for editors) return 'publish_posts'; });
Default: 'publish_pages' (Editor role and above)
Applied to:
- Admin bar cache clearing menu
- REST API
/wp-json/millicache/v1/cacheendpoint
Settings Access
Settings access is always restricted to the 'manage_options' capability (Administrator role and above) for security reasons.
This ensures that only administrators can:
- Access the MilliCache settings page in WordPress admin
- Use the REST API
/wp-json/millicache/v1/settingsendpoint - Use the REST API
/wp-json/millicache/v1/statusendpoint
Testing
Testing is automated with tools such as PHPUnit, PHPStan, and PHP CodeSniffer. For e2e-tests, we use Playwright running on @wordpress/env. That makes it basic for you to test the plugin in a real WordPress environment. To play with MilliCache or to run the tests, you need to have Docker and Node.js installed.
Start the Test Environment
The following commands will start the WordPress environment with MilliCache Plugin installed under http://localhost:8888.
Note
Another WordPress environment will be available under http://localhost:8889 for the Playwright tests.
Please note that this instance is configured for testing, e.g., with 5-second Cache-TTL.
So better to play with the first instance.
$ npm install $ npm run env:start
You can log in with admin and password.
Run the e2e-Tests
To run the Playwright tests under http://localhost:8889:
$ npm run env:e2e
Stop the Test Environment
To stop the environments:
$ npm run env:stop
Destroy the Test Environment
To destroy and remove the environments:
$ npm run env:destroy
Further useful commands
npm run env:cli wp ...- Run WP-CLI command at the WordPress environment. E.g.npm run env:cli wp millicache statsnpm run env:redis-cli- Open the Redis CLInpm run env:reset- Reset the WordPress environments and start from scratch
Credits
MilliCache is inspired by: