Configuración de Heartbeat API para reducir el uso de CPU en el admin

La Heartbeat API de WordPress mantiene sincronía entre el navegador y el servidor (autosaves, bloqueo de post, sesiones y otras funciones). En sitios con alto tráfico o con plugins que usan intensivamente estas llamadas, el admin puede generar numerosas peticiones AJAX a admin-ajax.php, provocando picos de CPU. Esta guía explica cómo diagnosticar el problema, aplicar ajustes seguros en WordPress y, si hace falta, mitigar a nivel servidor.

Por qué la Heartbeat API puede consumir CPU

Heartbeat no es mala por sí misma: envía peticiones periódicas desde el navegador para que el servidor ejecute lógica relacionada con la edición, sincronización de sesiones o notificaciones. Los problemas típicos son:

  • Intervalos muy cortos (por defecto la edición y el admin usan intervalos bajos, p. ej. ~15s).
  • Plugins o temas que añaden callbacks pesados a cada pulso (consultas a la base de datos, llamadas externas).
  • Múltiples usuarios conectados a la vez con pestañas abiertas del admin.
  • Servidor sin recursos o con mala configuración de PHP/NGINX/Apache que no absorbe la carga.

Diagnóstico: cómo identificar que Heartbeat es la causa

Sigue estos pasos antes de aplicar cambios:

  • Usa las DevTools del navegador (pestaña Network) para filtrar por admin-ajax.php y revisar la frecuencia y duración de las peticiones.
  • En el servidor, monitoriza procesos con top/htop y observa picos de PHP-FPM o Apache cuando varios usuarios están en el admin.
  • Activa temporalmente un plugin de monitorización como Query Monitor para ver qué hooks se ejecutan en admin-ajax.php (identifica funciones que ejecuten consultas costosas).
  • Reproduce la carga: abre varias pestañas del editor y observa el impacto.

Entender si las peticiones son frecuentes (cada 15s) y si disparan lógica pesada determina la solución adecuada.

Ajustes en WordPress: soluciones seguras y recomendadas

Antes de desactivar Heartbeat por completo, prefiera reducir su frecuencia o limitarlo en páginas concretas. A continuación hay snippets listos para usar.

Aumentar el intervalo de Heartbeat (recomendado)

Este filtro modifica el intervalo en segundos. Valores seguros: 60–120s en admin fuera del editor; 30–60s en el editor.

add_filter('heartbeat_settings', 'mi_heartbeat_interval');
function mi_heartbeat_interval($settings) {
    // intervalo en segundos
    $settings['interval'] = 60; // subir de 15 a 60 por ejemplo
    return $settings;
}

Colócalo en el functions.php del tema hijo o en un mu-plugin. Esta técnica reduce la carga sin perder funcionalidades críticas.

Desactivar Heartbeat en pantallas concretas

Si sólo necesitas Heartbeat en el editor (post.php / post-new.php), puedes desregistrarlo en otras páginas del admin:

add_action('admin_enqueue_scripts', 'desactivar_heartbeat_admin', 1);
function desactivar_heartbeat_admin() {
    $screen = get_current_screen();
    if (!$screen) return;

    // conservar en editor de entradas y páginas
    if (in_array($screen->base, array('post', 'post-new'))) {
        return;
    }

    wp_deregister_script('heartbeat');
}

Precaución: desregistrar Heartbeat puede romper plugins que dependan de él (sincronizaciones, bloqueos). Testea en staging antes de producción.

Reducir autosaves y revisiones

Autosaves interactúan con Heartbeat. Ajusta el intervalo de autosave y el número de revisiones para bajar frecuencia y I/O en base de datos:

// en wp-config.php
define('AUTOSAVE_INTERVAL', 300); // por defecto 60s, aumenta a 5 minutos
define('WP_POST_REVISIONS', 5);  // limita revisiones para reducir escrituras

Mitigación a nivel servidor

Si el problema es masivo o hay ataques/bots que generan muchas peticiones, conviene aplicar límites en el servidor.

Rate limiting con NGINX

Con NGINX puedes limitar las peticiones a admin-ajax.php por IP:

http {
    limit_req_zone $binary_remote_addr zone=ajax_zone:10m rate=5r/s;
    ...
}

server {
    location = /wp-admin/admin-ajax.php {
        limit_req zone=ajax_zone burst=10 nodelay;
        include fastcgi_params;
        fastcgi_pass unix:/run/php/php7.4-fpm.sock;
    }
}

Este ejemplo permite 5 peticiones/segundo por IP y evita ráfagas. Consulta la documentación oficial de NGINX para ajustar parámetros a tu entorno.

Filtro de tráfico y WAF

Si usas un CDN o WAF, aplica reglas que limiten o bloqueen tráfico sospechoso en rutas como /wp-admin/ o /wp-admin/admin-ajax.php. Cloudflare ofrece opciones de rate limiting y reglas de firewall que pueden reducir carga sin tocar la app: Cloudflare Rate Limiting.

Optimización de código y plugins

Revisa plugins que añadan callbacks a la Heartbeat. Buenas prácticas:

  • Evitar consultas sin índices en callbacks de Heartbeat.
  • Mover tareas costosas a cron o jobs asíncronos (WP-Cron, colas o workers).
  • Cachear resultados frecuentes en transients u object cache (Redis/Memcached).

Para entender cómo las llamadas AJAX usan recursos en PHP, la referencia de funciones y comportamiento en servidor puede consultarse en PHP.net, útil para optimizar tiempos de ejecución y gc de procesos.

Pruebas y buenas prácticas antes de aplicar en producción

  • Implementa cambios en staging y mide CPU/RPS con herramientas de monitoreo (top, htop, recursos del proveedor).
  • Comprueba que funcionalidades críticas siguen operativas (bloqueo de editores, notificaciones, revisiones).
  • Si reduces el intervalo, haz pruebas con varios roles y usuarios simultáneos.
  • Registra métricas antes y después (latencia de admin, número de peticiones a admin-ajax, uso de CPU).

Ejemplo práctico: combinación segura

Una configuración equilibrada para un sitio con tráfico medio puede combinar:

  • Aumentar intervalo a 60s mediante heartbeat_settings.
  • Desregistrar Heartbeat fuera del editor (evitar llamadas en listados y dashboards).
  • Limitar rate en NGINX para controlar ráfagas.
  • Optimizar callbacks pesados y usar object caching.

Esto reduce peticiones por usuario, baja I/O y atenúa picos de CPU sin romper funciones clave.

Recursos y enlaces útiles

Para profundizar sobre cómo funcionan las peticiones en el navegador y su implementación, la documentación de MDN Web Docs sobre XHR/Fetch es muy valiosa. Para aplicar limitación en el servidor revisa la guía de NGINX y la sección de rate limiting de Cloudflare para reglas avanzadas.

Conclusión

La Heartbeat API es necesaria, pero su configuración por defecto y el uso que hagan plugins pueden generar una carga significativa en el admin. El enfoque correcto es: diagnosticar con datos, aumentar intervalos de forma prudente, limitar Heartbeat donde no se necesita y aplicar mitigaciones a nivel servidor cuando corresponda. Implementa cambios en staging, monitoriza métricas y prioriza optimizaciones de código (caching y offloading de tareas) antes de recurrir a desactivaciones radicales. Con estos pasos reducirás picos de CPU sin sacrificar la experiencia de administración.