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.

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.
- MilliCache’s real innovation is semantic invalidation, not just fast page delivery.
- Its early bootstrap path lets WordPress short-circuit before the heavy stack loads.
- The storage layer is built for distributed infrastructure, not a single-server plugin setup.
- Multisite isolation and typed PHP make the cache behave like infrastructure software.
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.
| Approach | What it caches | Invalidation model | Scale fit |
|---|---|---|---|
| File-based plugin cache | HTML on disk | Clear page or clear all | Good for small sites |
| Server cache | Whole responses at the edge or proxy | Fast, but WordPress-unaware unless carefully wired | Strong, but operationally tricky |
| MilliCache | HTML in shared in-memory storage | Flags and rules target related pages | Built 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.
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 posture | Strength | Trade-off | What MilliCache assumes |
|---|---|---|---|
| Single-node Redis | Simple to run | Less resilient under failure | Good starting point |
| Replicated or sentinel setup | Higher availability | More operational moving parts | Shared cache across web servers |
| Valkey, Dragonfly, KeyDB | Modern in-memory alternatives | Backend differences vary | Backend 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
| Project | Type | Invalidation style | Why it stands apart |
|---|---|---|---|
| MilliCache | Redis-native WordPress plugin | Semantic flags and rules | WordPress-aware and infrastructure-minded |
| Redis Page Cache | Redis-backed plugin | Page-level cache clearing | Similar backend, less expressive invalidation |
| Cachify | Plugin cache | Simpler purge behavior | Lightweight and broad, not flag-centric |
| Cache Enabler | Disk-based plugin | File purge | Fast on disk, not shared memory |
| WP Rocket | Commercial plugin | Page and asset optimization | User-friendly, but not a shared in-memory system |
| Nginx FastCGI Cache | Server cache | Proxy-level purges | Extremely fast, but WordPress-aware invalidation is harder |
| Batcache | Memcached page cache | Response caching | A 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!
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.