How It Works
Where QuantumCache operates in the request stack, what it caches, and how Pro extends behavior for WooCommerce and logged-in users.
What QuantumCache Is Not — Stated First
Not a full-page cache
QuantumCache does not store or serve complete HTTP responses. A full-page cache (e.g., WP Super Cache, W3 Total Cache in page cache mode) stores the entire rendered HTML output of a page request and serves it directly, bypassing PHP entirely. QuantumCache stores query results and rendered fragments produced during PHP execution — the components that are expensive to compute within a request.
Not a CDN
QuantumCache does not operate at the network edge or serve content from geographically distributed nodes. It operates at the origin server level, within the PHP/WordPress execution layer.
Where It Fits in the Request Stack
Requests absorbed by the CDN or page cache never reach QuantumCache. QuantumCache operates at the PHP/WordPress layer — it only affects requests that complete a full trip to the PHP application.
%% DIAG-001 — Request Stack / System Positioning Diagram
%% Source: qc_source_of_truth.md §7
%% QuantumCache does not replace CDN or page cache — it complements them.
flowchart TD
CLIENT["Client"]
CDN["CDN\n─────────────────────\nRequests absorbed here\nnever reach QC"]
PAGECACHE["Page Cache\n─────────────────────\nRequests absorbed here\nnever reach QC"]
PHP["PHP / WordPress + QuantumCache\n─────────────────────────────────────────────\nQC operates here — query and fragment caching\nduring PHP execution\nBenefits requests that reach PHP:\nlogged-in users (Pro) · dynamic Woo endpoints\npage cache misses · sites without a page cache"]
DB["Database"]
CLIENT -->|"request"| CDN
CDN -->|"cache miss / uncacheable"| PAGECACHE
PAGECACHE -->|"cache miss / uncacheable"| PHP
PHP -->|"DB query (on cache miss)"| DB
DB -->|"result"| PHP
PHP -->|"response"| PAGECACHE
PAGECACHE -->|"response"| CDN
CDN -->|"response"| CLIENT
note1["QuantumCache does not replace CDN or page cache — it complements them"]
note2["Bench environment (perf_bench / full_report): no CDN, no page cache.\nAll requests reached PHP. Measured reductions are directly attributable to QC."]
style CLIENT fill:#f5f5f5,stroke:#aaa
style CDN fill:#dbeafe,stroke:#3b82f6
style PAGECACHE fill:#dbeafe,stroke:#3b82f6
style PHP fill:#dcfce7,stroke:#16a34a
style DB fill:#f5f5f5,stroke:#aaa
style note1 fill:#fffbeb,stroke:#d97706,color:#92400e
style note2 fill:#f8f8f8,stroke:#ccc,color:#555 QuantumCache complements page caching and CDN layers — it does not replace them. In the benchmark environment, no CDN or page cache was present; all requests reached PHP.
QuantumCache benefits requests that do reach PHP:
- Dynamic WooCommerce endpoints that bypass full-page caching (product archives, product pages)
- Requests from logged-in users, when Pro's logged-in caching is configured for their role
- Page cache misses
- Sites operating without a full-page cache
In the benchmark environment (perf_bench and full_report runs), no CDN or page cache was present.
All requests reached PHP, making the measured TTFB reductions directly attributable to QuantumCache.
See Benchmarks for full results.
Cache MISS and HIT Flow
Every request that reaches the PHP layer is evaluated for cache eligibility before QuantumCache attempts a cache read or write.
%% DIAG-002 — Request Lifecycle: Cache MISS and HIT Flow
%% Source: qc_source_of_truth.md §6 (Terminology), assertions F1, F2, P1, P2
%% Scope: PHP layer only. Does not include CDN, page cache, or Pro bypass logic (see DIAG-004).
%% Full-page responses are NOT cached — only query results and fragments.
flowchart TD
REQ["Incoming anonymous request\n(reaches PHP layer)"]
CACHEABLE{"Cacheability check\nIs this request eligible\nfor the cache path?"}
MISS_QUERY["Query cache: MISS\n→ Execute DB query\n→ Store result in cache"]
MISS_FRAG["Fragment cache: MISS\n→ Render fragment\n→ Store fragment in cache"]
HIT_QUERY["Query cache: HIT\n→ Return cached result\n(DB call skipped)"]
HIT_FRAG["Fragment cache: HIT\n→ Return cached fragment\n(rendering skipped)"]
STORE["Cache store\n─────────────────\nRedis (primary)\nMySQL fallback"]
RESPONSE_MISS["Response\nX-QC-Main: MISS"]
RESPONSE_HIT["Response\nX-QC-Main: HIT\n─────────────────\nDatabase call skipped;\ncached results served"]
REQ --> CACHEABLE
CACHEABLE -->|"MISS (first / cold request)"| MISS_QUERY
CACHEABLE -->|"HIT (warm — after cache populated)"| HIT_QUERY
MISS_QUERY -->|"result stored"| STORE
MISS_QUERY --> MISS_FRAG
MISS_FRAG -->|"fragment stored"| STORE
MISS_FRAG --> RESPONSE_MISS
HIT_QUERY -->|"result read"| STORE
HIT_QUERY --> HIT_FRAG
HIT_FRAG -->|"fragment read"| STORE
HIT_FRAG --> RESPONSE_HIT
note1["First request (cold) follows MISS path.\nSubsequent matching requests follow HIT path after warm-up."]
style REQ fill:#f5f5f5,stroke:#aaa
style CACHEABLE fill:#fef9c3,stroke:#ca8a04
style MISS_QUERY fill:#fee2e2,stroke:#dc2626
style MISS_FRAG fill:#fee2e2,stroke:#dc2626
style HIT_QUERY fill:#dcfce7,stroke:#16a34a
style HIT_FRAG fill:#dcfce7,stroke:#16a34a
style STORE fill:#dbeafe,stroke:#3b82f6
style RESPONSE_MISS fill:#fff7ed,stroke:#ea580c
style RESPONSE_HIT fill:#dcfce7,stroke:#16a34a
style note1 fill:#f8f8f8,stroke:#ccc,color:#555 First request (cold) follows the MISS path — WordPress executes normally, results are stored. Subsequent matching requests follow the HIT path after warmup, bypassing the database.
A request is eligible for caching when all of the following are true:
- Request method is
GETorHEAD - Front-end (non-admin) request
- Targets the main WordPress query — secondary queries (widget loops, related posts, etc.) are not intercepted
- Not a search or feed request
- User is not logged in, or logged-in caching is explicitly enabled for this role (Pro only)
- URL does not include
?qc_nocache=1(developer debug bypass) - No bypass rule applies (WooCommerce endpoints, AJAX, session cookies — Pro only)
Query Caching and Fragment Caching
QuantumCache maintains two internal cache layers, both backed by the same store (Redis or MySQL fallback), operating at different points in the request lifecycle.
%% DIAG-003 — Query Cache vs Fragment Cache: Internal Relationship
%% Source: qc_source_of_truth.md §6 (Terminology: Query cache, Fragment cache), §1.9 (counter data)
%% Fragment hits consistently exceed query hits in count across all tested segments and configs.
%% Source files do not define the specific fragment boundaries.
flowchart LR
PHP["PHP execution process"]
subgraph QC_LAYERS["QuantumCache — Two Internal Cache Layers"]
direction TB
QCACHE["Query Cache\n─────────────────────────────────────\nStores results of database queries.\nHit = DB call skipped.\nMeasured: query_hits / query_misses"]
FCACHE["Fragment Cache\n─────────────────────────────────────\nStores rendered HTML or data fragments.\nHit = rendering skipped.\nMeasured: frag_hits / frag_misses\n\nNote: fragment boundaries are not defined\nin source files"]
end
DB["Database"]
RENDER["Rendering\n(fragment assembly)"]
PHP -->|"check"| QCACHE
QCACHE -->|"miss → query"| DB
DB -->|"result"| QCACHE
PHP -->|"check"| FCACHE
FCACHE -->|"miss → render"| RENDER
RENDER -->|"fragment stored"| FCACHE
note1["Fragment hits are consistently higher in count than query hits\nacross all tested segments and configs (benchmark-derived, §1.9 — see TABLE-004)"]
note2["Neither layer stores complete HTTP responses.\nQuantumCache is not a full-page cache."]
style PHP fill:#f5f5f5,stroke:#aaa
style QC_LAYERS fill:#f0fdf4,stroke:#16a34a
style QCACHE fill:#dcfce7,stroke:#16a34a
style FCACHE fill:#dcfce7,stroke:#16a34a
style DB fill:#f5f5f5,stroke:#aaa
style RENDER fill:#f5f5f5,stroke:#aaa
style note1 fill:#f8f8f8,stroke:#ccc,color:#555
style note2 fill:#fffbeb,stroke:#d97706,color:#92400e Query caching operates early in the request (before the database query runs). Fragment caching operates later (during template output). Both can deliver cached results on the same warm request. See Benchmarks for counter data.
Query caching
Hooks into WordPress via posts_pre_query (read path) and the_posts (store path).
On a cache hit, posts_pre_query returns stored post IDs before WordPress executes
the database query. The IDs are hydrated using WordPress's in-memory object cache
(_prime_post_caches + get_post()), so no database call occurs for the main query.
On a miss, WordPress executes normally. After results return, the_posts stores the
post IDs as a JSON payload, tagged with post type, individual post IDs, and associated taxonomy terms.
Cache keys are built from a fingerprint of the WP_Query vars, site locale, and a role bucket
(anon, or a sorted role list when Pro's logged-in caching is enabled). Different locales
and different user roles resolve to separate cache keys.
Fragment caching
Stores rendered HTML captured during template execution. Rather than caching entire page output, it caches specific output units — a fragment is anything from a navigation block to a product grid.
Free registers fragment caching automatically (AutoFragments) for:
the_contentandcore/post-contentblock — post body on singular pagescore/queryblock — query loop output on block themesthe_excerpt— excerpt output in archive loopscore/navigationblock — navigation menuscore/latest-postsandcore/archivesblocks- Classic sidebar widget areas
Pro additionally wraps WooCommerce-specific output on shop and category archive pages:
- Breadcrumb, result count, catalog ordering dropdown
- Full product loop and inner product grid
Fragments containing nonces or JWT-like tokens are never cached, regardless of configuration.
This is a hard constraint in FragmentCache::render() and applies to both Free and Pro.
How the two layers interact
Query caching reduces database calls early in the request (before the main query runs). Fragment caching reduces rendering cost later (during template output). On a fully warm request, both layers can deliver cached results: the main query returns post IDs without a database call, and expensive rendered blocks are served from the fragment cache without re-executing their rendering logic.
Cache Stores: Redis and MySQL Fallback
QuantumCache uses Redis as its primary cache store. When Redis is unavailable, it falls back to a MySQL-backed cache table.
Redis (primary)
Keeps cached entries in memory. Cache reads and writes are fast and add negligible overhead to the request. Redis is the recommended configuration. See benchmark results →
MySQL fallback
Uses a dedicated cache table on the same MySQL server. Each cache lookup involves a database query, which partially offsets the benefit of query caching. MySQL fallback still provides measurable benefit — particularly for fragment caching — but delivers smaller gains than Redis. No MySQL fallback data is available for WooCommerce routes. See benchmark results →
How Pro Changes Behavior for WooCommerce
Pro extends the same query and fragment cache engine as Free. When WooCommerce is present,
Pro's WooModule registers additional behavior for WooCommerce routes.
%% DIAG-004 — Pro WooCommerce Bypass and TTL Decision Flow
%% Source: qc_source_of_truth.md §2 (Pro capabilities), assertions P3, P4, P6
%% P3: X-QC-Pro-Force-TTL:90 on /shop/ MISS
%% P4: /cart/ → X-QC-Pro-Obs-Bypass:1 reason:woo_endpoint (br-001)
%% P6: enable_logged_in_cache=0 → logged-in user excluded before cache/bypass path
%% DIAGRAM-LEVEL LABEL: Documented behavior only — not exhaustive.
flowchart TD
BANNER["⚠ Documented behavior only — not exhaustive.\nReflects confirmed assertions P3, P4, P6.\nSource files do not enumerate all bypass rules\nor all logged-in configurations.\nThis flow applies to Pro only.\nFree does not implement any nodes shown in this diagram."]
REQ["Incoming request (Pro active)"]
LOGGEDIN{"User logged in?\n(Pro: enable_logged_in_cache=0)"}
EXCLUDED["Excluded before cache/bypass path\n→ Uncached PHP response\n─────────────────────────────────\nenable_logged_in_cache=0 (confirmed, assertion P6)\nBehavior with =1 not documented"]
ENDPOINT{"WooCommerce\nendpoint bypass check\n(br-001)"}
BYPASSED["Bypass: X-QC-Pro-Obs-Bypass:1\nreason:woo_endpoint\n→ Uncached PHP response\n─────────────────────────────\nbr-001: /cart/ only.\nSource files document\nno other bypass rules."]
CACHE{"Cache check\nMISS or HIT?"}
MISS_PHP["PHP executes\n→ Apply Woo TTL override if applicable\nX-QC-Pro-Force-TTL:90 confirmed for\n/shop/ MISS (assertion P3)\nTTL for other routes not documented\nin source files"]
STORE["Populate cache store\n(Redis / MySQL fallback)"]
HIT["Return cached result\nX-QC-Main: HIT"]
MISS_RESP["Return response\nX-QC-Main: MISS"]
BANNER ~~~ REQ
REQ --> LOGGEDIN
LOGGEDIN -->|"Yes"| EXCLUDED
LOGGEDIN -->|"No (anonymous)"| ENDPOINT
ENDPOINT -->|"Yes (WooCommerce endpoint)"| BYPASSED
ENDPOINT -->|"No"| CACHE
CACHE -->|"MISS"| MISS_PHP
CACHE -->|"HIT"| HIT
MISS_PHP --> STORE
STORE --> MISS_RESP
style BANNER fill:#fffbeb,stroke:#d97706,color:#92400e
style REQ fill:#f5f5f5,stroke:#aaa
style LOGGEDIN fill:#fef9c3,stroke:#ca8a04
style EXCLUDED fill:#fce7f3,stroke:#db2777
style ENDPOINT fill:#fef9c3,stroke:#ca8a04
style BYPASSED fill:#fce7f3,stroke:#db2777
style CACHE fill:#fef9c3,stroke:#ca8a04
style MISS_PHP fill:#fee2e2,stroke:#dc2626
style STORE fill:#dbeafe,stroke:#3b82f6
style HIT fill:#dcfce7,stroke:#16a34a
style MISS_RESP fill:#fff7ed,stroke:#ea580c Free does not implement any of these nodes — no TTL overrides, no bypass rules, no Woo-specific fragments. On Free, WooCommerce routes are handled the same as standard pages.
WooCommerce TTL overrides
For anonymous requests to WooCommerce archive routes (/shop/, /product-category/*,
/product-tag/*), Pro overrides the standard query TTL with a WooCommerce-specific value.
This prevents product archive pages from remaining cached for the default duration, which may be
too long for a shop with frequent product changes.
The override is applied via the quantumcache_query_ttl filter in WooModule::register(),
and is visible as an X-QC-Pro-Force-TTL response header on MISS responses
(when debug headers are enabled).
WooCommerce endpoint bypass
Pro's BypassRules registers a filter on quantumcache_should_bypass_cache.
Requests matching any of the following conditions bypass the cache entirely —
they are neither served from cache nor stored to cache:
| Rule | Condition |
|---|---|
| br-001 | Request path is /cart/, /checkout/, or /my-account/ |
| br-002 | Request includes a wc-ajax parameter |
| br-003 | Request method is not GET or HEAD |
| br-004 | Request carries a wp_woocommerce_session_* cookie |
| br-005 | Request carries a woocommerce_cart_hash cookie |
| br-006 | Request carries a woocommerce_items_in_cart cookie |
Rules br-004 through br-006 are not applied to users approved for role-scoped caching
(Pro, enable_logged_in_cache active for their role). The session-cookie bypass
exists to protect anonymous users from seeing stale cart data — not to block users that
Pro has already cleared for caching.
WooCommerce-specific fragments
WooModule wraps WooCommerce rendering hooks with fragment caching on shop and category
archive pages: breadcrumb, result count, catalog ordering dropdown, and the product grid
(outer and inner captures). All WooCommerce fragments are tagged post_type:product
and purged when products change.
Free does not wrap WooCommerce rendering hooks. On Free, WooCommerce archive pages use the Auto Fragments registered for general WordPress output.
Product Invalidation (Pro)
%% DIAG-005 — Pro Product Invalidation Flow
%% Source: qc_source_of_truth.md §2 (Pro: product invalidation), §6 (Terminology: Invalidation), assertion P5
%% P5: product update → InvalidationMap purges post_type:product → next request is X-QC-Main:MISS
%% This behavior is Pro only. Free does not implement WooCommerce invalidation.
flowchart TD
UPDATE["Product update event\n(WordPress admin or API)"]
IMAP["InvalidationMap\n─────────────────────────────────────\nMaps post_type:product\nto relevant cache entries\n\nSource files do not enumerate\nother mapped types"]
PURGE["Cache purge\n─────────────────────────────────────\nAffected entries removed from\nRedis / MySQL fallback\n\npurge_calls and purge_tags counters\ntrack invalidation events.\nDuring warm read pass (no writes)\nthese counters are 0."]
NEXT["Next request for affected route\n→ X-QC-Main: MISS"]
PHP["PHP executes\n→ Re-queries database\n→ Re-renders fragments"]
REPOP["Cache repopulated\n(Redis / MySQL fallback)"]
RESPONSE["Response served\n(fresh data)"]
NOTE["This behavior is Pro only.\nFree does not implement\nWooCommerce invalidation."]
UPDATE --> IMAP
IMAP --> PURGE
PURGE --> NEXT
NEXT --> PHP
PHP --> REPOP
REPOP --> RESPONSE
NOTE ~~~ UPDATE
style UPDATE fill:#f5f5f5,stroke:#aaa
style IMAP fill:#fef9c3,stroke:#ca8a04
style PURGE fill:#fee2e2,stroke:#dc2626
style NEXT fill:#fff7ed,stroke:#ea580c
style PHP fill:#f5f5f5,stroke:#aaa
style REPOP fill:#dbeafe,stroke:#3b82f6
style RESPONSE fill:#dcfce7,stroke:#16a34a
style NOTE fill:#fffbeb,stroke:#d97706,color:#92400e
Pro's InvalidationMap hooks into WooCommerce events to purge cache entries when data changes.
Free uses base QueryCache invalidation (post save, delete, term changes) but does not register WooCommerce-specific hooks.
Pro's InvalidationMap purges cache entries using tag-based invalidation via purgeTags()
on the store. Purge calls are batched at shutdown to prevent multiple sequential purge requests when
cascading WooCommerce hooks fire within a single request.
| Event | Tags purged |
|---|---|
| Product create, update, or delete | post:ID, post_type:product, associated term:ID tags, price_list |
| Stock level changes | Same as product update |
| Low stock / out of stock | Same as product update |
| Order completion | post:ID for each product in the order |
| Term create, edit, or delete | taxonomy:X, term:ID |
| Product review posted | post:ID, post_type:product |
| WooCommerce store options changed (currency, tax display, stock visibility, customer address) | post_type:product, price_list, option:X |
How Free and Pro Handle Logged-In Users
%% DIAG-006 — Pro Logged-In User Handling Flow
%% Source: qc_source_of_truth.md §2 (Pro: logged-in behavior), §6 (Terminology: Logged-in behavior), assertion P6
%% DIAGRAM-LEVEL LABEL: Documented behavior only — not exhaustive.
%% Reflects confirmed assertion P6 (enable_logged_in_cache=0 only).
%% Other configurations are not documented in source files.
flowchart TD
BANNER["⚠ Documented behavior only — not exhaustive.\nReflects confirmed assertion P6 (enable_logged_in_cache=0 only).\nOther configurations are not documented in source files.\nFree: no logged-in handling is documented in source files."]
REQ["Incoming request (Pro active)"]
AUTH{"User authentication check\nIs the user logged in?"}
EXCLUDED["Excluded before cache\nand bypass evaluation\n─────────────────────────────────────────\nLogged-in users receive\nuncached PHP responses.\nNo cache read. No cache write.\n─────────────────────────────────────────\nConfirmed: assertion P6\nSource files do not describe\nper-role differentiation.\nBehavior when enable_logged_in_cache=1\nis not documented in source files."]
ANON["Anonymous (logged-out) request\n→ Normal cache/bypass flow\n(see DIAG-004)"]
BANNER ~~~ REQ
REQ --> AUTH
AUTH -->|"Yes — logged in\n(enable_logged_in_cache=0)"| EXCLUDED
AUTH -->|"No — anonymous"| ANON
style BANNER fill:#fffbeb,stroke:#d97706,color:#92400e
style REQ fill:#f5f5f5,stroke:#aaa
style AUTH fill:#fef9c3,stroke:#ca8a04
style EXCLUDED fill:#fce7f3,stroke:#db2777
style ANON fill:#dcfce7,stroke:#16a34a
Free skips all cache operations for logged-in users by default.
Pro optionally enables caching for specific roles via LoggedInModule.
Sensitive paths are always excluded regardless of configuration.
Free — no logged-in caching
Free never caches logged-in users. The QUANTUMCACHE_CACHE_LOGGED_IN constant
defaults to false. Both QueryCache and AutoFragments
check is_user_logged_in() early and skip all cache operations when a logged-in
user is detected. Logged-in users receive full PHP responses with no query or fragment caching applied.
Pro — optional role-scoped caching
Pro provides optional role-scoped caching via LoggedInModule. When
enable_logged_in_cache is enabled in Pro's options and the user's role matches the
configured logged_in_roles list, QuantumCache applies the same query and fragment
caching it uses for anonymous traffic. This is opt-in and disabled by default.
When logged-in caching is active for a user:
- Cache keys include a role bucket — different roles receive separate cache entries and do not share content
- Sensitive paths (
/cart/,/checkout/,/my-account/,/account/) are always excluded regardless of configuration - WooCommerce session-cookie bypass rules (br-004 through br-006) are not applied to users approved by
LoggedInModule
The enable_logged_in_cache option and LoggedInModule are not available in Free.
Logged-in caching requires Pro.
wp_options and Cold Path
wp_options — zero modification
QuantumCache does not write to or modify the wp_options table during operation.
Confirmed via zero-delta measurement across all tested configs:
Δ transients=+0, Δ site_transients=+0, Δ nonexpired=+0
Δ autoload_bytes=+0, Δ options_bytes=+0 Cold path behavior
Warm steady-state results (post warmup) do not describe the first request after a cache flush. Cold TTFB behavior is mixed — some URLs show reductions on the first request; some show overhead vs the no-cache baseline. The source files do not explain the cold-path variance.
See TABLE-002 (standard pages) and TABLE-003 (WooCommerce) in Benchmarks for per-URL cold data.
See the measured results
Benchmark data, methodology, and cold-path tables.