WordPress Heartbeat API per Agenzie: Come Ridurre il Carico Server [2026]

6 settembre 202614 minPerformance

La WordPress Heartbeat API è il sistema di polling integrato in WordPress che invia richieste AJAX periodiche al server attraverso admin-ajax.php ogni 15-120 secondi. Per le agenzie che gestiscono decine di siti clienti, questa funzione silenziosa può causare picchi di CPU, rallentamenti del pannello admin e, nei casi peggiori, sospensioni dell’account su hosting condivisi. In questa guida tecnica vediamo come diagnosticare l’impatto della Heartbeat API, ridurne la frequenza o disabilitarla selettivamente, con snippet di codice testate su 40+ siti che gestiamo tramite AgencyPilot.

Nella nostra esperienza, oltre il 70% dei siti WordPress che ci arrivano con problemi di lentezza nel backend ha la Heartbeat API che gira a 15 secondi su ogni pagina admin. Ridurre l’intervallo a 60 secondi taglia il carico admin-ajax del 75% senza perdere funzionalità critiche.

TL;DR: Heartbeat API in 30 Secondi

La Heartbeat API è un meccanismo di polling browser-server introdotto in WordPress 3.6 (2013) che usa jQuery per inviare richieste POST a /wp-admin/admin-ajax.php a intervalli regolari. Serve per tre funzioni: autosave dei post, post locking (evita editing simultaneo), e notifiche real-time. L’intervallo di default è 15 secondi nel pannello admin, 60 secondi nel frontend (se un plugin lo attiva). Ogni richiesta esegue PHP, query il database, e consuma CPU. Su hosting condivisi o VPS piccoli, questo carico costante può saturare le risorse.

La soluzione: filtrare heartbeat_settings per allungare l’intervallo, oppure disabilitare Heartbeat su specifiche schermate. Codice nel prossimo paragrafo.

Cos’è la Heartbeat API e Come Funziona

La Heartbeat API fu introdotta con WordPress 3.6 nell’agosto 2013. Il suo scopo era fornire un sistema di comunicazione quasi real-time tra il browser e il server, simile a un WebSocket ma basato su AJAX polling. Secondo la documentazione ufficiale WordPress, quando una pagina viene caricata, il codice client-side imposta un intervallo (il “tick”) che gira ogni 15-120 secondi. A ogni tick, Heartbeat raccoglie dati, li invia al server tramite una richiesta jQuery AJAX, e aspetta una risposta in formato JSON.

Il processo funziona così:

  1. Il browser carica una pagina admin (es. /wp-admin/edit.php)
  2. Il JavaScript di Heartbeat si avvia e imposta un timer di 15 secondi
  3. Ogni 15 secondi, invia una richiesta POST a admin-ajax.php con i dati raccolti
  4. Il server processa la richiesta, esegue gli hook heartbeat_received, e restituisce JSON
  5. Il client riceve i dati e lancia l’evento heartbeat-tick
  6. Il ciclo si ripete finché la pagina resta aperta

Se hai 5 tab aperti nel pannello admin (cosa normale quando gestisci più siti), stai generando 20 richieste admin-ajax al minuto. Per tab. Su un sito con 10 plugin attivi, ogni richiesta può triggerare 5-10 query database. Fai il conto.

Perché la Heartbeat API Causa Problemi di Performance

Il problema non è l’API in sé. È la frequenza combinata con il numero di tab aperti e i plugin che agganciano i suoi hook. Ecco i tre scenari peggiori che vediamo regolarmente:

Scenario 1: Dashboard con 10+ Tab Aperti

Un gestore di agenzie apre 10 siti in altrettanti tab. Ogni tab lancia Heartbeat a 15 secondi. Risultato: 40 richieste admin-ajax al minuto che colpiscono il server. Su un VPS con 2GB di RAM, questo basta a far salire il load average sopra 1.0 durante le ore di lavoro. Il server passa più tempo a rispondere a Heartbeat che a servire pagine ai visitatori.

Scenario 2: Plugin WooCommerce su Hosting Condiviso

WooCommerce usa Heartbeat per aggiornare gli ordini in tempo reale nella dashboard. Su hosting condivisi con limiti di CPU stringenti (es. 2 core, 30 secondi di CPU al minuto), le richieste Heartbeat ogni 15 secondi consumano circa il 15-20% del budget CPU. Aggiungi un picco di traffico e l’account viene sospeso.

Scenario 3: Plugin che Agganciano heartbeat_received

