Technical overview

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 — where QuantumCache operates
%% 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
%% 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 GET or HEAD
  • 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 and fragment cache — two layers in the same request
%% 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_content and core/post-content block — post body on singular pages
  • core/query block — query loop output on block themes
  • the_excerpt — excerpt output in archive loops
  • core/navigation block — navigation menus
  • core/latest-posts and core/archives blocks
  • 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 request handling flow
%% 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:

RuleCondition
br-001Request path is /cart/, /checkout/, or /my-account/
br-002Request includes a wc-ajax parameter
br-003Request method is not GET or HEAD
br-004Request carries a wp_woocommerce_session_* cookie
br-005Request carries a woocommerce_cart_hash cookie
br-006Request 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 update invalidation flow
%% 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.

EventTags 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
Free vs Pro — logged-in user handling
%% 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.