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

Transient API e database WordPress: quando la cache applicativa diventa un problema

02 Nov 2026 — 15:20 8 min di lettura
Transient API e database WordPress: quando la cache applicativa diventa un problema

I transient di WordPress sono una cache applicativa comoda, ma quando finiscono nel database invece che in Redis diventano un problema. Tabelle wp_options gonfie di transient scaduti, query che rallentano, e perché l'autoload è il killer silenzioso delle performance.

I transient sono una delle API più usate e meno capite di WordPress. Il concetto è semplice: set_transient chiave valore scadenza, get_transient chiave — una cache applicativa con TTL. Peccato che quando Redis non è configurato, WordPress li salva nella tabella wp_options. E lì restano, anche dopo la scadenza, perché WordPress non li cancella attivamente — li ignora solo quando li legge. Su un sito attivo con plugin che ne usano decine, la tabella wp_options si riempie di transient scaduti che nessuno pulisce.

Il problema non è lo spazio su disco — i transient sono piccoli. Il problema è l'autoload. Quando un transient viene salvato con autoload=yes (che è il default), WordPress lo carica in memoria a ogni singola richiesta, anche se è scaduto da mesi. Una tabella wp_options con 500 transient scaduti in autoload può aggiungere 200-300KB a ogni page load, prima ancora che la pagina inizi a renderizzare. È un rallentamento invisibile che nessuno attribuisce alla cache.

Individuare i transient scaduti nella tabella wp_options

Prima di pulire, misura. Una query SQL ti dice quanti transient ci sono, quanti sono scaduti, e quanto pesano:

SQL
-- Conta i transient e il loro peso totale
SELECT 
    COUNT(*) AS totale_transient,
    SUM(LENGTH(option_value)) AS peso_byte
FROM wp_options
WHERE option_name LIKE '_transient_%' OR option_name LIKE '_site_transient_%';

-- Lista i transient scaduti (con autoload=yes, i più pericolosi)
SELECT 
    option_name,
    LENGTH(option_value) AS peso_byte,
    autoload
FROM wp_options
WHERE (
    option_name LIKE '_transient_timeout_%' 
    OR option_name LIKE '_site_transient_timeout_%'
)
AND option_value < UNIX_TIMESTAMP()
AND autoload = 'yes'
ORDER BY LENGTH(option_value) DESC
LIMIT 30;
Nota: I transient hanno due righe: una per il valore (_transient_nome) e una per la scadenza (_transient_timeout_nome). La scadenza è un timestamp Unix. Se è minore di UNIX_TIMESTAMP(), il transient è scaduto ma ancora presente nella tabella.

Pulire i transient scaduti (con cautela)

La pulizia va fatta con un backup recente e mai durante i picchi di traffico. Il modo più sicuro è usare WP-CLI, che gestisce correttamente i transient di sito e di rete:

Terminale
# Elimina tutti i transient scaduti (sicuro, non tocca quelli attivi)
wp transient delete --expired

# Elimina TUTTI i transient (anche quelli non scaduti — più aggressivo)
# Usalo solo se sai cosa stai facendo
wp transient delete --all

# Per installazioni multisite, ripeti per ogni sito
wp site list --field=url | xargs -I{} wp transient delete --expired --url={}

# Verifica il peso della tabella wp_options dopo la pulizia
wp db query "SELECT COUNT(*) FROM wp_options WHERE option_name LIKE '_transient_%';"
Nota: wp transient delete --expired è sicuro: rimuove solo i transient la cui scadenza è passata. I transient attivi (non scaduti) non vengono toccati. Esegui la pulizia durante una finestra a basso traffico, e verifica il sito subito dopo.

Perché i transient finiscono nel database (e come evitarlo)

WordPress salva i transient in wp_options solo quando non c'è un object cache esterno (Redis o Memcached). Se Redis è configurato correttamente, set_transient scrive direttamente in Redis — che gestisce la scadenza automaticamente e non lascia rifiuti nella tabella. La differenza è drastica: con Redis, i transient scaduti spariscono da soli; senza Redis, si accumulano per sempre.

Per verificare se Redis sta gestendo i transient, controlla che l'object cache sia attiva:

wp-config.php
// Verifica se l'object cache esterna è attiva
if ( wp_using_ext_object_cache() ) {
    error_log( 'Object cache esterna ATTIVA (Redis/Memcached)' );
} else {
    error_log( 'Object cache esterna NON attiva — transient nel database' );
}

// Forza un transient di test e verifica dove finisce
$test_key = 'wpplanet_cache_test_' . time();
set_transient( $test_key, 'test', 60 );

// Se wp_using_ext_object_cache() è false, il transient è in wp_options
// e rimarrà lì anche dopo la scadenza.
Nota: wp_using_ext_object_cache() restituisce true solo se il file wp-content/object-cache.php esiste e un object cache esterno è configurato. Se hai installato il plugin Redis Object Cache ma non è attivato, i transient finiscono comunque nel database. Verifica dal pannello del plugin che la connessione a Redis sia attiva.

Il cron di pulizia automatico

Se non puoi usare Redis (o non vuoi), l'alternativa è un cron di sistema che pulisce i transient scaduti periodicamente. Non usare wp-cron per questo — è inaffidabile sui siti a basso traffico. Usa un cron di sistema:

Terminale
# Cron di sistema: pulisce i transient scaduti ogni domenica alle 4
# Aggiungi a /etc/crontab o crontab -e
0 4 * * 0 www-data wp transient delete --expired --path=/var/www/html --allow-root

# Oppure, se non hai WP-CLI, uno script PHP standalone:
# /var/scripts/clean-transients.php
<?php
require_once '/var/www/html/wp-load.php';
global $wpdb;
$wpdb->query(
    "DELETE FROM {$wpdb->options} 
     WHERE option_name LIKE '_transient_timeout_%' 
     AND option_value < UNIX_TIMESTAMP()"
);
$wpdb->query(
    "DELETE FROM {$wpdb->options} 
     WHERE option_name LIKE '_site_transient_timeout_%' 
     AND option_value < UNIX_TIMESTAMP()"
);
Nota: Lo script PHP elimina prima i record di scadenza (_transient_timeout_*) e poi, in una seconda query, i valori orfani. Esegui con l'utente del web server (www-data) per evitare problemi di permessi sui file di cache.

I transient sono uno strumento utile, ma come ogni cache hanno un costo. Se finiscono nel database, quel costo si manifesta come rallentamento silenzioso. La regola operativa è semplice: se usi transient, usa Redis. Se non puoi usare Redis, pulisci periodicamente. E se un plugin ne crea centinaia senza scadenza, valuta se quel plugin sta facendo qualcosa che non dovrebbe.

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