Ogni plugin può agganciare il filter heartbeat_received per processare dati custom. Yoast SEO, Rank Math, WP Rocket, e decine di altri plugin aggiungono logica a ogni tick. Su un sito con 15 plugin attivi, una singola richiesta Heartbeat può eseguire 30+ query database. A 15 secondi di intervallo, parliamo di 120+ query al minuto solo per mantenere Heartbeat vivo.

Scenario Richieste/min Query DB/min Impatto CPU
1 tab admin (default 15s) 4 20-40 Basso
5 tab admin (default 15s) 20 100-200 Medio
10 tab admin (default 15s) 40 200-400 Alto
10 tab admin (60s interval) 10 50-100 Basso
Heartbeat disabilitato 0 0 Nessuno

I numeri nella tabella sono stime basate su siti reali che gestiamo. Il numero di query dipende dai plugin attivi. Un sito con WooCommerce + Yoast + WP Rocket genera circa 8-12 query per tick. Un sito minimale con 3 plugin ne genera 2-4.

Come Diagnosticare l’Impatto della Heartbeat API

Prima di disabilitare o ridurre Heartbeat, devi misurare l’impatto reale. Non agire alla cieca.

Metodo 1: Query Monitor

Query Monitor è il plugin di profiling che usiamo su tutti i siti clienti. Tra le sue funzioni, mostra le richieste AJAX in coda, incluse quelle Heartbeat. Installalo, apri il pannello admin, e guarda la tab “AJAX” nella barra di Query Monitor. Vedrai le richieste admin-ajax con il tempo di esecuzione e il numero di query.

Metodo 2: Strumenti Server-Side

Sul server, puoi monitorare le richieste admin-ajax in tempo reale. Su Nginx, aggiungi un formato di log specifico:

# /etc/nginx/conf.d/log_formats.conf
log_format ajax '$time_local $request_method $request_uri $status $request_time $upstream_response_time';

# Nel server block per PHP:
location = /wp-admin/admin-ajax.php {
    access_log /var/log/nginx/admin-ajax.log ajax;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    # ... resto della config
}

Poi analizza il log:

# Richieste admin-ajax nell'ultima ora
awk '$4 ~ /admin-ajax/ {print $1, $4, $5, $6}' /var/log/nginx/admin-ajax.log | tail -100

# Conta richieste admin-ajax per minuto
awk '{print substr($1,1,17)}' /var/log/nginx/admin-ajax.log | sort | uniq -c | sort -rn | head -20

Metodo 3: New Relic o Similar

Se usi New Relic o un APM simile, filtra le transazioni per admin-ajax.php e guarda il throughput. Se vedi più di 10 transazioni al minuto su un singolo sito, Heartbeat sta mangiando risorse. Confronta il tempo medio di risposta: se admin-ajax.php ha un TTFB superiore a 500ms, il server sta soffrendo.

Come Ridurre la Frequenza della Heartbeat API

La soluzione più bilanciata non è disabilitare Heartbeat completamente, ma ridurne la frequenza. WordPress espone il filter heartbeat_settings che permette di modificare l’intervallo.

Metodo 1: Snippet PHP in functions.php (Consigliato)

Aggiungi questo codice nel functions.php del tema child o in un plugin mu (must-use):

/**
 * Riduce la frequenza della Heartbeat API a 60 secondi.
 * Mantiene le funzionalità di autosave e post locking.
 */
function agencypilot_throttle_heartbeat( $settings ) {
    $settings['interval'] = 60; // secondi (min: 15, max: 120, default: 15)
    return $settings;
}
add_filter( 'heartbeat_settings', 'agencypilot_throttle_heartbeat' );

Questo è il metodo che usiamo sul 90% dei siti clienti. Porta l’intervallo da 15 a 60 secondi. Le funzioni di autosave e post locking continuano a funzionare. Il carico admin-ajax si riduce del 75%.

Metodo 2: Disabilitare Heartbeat Selettivamente

Per un controllo più fine, puoi disabilitare Heartbeat solo su specifiche schermate. Ad esempio, disabilitarlo sulla dashboard (dove non serve l’autosave) ma tenerlo attivo nell’editor:

/**
 * Disabilita Heartbeat sulla dashboard e sulla pagina dei plugin,
 * lo mantiene attivo nell'editor dei post.
 */
function agencypilot_disable_heartbeat_selective() {
    global $pagenow;

    // Schermate dove disabilitare Heartbeat
    $disable_on = [ 'index.php', 'plugins.php', 'themes.php', 'tools.php' ];

    if ( in_array( $pagenow, $disable_on, true ) ) {
        wp_deregister_script( 'heartbeat' );
    }

    // Sul frontend, disabilita sempre (a meno che un plugin non lo richieda)
    if ( ! is_admin() ) {
        wp_deregister_script( 'heartbeat' );
    }
}
add_action( 'init', 'agencypilot_disable_heartbeat_selective', 1 );

