Salta al contenuto principale
Sistemi Attivi
WP Planet — WordPress Cloud & Managed Services
Torna al MagazinePerformance

Redis object cache WordPress: quando il database diventa il collo di bottiglia (e come risolverlo)

23 Ott 2026 — 09:30 9 min di lettura
Redis object cache WordPress: quando il database diventa il collo di bottiglia (e come risolverlo)

La page cache copre il 90% dei casi, ma sulle pagine dinamiche — checkout, account, query complesse — è l'object cache Redis che fa la differenza. Quando serve davvero, come configurarla senza peggiorare le prestazioni, e perché un'object cache mal configurata è peggio di nessuna cache.

La page cache risolve la maggior parte dei problemi di velocità di un sito WordPress — su questo non ci piove. Ma c'è un limite che chi gestisce e-commerce o siti ad alto traffico conosce bene: le pagine dinamiche non si possono cachare. Il checkout di WooCommerce, l'area account, le pagine con prezzi personalizzati per ruolo utente, i risultati di ricerca filtrati. Su tutte queste pagine la page cache non può intervenire, e ogni richiesta arriva al database. È lì che l'object cache entra in gioco.

Lo vediamo regolarmente nei report: un WooCommerce con 3.000 prodotti, page cache attiva, TTFB sotto 200ms sulle pagine statiche — e poi 1.800ms sul checkout. Il collo di bottiglia non è il server, non è PHP, non è la page cache. È il database che esegue le stesse query identiche per ogni visitatore, perché la page cache non può servire una pagina personalizzata. L'object cache Redis intercetta quelle query e serve il risultato dalla memoria invece di rifare la stessa domanda a MySQL.

Page cache vs object cache: due livelli, due lavori diversi

La page cache salva l'HTML completo di una pagina. Quando un visitatore richiede /chi-siamo/, il server serve l'HTML già renderizzato senza far girare PHP né interrogare il database. È il livello che dà il salto di velocità più visibile. Ma su una pagina dinamica — dove il contenuto cambia per ogni utente — la page cache non può intervenire. PHP gira, e ogni giro fa le sue query al database.

L'object cache lavora a un livello più basso: invece di cachare l'HTML della pagina intera, cachare i singoli risultati delle query al database. Le opzioni di WordPress (la tabella wp_options), i post meta, i termini, i risultati di WP_Query. Quando PHP ha bisogno di un dato, prima chiede a Redis; solo se Redis non ce l'ha, chiede a MySQL. Su una pagina dinamica con 40 query, Redis può servirne 35 dalla memoria e lasciare a MySQL solo le 5 che cambiano davvero per utente.

La differenza si misura. Su un WooCommerce con Redis configurato bene, il TTFB del checkout scende da 1.800ms a 300-400ms — non perché il server sia più veloce, ma perché 35 query su 40 non arrivano più al database.

Quando Redis serve davvero (e quando è sprecato)

Non tutti i siti hanno bisogno di Redis. Un blog con 500 visite al giorno e pagine quasi tutte statiche non vede alcun beneficio misurabile: la page cache copre già tutto, e il database non è sotto pressione. Aggiungere Redis lì è sovrainvestimento — costa risorse, aggiunge complessità, e un punto di failure in più (se Redis cade, le pagine dinamiche rallentano).

Redis serve quando il database è il collo di bottiglia. I casi tipici: WooCommerce con migliaia di prodotti e traffico reale, siti editoriali con query complesse (filtri, ricerche, relazioni), community con area utente attiva, qualsiasi sito dove le pagine dinamiche ricevono traffico significativo. Il segnale più chiaro è il TTFB: se le pagine statiche volano ma le dinamiche sono lente, il database è il problema e Redis è la risposta.

Configurare Redis correttamente (non solo attivarlo)

Il errore più comune è attivare Redis e basta. Un plugin di object cache mal configurato può serializzare oggetti grandi, cachare dati che cambiano spesso senza invalidarli, o peggiorare le prestazioni con overhead di serializzazione. La configurazione corretta parte da wp-config.php:

wp-config.php
// wp-config.php — configurazione Redis object cache
define( 'WP_REDIS_HOST', '127.0.0.1' );
define( 'WP_REDIS_PORT', 6379 );
define( 'WP_REDIS_DATABASE', 0 );

// TTL predefinito: 1 ora. Troppo corto = cache inutile,
// troppo lungo = dati stale. 3600s è un buon compromesso.
define( 'WP_REDIS_MAXTTL', 3600 );

