MilliCache: The WordPress Cache That Thinks in Flags, Not Pages

A Redis-native caching layer that serves HTML fast, isolates multisite traffic, and clears only the parts of the site that actually changed.

8 min read View on GitHub More from millipress

A wide editorial scene showing a WordPress request entering a forked control gate. One path is a blunt clear-all lever that washes over many page stacks. The other path is a branching network of tagged cache nodes where only the affected archives and taxonomy branches fade out. The image explains that MilliCache treats invalidation as a precise graph, not a site-wide reset.
MilliCache’s core idea is not just faster delivery. It is targeted invalidation.

MilliCache is application-aware full-page caching backed by Redis. So it can make decisions based on actual WordPress context — posts, terms, templates, blocks, query state, cookies, request patterns, custom hooks, etc.

Philipp Wellmer, Lead Developer / Maintainer · Introducing MilliCache: High-performance Redis page caching
Key Takeaways

Most WordPress cache plugins are optimized for one of two things: a quick hit rate or an easy panic button. MilliCache is more interesting because it changes the question. Instead of asking, “What page should I clear?” it asks, “What should this content change actually affect?”

That shift matters when the site has archives, taxonomies, multisite traffic, and multiple app servers sharing the same cache. A blunt purge is safe only because it is vague. MilliCache is built to be specific.

Why WordPress Caching Breaks at Scale

Classic caching in WordPress often collapses into a binary choice. Either cache aggressively and hope invalidation stays simple, or clear too much and lose the performance win. The problem is not storage. The problem is precision.

ApproachWhat it cachesInvalidation modelScale fit
File-based plugin cacheHTML on diskClear page or clear allGood for small sites
Server cacheWhole responses at the edge or proxyFast, but WordPress-unaware unless carefully wiredStrong, but operationally tricky
MilliCacheHTML in shared in-memory storageFlags and rules target related pagesBuilt for shared infrastructure

MilliCache’s Real Trick: Cache Flags

Flags are the project’s key idea. A cached response is not just a URL with a TTL. It belongs to a semantic set, such as a singular post, an archive, a taxonomy term, or a multisite-scoped surface. When content changes, MilliCache does not need to guess. It resolves the flags that matter and invalidates only the entries attached to them.

One content change fans out to a small, explainable set of flags, then to the cache entries those flags protect.

A close-up view of a cache registry board with pinned entries connected by small metal flags. Some pins are tagged as post, archive, or term relationships, and one pin has been pulled so only its connected entries are released while others remain fixed. The image explains how MilliCache uses flags to make invalidation tactile and selective.
Flags make the cache look less like a list of URLs and more like a relationship map.

That model is the difference between a cache as a blunt object and a cache as a system. URL-only purging says, “This page changed.” Flag-based invalidation says, “These relationships changed, and only these surfaces need attention.”

How the Engine Moves Requests From Bootstrap to Response

MilliCache’s speed starts before WordPress fully boots. The `advanced-cache.php` drop-in runs early in the request lifecycle, hands control to the engine, and checks storage before the rest of the stack wakes up. If there is a valid hit, the request ends there.

<?php
// wp-content/advanced-cache.php
require_once __DIR__ . '/plugins/millicache/src/Engine.php';

$engine = \MilliCache\Engine::instance();
$engine->start();

// If a cache hit is found, WordPress never loads the heavy stack.

That early exit is the point. MilliCache avoids the expensive path through full WordPress initialization, database connections, template resolution, and plugin churn when it already has the response.

Under the hood, the engine coordinates request parsing, storage lookup, validation, and response serving. The codebase is organized around that sequence, which keeps the hot path narrow and makes the behavior easier to reason about.

Storage Topology Is a First-Class Design Choice

MilliCache is not married to a single cache server. It supports Redis-compatible infrastructure including Valkey, Dragonfly, and KeyDB, plus topology-aware setups like replication and sentinel. That matters because cache correctness is an infrastructure problem, not just an API choice.

Backend postureStrengthTrade-offWhat MilliCache assumes
Single-node RedisSimple to runLess resilient under failureGood starting point
Replicated or sentinel setupHigher availabilityMore operational moving partsShared cache across web servers
Valkey, Dragonfly, KeyDBModern in-memory alternativesBackend differences varyBackend must behave like shared infrastructure

The interesting part is not just backend compatibility. It is that MilliCache treats cache storage as a distributed layer with failure handling, topology awareness, and request-level restraint when connectivity drops.

Multisite Without Cache Bleed

Multisite is where many WordPress caches get sloppy. If keys are not scoped correctly, one site can leak into another. MilliCache treats site identity as part of the cache model, so entries stay isolated even when multiple sites share the same backend.

That is not a flashy feature. It is the kind of correctness guarantee operators notice only when it is missing.

How It Compares to the Rest of the WordPress Cache Stack

ProjectTypeInvalidation styleWhy it stands apart
MilliCacheRedis-native WordPress pluginSemantic flags and rulesWordPress-aware and infrastructure-minded
Redis Page CacheRedis-backed pluginPage-level cache clearingSimilar backend, less expressive invalidation
CachifyPlugin cacheSimpler purge behaviorLightweight and broad, not flag-centric
Cache EnablerDisk-based pluginFile purgeFast on disk, not shared memory
WP RocketCommercial pluginPage and asset optimizationUser-friendly, but not a shared in-memory system
Nginx FastCGI CacheServer cacheProxy-level purgesExtremely fast, but WordPress-aware invalidation is harder
BatcacheMemcached page cacheResponse cachingA spiritual predecessor, not a modern flag graph

MilliCache sits in a narrow but useful middle space. It behaves like a WordPress plugin when it needs application context, and like infrastructure software when it needs to scale across hosts.

Why the Codebase Signals Serious Intent

The repository reads like infrastructure software, not a weekend plugin. Strict typing, PSR-style structure, Composer, PHPUnit, PHPStan, Playwright, GitHub Actions, and release automation all point to the same conclusion: the project is designed to be maintained, tested, and operated.

That does not guarantee good caching. It does signal that the team understands the difference between a demo and a system you can trust.

FastCGI not registering when changes are published has always annoyed me. I've tried it out a bit and it seems to work very well. Thanks for making this!

Tetrahedrax, Community Member · Roots Discourse Discussion

That reaction captures the appeal neatly. MilliCache is not trying to win by being the simplest cache in the room. It is trying to make WordPress caching behave like a controlled, explainable system.

A hedcut-style portrait of Philipp Wellmer, rendered from a verified GitHub avatar. The portrait identifies the maintainer behind MilliCache and gives a human face to the project’s engineering choices.