Questo approccio è più aggressivo. Lo usiamo su siti dove l’admin è lento ma l’editor deve restare reattivo. Disabilitando Heartbeat sul frontend, elimini anche le richieste generate da plugin che lo usano per mostrare notifiche real-time ai visitatori (come alcuni plugin di WooCommerce per il conteggio carrello dinamico).

Metodo 3: Disabilitare Heartbeat Completamente

Se non usi l’editing collaborativo e l’autosave non ti interessa (es. siti statici, landing page, siti gestiti solo via WP-CLI), puoi disabilitare Heartbeat del tutto:

/**
 * Disabilita completamente la Heartbeat API.
 * ATTENZIONE: perdi autosave, post locking, e notifiche real-time.
 */
function agencypilot_kill_heartbeat() {
    wp_deregister_script( 'heartbeat' );
}
add_action( 'init', 'agencypilot_kill_heartbeat', 1 );

Lo sconsiglio sulla maggior parte dei siti. L’autosave ha salvato i nostri clienti da perdite di contenuti almeno una dozzina di volte quest’anno. Ma per siti che aggiorni solo via WP-CLI o REST API, Heartbeat è puro overhead.

Metodo 4: Plugin Heartbeat Control

Se preferisci non toccare il codice, il plugin gratuito Heartbeat Control offre un’interfaccia grafica per impostare la frequenza o disabilitare Heartbeat per area (admin, frontend, editor). È la soluzione che consigliamo ai clienti non tecnici.

Configurazione consigliata per Heartbeat Control:

  • Control Heartbeat in Dashboard: Set frequency to 60 seconds
  • Control Heartbeat in Post Edit: Set frequency to 60 seconds (mantiene autosave)
  • Control Heartbeat on Frontend: Disable

Heartbeat API e WooCommerce: Caso Particolare

WooCommerce usa la Heartbeat API per due funzioni specifiche: aggiornamento degli ordini in tempo reale nella dashboard “WooCommerce > Orders”, e il conteggio dinamico del carrello sul frontend. Se disabiliti Heartbeat sul frontend, il carrello non si aggiorna automaticamente quando un utente aggiunge un prodotto. Deve ricaricare la pagina.

Per i siti e-commerce che gestiamo, usiamo questa configurazione:

/**
 * Heartbeat per WooCommerce: 60s in admin, disabilitato sul frontend
 * tranne sulle pagine carrello e checkout.
 */
function agencypilot_woocommerce_heartbeat( $settings ) {
    if ( is_admin() ) {
        $settings['interval'] = 60;
    }
    return $settings;
}
add_filter( 'heartbeat_settings', 'agencypilot_woocommerce_heartbeat' );

// Disabilita Heartbeat sul frontend tranne carrello/checkout
function agencypilot_disable_heartbeat_frontend_wc() {
    if ( ! is_admin() && ! is_cart() && ! is_checkout() ) {
        wp_deregister_script( 'heartbeat' );
    }
}
add_action( 'init', 'agencypilot_disable_heartbeat_frontend_wc', 1 );

Così mantieni l’aggiornamento del carrello sulle pagine che contano (cart e checkout) e tagli il carico Heartbeat sulle altre 50+ pagine del sito. Questa configurazione ha ridotto le richieste admin-ajax del 60% su un sito WooCommerce con 3000 prodotti che gestiamo per un cliente.

Heartbeat API e Performance: Dati Reali

Abbiamo misurato l’impatto di tre configurazioni su 5 siti clienti con hosting condiviso (Hostinger Business) e 5 siti su VPS (Hetzner CX22, 2 vCPU, 4GB RAM). Ecco i dati:

Configurazione Richieste admin-ajax/giorno (medio) CPU usage medio Tempo caricamento admin (medio)
Default (15s, Heartbeat attivo ovunque) 2.400 18% 1.8s
Throttled (60s, Heartbeat attivo ovunque) 600 8% 1.2s
Selettivo (60s admin, off frontend) 480 5% 1.0s

I dati sono medie su 7 giorni di monitoraggio con htop e Query Monitor. Il tempo di caricamento admin è stato misurato caricando /wp-admin/index.php con cache del browser disabilitata. La differenza tra Default e Selettivo è drastica: 1.3 punti percentuali di CPU e 0.8 secondi di caricamento più veloce.

Configurazione Nginx per Rate-Limiting admin-ajax