// Prefisso per evitare collisioni tra siti sullo stesso Redis
define( 'WP_REDIS_PREFIX', 'wp_' . $_ENV['SITE_ID'] ?? 'default' );

// Disabilita i banner di debug in produzione
define( 'WP_REDIS_DISABLE_BANNERS', true );
Nota: Redis deve essere installato e attivo sul server. Su hosting condiviso non è sempre disponibile — in quel caso la page cache + CDN coprono la maggior parte dei casi. Su cloud hosting gestito WP Planet, Redis è incluso nei piani Business e Enterprise.

Il TTL è il parametro più critico. Un TTL troppo corto (60 secondi) rende la cache quasi inutile — i dati scadono prima di essere riusati. Un TTL troppo lungo (24 ore) serve dati stale — un prezzo cambiato nel database non si riflette nel frontend per ore. 3.600 secondi (1 ora) è un buon compromesso per la maggior parte dei siti. Per WooCommerce, dove i prezzi e gli stock cambiano più spesso, conviene un TTL più corto sulle chiavi dei prodotti (600-900 secondi) e invalidazione manuale al salvataggio.

L'invalidazione: il punto dove la cache si rompe

Il problema più insidioso dell'object cache non è configurarla, è invalidarla. Quando un prodotto cambia prezzo, le vecchie versioni cachate devono essere eliminate — altrimenti il frontend mostra il prezzo sbagliato. WordPress invalida automaticamente le cache dei post correlati al salvataggio, ma i plugin personalizzati o i dati custom spesso no.

La regola operativa: ogni volta che modifichi un dato che l'object cache potrebbe servire, invalida la chiave corrispondente. Su WooCommerce questo è gestito dal core; su sviluppi custom, devi farlo manualmente:

wp-config.php
// Invalida una chiave specifica di object cache dopo un update
function invalidate_custom_cache( $post_id ) {
    // Elimina la chiave cachata per questo post
    wp_cache_delete( 'custom_data_' . $post_id, 'my_plugin_group' );

    // Oppure elimina un gruppo intero se i dati sono correlati
    wp_cache_delete( 'related_products_' . $post_id, 'woocommerce' );
}
add_action( 'save_post_product', 'invalidate_custom_cache', 10, 1 );
Nota: L'invalidazione manuale è il punto dove l'object cache passa da utile a essenziale. Senza invalidazione corretta, i dati stale sono garantiti — e su un e-commerce, un prezzo sbagliato in cache è un problema commerciale, non solo tecnico.

Il monitoraggio: come capire se Redis sta lavorando

Un Redis attivo ma inutile è peggio di un Redis spento — perché ti fa credere di essere coperto quando non lo sei. Il primo controllo è il hit rate: quante volte Redis serve il dato dalla memoria rispetto a quante lo richiede a MySQL. Un hit rate sotto il 50% significa che la cache non sta lavorando — o perché i TTL sono troppo corti, o perché le chiavi non sono ben strutturate, o perché il traffico non è abbastanza alto da riempire la cache prima che scada.

Puoi controllare il hit rate direttamente dal server con redis-cli:

Terminale
# Connetti a Redis e controlla le statistiche
redis-cli -h 127.0.0.1 -p 6379

# Statistiche generali
INFO stats

# Cerca la riga 'keyspace_hits' e 'keyspace_misses'
# Hit rate = keyspace_hits / (keyspace_hits + keyspace_misses)
# Un buon hit rate è sopra l'80%. Sotto il 50%, rivedi la configurazione.

# Controlla quante chiavi sono in memoria
DBSIZE

# Controlla la memoria usata
INFO memory
Nota: Un hit rate alto (>80%) con poche chiavi in memoria significa che la cache lavora bene. Un hit rate basso con molte chiavi significa che i dati scadono prima di essere riusati — riduci il numero di chiavi cachate o allunga il TTL.

Redis non è una soluzione universale, ma quando il database è il collo di bottiglia è la leva più potente. La differenza tra un WooCommerce con e senza object cache, sulle pagine dinamiche, può essere di un fattore 4-5x sul TTFB. Non è un'ottimizzazione fine a se stessa: è ciò che separa un e-commerce che regge i picchi da uno che crolla proprio quando potrebbe vendere di più.

Audit Core Web Vitals

Misura LCP, INP e CLS sui tuoi utenti reali, non su un test di laboratorio.

Un audit Core Web Vitals identifica esattamente cosa rallenta il tuo sito e dove intervenire con priorità.

Audit Core Web Vitals
Condividi