Object cache misses are invisible without instrumentation

A persistent object cache either works or silently does not, and both look identical from the front end: the site is up, the pages render, and the queries are or are not happening.

add_action( 'shutdown', function () {
    global $wp_object_cache;

    if ( ! defined( 'SHOP_CACHE_DEBUG' ) ) {
        return;
    }

    error_log( sprintf(
        'cache hits=%d misses=%d ratio=%.1f%%',
        $wp_object_cache->cache_hits,
        $wp_object_cache->cache_misses,
        100 * $wp_object_cache->cache_hits /
            max( 1, $wp_object_cache->cache_hits + $wp_object_cache->cache_misses )
    ) );
} );

A drop-in that failed to connect falls back to the in-memory cache without complaint, so the ratio looks plausible per request and nothing persists between them. The number worth watching is not the ratio but whether it is the same on every request — a persistent cache warms up, and one that starts cold every time is not persistent.