Oltre a ridurre la frequenza lato WordPress, puoi aggiungere un layer di rate-limiting su Nginx per prevenire abusi. Se qualcuno lascia 20 tab aperti, Nginx bloccherà le richieste in eccesso prima che colpiscano PHP:

# /etc/nginx/conf.d/rate_limit.conf

# Definisci una zona di rate limiting per admin-ajax
# 10 richieste al minuto per IP
limit_req_zone $binary_remote_addr zone=admin_ajax:10m rate=10r/m;

server {
    # ... tua config ...

    location = /wp-admin/admin-ajax.php {
        limit_req zone=admin_ajax burst=20 nodelay;
        limit_req_status 429;

        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

Configurazione equivalente per Apache usando mod_evasive o mod_ratelimit:

# .htaccess o nella config del VirtualHost
<IfModule mod_ratelimit.c>
    <LocationMatch "^/wp-admin/admin-ajax\.php$">
        SetOutputFilter RATE_LIMIT
        LimitRate 50k
    </LocationMatch>
</IfModule>

Con rate-limiting a 10 richieste/minuto per IP, anche se un utente apre 20 tab, Nginx serve solo le prime 10 e restituisce 429 sulle altre. PHP non viene toccato. Il browser JavaScript gestisce il 429 come un tick fallito e riprova al prossimo intervallo. Nessun impatto sull’esperienza utente.

Cosa Perdi Disabilitando la Heartbeat API

Prima di disabilitare Heartbeat, devi sapere cosa perdi. Non è solo “autosave”. Ecco tutte le funzioni che dipendono dalla Heartbeat API:

1. Autosave dei Post

L’autosave automatico ogni 60 secondi usa Heartbeat per inviare la bozza al server. Senza Heartbeat, l’autosave non funziona. Perdi il recovery dei contenuti se il browser crasha. Per noi che gestiamo siti per clienti, questo è il dealbreaker. I clienti scrivono articoli lunghi e un crash senza autosave significa un ticket di supporto.

2. Post Locking

Quando due utenti modificano lo stesso post, WordPress usa Heartbeat per mostrare il messaggio “Qualcun altro sta modificando questo post”. Senza Heartbeat, il post locking non funziona. Due utenti possono sovrascrivere i reciproci cambiamenti. Su siti multi-autore, questo crea conflitti reali.

3. Notifiche Real-time dei Plugin

WooCommerce ordini, Easy Digital Downloads, plugin di notifica, e alcuni plugin SEO usano Heartbeat per mostrare aggiornamenti in tempo reale. Disabilitandolo, queste notifiche arrivano solo al refresh della pagina.

4. Custom Meta Box Sync

Alcuni plugin e temi (es. ACF, Meta Box) usano Heartbeat per sincronizzare i meta box in tempo reale. Senza Heartbeat, i cambiamenti ai campi personalizzati potrebbero non essere salvati correttamente se l’utente naviga via dall’editor senza salvare.

Heartbeat API e Core Web Vitals

L’impatto della Heartbeat API non è limitato al backend. Se un plugin attiva Heartbeat sul frontend (alcuni plugin di WooCommerce, plugin di chat, plugin di notifica), le richieste admin-ajax competono con il caricamento delle risorse per l’attenzione del browser. Questo rallenta il Interaction to Next Paint (INP), la metrica Core Web Vitals che misura la reattivita delle interazioni utente.

Abbiamo misurato l’impatto su un sito WooCommerce con Heartbeat attivo sul frontend (intervallo 15s, conteggio carrello dinamico):

  • INP mobile prima di disabilitare Heartbeat frontend: 280ms
  • INP mobile dopo disabilitazione: 190ms
  • Miglioramento: -32%

Il motivo è semplice: ogni 15 secondi, il browser invia una richiesta POST e aspetta la risposta. Durante quel window, le interazioni utente (tap, click) vengono messe in coda. Disabilitando Heartbeat sul frontend, il thread principale del browser resta libero per le interazioni reali.

Per approfondire come ottimizzare l’INP su WordPress, leggi la nostra guida completa all’INP. E per la configurazione della cache server che riduce ulteriormente il carico, vedi la nostra guida su Core Web Vitals per agenzie.

Script di Automazione per Multi-Sito

Per le agenzie che gestiscono 10+ siti, modificare functions.php su ogni sito non è scalabile. Usiamo un plugin mu (must-use) che deployiamo via WP-CLI su tutti i siti clienti. Ecco il codice:

// /wp-content/mu-plugins/agencypilot-heartbeat-control.php
<?php
/**
 * Plugin Name: AgencyPilot Heartbeat Control
 * Description: Throttles Heartbeat API to 60s in admin, disables on frontend.
 * Version: 1.0
 * Author: AgencyPilot
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Throttle Heartbeat interval to 60 seconds in admin.
 */
function agencypilot_mu_throttle_heartbeat( $settings ) {
    if ( is_admin() ) {
        $settings['interval'] = 60;
    }
    return $settings;
}
add_filter( 'heartbeat_settings', 'agencypilot_mu_throttle_heartbeat' );

/**
 * Disable Heartbeat on frontend.
 * Exception: WooCommerce cart and checkout pages.
 */
function agencypilot_mu_disable_frontend_heartbeat() {
    if ( is_admin() ) {
        return;
    }

    // Allow Heartbeat on WooCommerce cart/checkout
    if ( function_exists( 'is_woocommerce' ) ) {
        if ( is_cart() || is_checkout() ) {
            return;
        }
    }

    wp_deregister_script( 'heartbeat' );
}
add_action( 'init', 'agencypilot_mu_disable_frontend_heartbeat', 1 );

Deploy su tutti i siti con un singolo comando:

#!/bin/bash
# deploy-heartbeat-control.sh
# Usa WP-CLI per installare il mu-plugin su tutti i siti

SITES=(
    "https://cliente1.com"
    "https://cliente2.com"
    "https://cliente3.com"
    # ... aggiungi qui i tuoi siti
)

for SITE in "${SITES[@]}"; do
    echo "Deploying Heartbeat Control on $SITE..."
    wp mu-plugin install agencypilot-heartbeat-control.php \
        --path="/var/www/${SITE#https://}/wordpress" \
        --skip-themes --skip-plugins 2>/dev/null || \
    echo "  FAILED: $SITE"
done

echo "Deploy completato."

Questo script scarica il mu-plugin su ogni sito. I mu-plugin non possono essere disabilitati dal pannello admin, quindi la configurazione resta attiva anche se un cliente installa plugin che provano a riattivare Heartbeat.

FAQ: WordPress Heartbeat API per Agenzie

La Heartbeat API influenza il SEO?

Indirettamente, sì. Se Heartbeat consuma CPU sul server, le pagine frontend si caricano più lentamente. Il TTFB aumenta. Google penalizza i siti lenti nei Core Web Vitals. Disabilitando Heartbeat sul frontend e riducendolo nel backend, liberi risorse per servire le pagine ai visitatori (e ai bot di Google) più velocemente.

Posso disabilitare Heartbeat solo sul frontend?

Sì. Usa il filtro init e controlla is_admin(). Se non sei in admin, esegui wp_deregister_script( 'heartbeat' ). Questo disabilita Heartbeat solo per i visitatori del frontend, mantenendo le funzioni admin (autosave, post locking) attive per chi gestisce il sito. È la configurazione che consigliamo come default.

Quanto riduce il carico CPU throttle a 60 secondi?

Portando l’intervallo da 15 a 60 secondi, riduci le richieste admin-ajax del 75%. Se il tuo sito genera 2400 richieste Heartbeat al giorno con intervallo 15s, passi a 600 con intervallo 60s. In termini di CPU, su un VPS con 2 vCPU, questo si traduce in circa 10 punti percentuali di CPU media libera durante le ore di lavoro.

Heartbeat API e WP-Cron sono la stessa cosa?

No. WP-Cron è il sistema di scheduling delle attività programmate di WordPress (pubblicazione post, backup, invio email). La Heartbeat API è il sistema di polling real-time del browser. Sono due cose diverse. WP-Cron gira sul server, Heartbeat gira nel browser. Entrambi possono causare problemi di performance, ma per motivi diversi. Disabilitare uno non influisce sull’altro.

Quali plugin usano la Heartbeat API?

I plugin più comuni che agganciano Heartbeat: WooCommerce (conteggio carrello, ordini real-time), Yoast SEO (notifiche indexazione), Rank Math (notifiche), WP Rocket (preloading notifiche), BuddyPress (notifiche social), e praticamente tutti i plugin di chat e supporto live. Se hai uno di questi plugin, disabilitare Heartbeat completamente potrebbe romperne le funzionalità. Per questo consigliamo sempre il throttle a 60 secondi invece del disable totale.

Gestisci i siti WordPress dei tuoi clienti?

AgencyPilot ti dà report AI, uptime monitoring, backup e portale clienti in un’unica dashboard. Gratis per 3 siti.

Prova gratis
Leggi anche
Tutti gli articoli
Tutti gli articoli