Sitio WordPress lento o caído por alto número de 404s
Cómo diagnosticar y resolver un sitio WordPress lento o inaccesible causado por bots rastreando URLs inexistentes y generando miles de respuestas 404.
Al administrar un sitio WordPress es posible que en algún momento el sitio se vuelva lento o directamente inaccesible. El primer instinto es revisar CPU, memoria y load average — y vas a encontrar que están al límite. El proceso que más consume es apache2, php-fpm o nginx según el stack.
Lo curioso es que al revisar plugins, caché y errores no encuentras nada obvio.
He pasado por esto. El culpable suele ser una campaña de SEO agresiva o un bot que rastrea cientos de URLs que no existen, cambiaron o fueron borradas. Cada request genera un ciclo completo de WordPress para devolver un 404, y con suficiente volumen colapsa el servidor.
Diagnóstico
1. Revisar logs del servidor web
# Apache
tail -f /var/log/apache2/access.log | grep " 404 "
# Nginx
tail -f /var/log/nginx/access.log | grep " 404 "Busca un patrón: si ves cientos de requests por segundo a URLs que no existen, encontraste el problema.
2. Comparar con métricas históricas
Correlaciona el spike de CPU/memoria con los logs de 404. Si coinciden en tiempo, confirmado.
3. Con WP Super Cache
Activar el modo debug en WP Super Cache genera un log que muestra qué URLs no se están cacheando. Las páginas 404 de WordPress no se cachean, por eso cada una consume recursos.
Soluciones
Bloquear bots conocidos en .htaccess (Apache)
Si identificas que el tráfico proviene de un bot específico:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} (AhrefsBot|SemrushBot|MJ12bot|DotBot) [NC]
RewriteRule .* - [F,L]
</IfModule>Evitar que WordPress procese archivos estáticos inexistentes (Apache)
Si el bot está rastreando rutas de archivos estáticos (.css, .js, .jpg, etc.) que no existen, WordPress no debería procesarlos en absoluto:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(robots\.txt|sitemap\.xml)
RewriteCond %{REQUEST_URI} \.(css|js|gif|jpg|jpeg|png|ico|svg|woff|woff2|ttf|pdf|zip)$ [NC]
RewriteRule .* - [L]
</IfModule>Esto retorna un 404 inmediato del servidor web sin cargar WordPress — mucho más barato en recursos.
Bloquear URLs de Facebook y otros dominios embebidos (Apache)
Un patrón frecuente es encontrar requests a rutas como /www.facebook.com/plugins/... que alguna migración dejó mal referenciada:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} www\.facebook\.com/plugins [NC]
RewriteRule .* /404.html [L,R=404]
</IfModule>Nginx — bloquear rutas inexistentes sin cargar PHP
location ~* \.(css|js|gif|jpg|jpeg|png|ico|svg|woff|woff2|ttf|pdf|zip)$ {
try_files $uri =404;
# No hacer proxy a PHP-FPM si el archivo no existe
}