Saltar al contenido
Linux 2024-12-28 14 min de lectura

Mejora del Rendimiento de tu Servidor con Caching en Nginx

Cuando un servidor empieza a sufrir por el volumen de peticiones y las páginas tardan cada vez más en responder, el caching con Nginx es la optimización con mejor relación esfuerzo-resultado que existe: convierte una página que exigía arrancar PHP y consultar la base de datos en un archivo que se lee del disco en microsegundos. Esta guía explica qué tipos de caché ofrece Nginx, cómo configurar proxy cache y FastCGI cache paso a paso, cómo excluir correctamente las rutas con sesión —el error que más problemas causa— y cómo verificar que todo funciona.

Mejora del Rendimiento de tu Servidor con Caching en Nginx
#Linux#Nginx#Caché#Rendimiento
T
Equipo Terranode
Editorial

Qué es el caching en Nginx y por qué funciona

El caching en Nginx consiste en guardar la respuesta ya generada de una petición para servirla tal cual en las siguientes, sin volver a ejecutar la aplicación que la produjo. Nginx guarda el cuerpo de la respuesta en disco y mantiene en memoria un índice con las claves que identifican cada entrada, así que la búsqueda es inmediata.

La diferencia práctica está en cuánto trabajo se salta. Una petición sin caché a un WordPress recorre este camino: Nginx recibe la petición, la pasa a PHP-FPM, PHP arranca WordPress, WordPress ejecuta decenas de consultas a MySQL, compone el HTML y lo devuelve. Con FastCGI cache activo, la misma petición se resuelve leyendo un archivo. Ese salto es la razón por la que un servidor modesto puede atender picos de tráfico que sin caché lo tumbarían: cuando el contenido no cambia entre un visitante y otro, generarlo de nuevo cada vez es trabajo puro repetido.

Este artículo usa la configuración de Nginx open source. La rama estable actual es la 1.30.x, publicada en abril de 2026, y la mainline va por 1.31.4, de agosto de 2026; todas las directivas que aparecen aquí existen desde hace muchas versiones y funcionan igual en las ramas anteriores.

Los tres tipos de caché de Nginx, comparados

Nginx ofrece tres enfoques según qué haya detrás del servidor y cuánto pueda envejecer el contenido:

TipoQué cacheaCuándo usarloDirectiva principal
Proxy cacheRespuestas de un backend HTTP (Node, Python, otro servidor web)Nginx actúa como proxy inverso delante de una aplicaciónproxy_cache_path
FastCGI cacheRespuestas de PHP-FPMWordPress, WooCommerce, Laravel y cualquier PHPfastcgi_cache_path
MicrocachingLo mismo que los anteriores, pero durante 1-10 segundosContenido que cambia a menudo pero recibe muchas visitas simultáneasproxy_cache_valid 200 1s

A eso se suma una capa distinta que conviene no confundir: el caché del navegador, que se controla con las cabeceras Cache-Control y Expires y hace que el visitante no vuelva a descargar imágenes, CSS y JavaScript. Esa capa ahorra ancho de banda y peticiones; las tres de la tabla ahorran trabajo de CPU y de base de datos en el servidor.

Ventajas y límites del caching

El caching resuelve un problema muy concreto y no resuelve otros, así que conviene tener claras ambas listas antes de configurarlo.

Lo que aporta:

  • Menos carga en el backend: la misma respuesta no se regenera una y otra vez, lo que libera CPU, memoria y conexiones a la base de datos.
  • Respuestas más rápidas: leer un archivo de caché toma microsegundos frente a las decenas o cientos de milisegundos que exige generar la página.
  • Escalabilidad: el mismo servidor atiende muchos más visitantes simultáneos, porque el coste por visita adicional cae casi a cero.
  • Resistencia a caídas: bien configurado, Nginx puede seguir sirviendo la copia guardada aunque el backend se caiga.

Lo que no resuelve o complica:

  • Contenido personalizado por usuario: carritos, paneles y cualquier página con sesión quedan fuera y deben excluirse explícitamente.
  • Espacio en disco: la caché crece hasta el límite que le pongas, y sin max_size puede llenar la partición.
  • Contenido desactualizado: si el original cambia y la caché no se invalida, los visitantes ven la versión vieja hasta que caduque.
  • Depuración más difícil: un cambio que "no se aplica" suele ser una copia en caché, y eso confunde durante los despliegues.

Paso 1: definir la zona de caché

La zona de caché se declara una sola vez, en el bloque http de la configuración principal, y define dónde se guarda el contenido y cuánta memoria se reserva para el índice:

nginx
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache_zone:10m max_size=1g inactive=60m use_temp_path=off;

Cada parámetro decide algo concreto:

  • /var/cache/nginx: ruta en disco donde se guardan los archivos de la caché.
  • levels=1:2: crea una jerarquía de subdirectorios en lugar de meter miles de archivos en una sola carpeta, lo que acelera el acceso del sistema de archivos.
  • keys_zone=cache_zone:10m: nombre de la zona y memoria reservada para el índice de claves. Un megabyte almacena unas 8.000 claves, así que 10m cubre alrededor de 80.000 URLs.
  • max_size=1g: tope de espacio en disco. Al alcanzarlo, Nginx elimina las entradas usadas hace más tiempo.
  • inactive=60m: una entrada que nadie solicite durante 60 minutos se borra aunque no haya caducado.
  • use_temp_path=off: escribe directamente en el directorio de caché en vez de copiar desde una carpeta temporal, evitando una copia innecesaria entre discos.

Paso 2: habilitar proxy cache en un location

Con la zona declarada, se activa dentro del bloque location que quieras cachear. Esta configuración sirve para Nginx trabajando como proxy inverso delante de una aplicación en Node, Python o cualquier otro backend HTTP:

nginx
location / {
    proxy_pass http://backend;
    proxy_cache cache_zone;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;

    proxy_cache_valid 200 302 10m;
    proxy_cache_valid 404 1m;

    # Una sola petición regenera la entrada; las demás esperan
    proxy_cache_lock on;

    # Sirve la copia vieja mientras se regenera en segundo plano
    proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504;
    proxy_cache_background_update on;

    add_header X-Cache-Status $upstream_cache_status;
}

Las tres directivas del bloque central son las que separan una caché básica de una que aguanta tráfico real. proxy_cache_lock on evita la estampida de caché: cuando una entrada caduca y llegan cien peticiones a la vez, solo una va al backend y las demás esperan el resultado. proxy_cache_use_stale updating junto con proxy_cache_background_update on permite entregar la copia caducada al visitante mientras Nginx regenera la nueva por detrás, de modo que nadie paga la espera de la regeneración. Incluir error timeout http_500 en la lista añade un efecto valioso: si el backend se cae, los visitantes siguen viendo el sitio.

Paso 3: FastCGI cache para WordPress y PHP

Cuando la aplicación corre sobre PHP-FPM, el equivalente al proxy cache es el FastCGI cache. La configuración necesita tres piezas que a menudo se omiten y que son imprescindibles: la clave de caché, las reglas de exclusión y su aplicación en el location de PHP.

Primero, la zona y la clave, en el bloque http:

nginx
fastcgi_cache_path /var/cache/nginx_fastcgi levels=1:2 keys_zone=WORDPRESS:100m max_size=1g inactive=60m use_temp_path=off;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

La clave de caché define qué se considera "la misma página". Incluir el esquema, el método, el host y la URI evita que la versión HTTP y la HTTPS, o dos dominios distintos del mismo servidor, compartan la misma entrada por error.

Segundo, las reglas de exclusión, dentro del bloque server:

nginx
set $skip_cache 0;

# Nunca cachear peticiones POST ni URLs con parámetros
if ($request_method = POST) { set $skip_cache 1; }
if ($query_string != "") { set $skip_cache 1; }

# Zonas privadas de WordPress y WooCommerce
if ($request_uri ~* "/wp-admin/|/wp-json/|/xmlrpc.php|wp-.*.php|/feed/|sitemap(_index)?.xml") { set $skip_cache 1; }
if ($request_uri ~* "/carrito|/cart|/finalizar-compra|/checkout|/mi-cuenta|/my-account") { set $skip_cache 1; }

# Usuarios identificados: sesión iniciada, comentario reciente o carrito activo
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_logged_in|woocommerce_items_in_cart|woocommerce_cart_hash") { set $skip_cache 1; }

Tercero, el location de PHP que usa todo lo anterior:

nginx
location ~ \.php$ {
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass unix:/run/php/php8.4-fpm.sock;

    fastcgi_cache WORDPRESS;
    fastcgi_cache_valid 200 301 302 60m;
    fastcgi_cache_valid 404 1m;

    fastcgi_cache_bypass $skip_cache;   # No leer de la caché
    fastcgi_no_cache $skip_cache;       # No guardar en la caché

    fastcgi_cache_lock on;
    fastcgi_cache_use_stale updating error timeout http_500 http_503;
    fastcgi_cache_background_update on;

    add_header X-FastCGI-Cache $upstream_cache_status;
}

Las dos directivas de exclusión hacen cosas distintas y hay que poner ambas: fastcgi_cache_bypass impide leer de la caché y fastcgi_no_cache impide guardar en ella. Con solo una de las dos, el sitio termina almacenando la página de un usuario identificado y sirviéndosela a un visitante anónimo.

El socket php8.4-fpm.sock corresponde a PHP 8.4, la versión con soporte activo en 2026. Ajusta la ruta a la versión instalada en tu servidor: ls /run/php/ muestra los sockets disponibles.

Microcaching: caché de un segundo para contenido que cambia

El microcaching aplica tiempos de vida de uno a diez segundos a contenido que se considera dinámico. Suena poco, y ese es exactamente el punto: en una página que recibe 500 visitas por segundo, cachear un solo segundo reduce la carga en el backend en un factor de 500 sin que ningún visitante vea datos con más de un segundo de antigüedad. Es la técnica que salva a los portales de noticias durante una noticia viral.

nginx
location / {
    proxy_pass http://backend;
    proxy_cache cache_zone;
    proxy_cache_valid 200 1s;
    proxy_cache_lock on;
    proxy_cache_use_stale updating;
    proxy_cache_background_update on;

    # Los usuarios con sesión nunca reciben la copia compartida
    proxy_cache_bypass $cookie_session;
    proxy_no_cache $cookie_session;
}

Existe además fastcgi_cache_min_uses, que retrasa el guardado hasta que una URL se pide N veces. Con fastcgi_cache_min_uses 3; solo se cachea lo que realmente se repite, lo que evita llenar el disco con miles de URLs que nadie vuelve a visitar.

Cómo verificar que la caché está funcionando

Con la cabecera X-Cache-Status activada, una petición con curl responde la pregunta en un segundo:

bash
curl -I https://tu-sitio.com/

En la salida aparecerá una línea como X-Cache-Status: HIT. Estos son los valores posibles y qué significa cada uno:

ValorQué ocurrióQué hacer
MISSNo estaba en caché; se pidió al backend y se guardóNormal en la primera petición. Repite el curl
HITSe sirvió desde la caché sin tocar el backendTodo correcto
BYPASSUna regla de exclusión impidió usar la cachéCorrecto en /wp-admin/; revisa las reglas si ocurre en la portada
EXPIREDLa copia había caducado y se regeneróNormal; sube fastcgi_cache_valid si pasa demasiado
UPDATINGSe sirvió la copia vieja mientras se regenerabaCorrecto, es el efecto de use_stale updating
STALEEl backend falló y se sirvió la copia viejaRevisa PHP-FPM o el backend, está caído

La prueba que de verdad importa: abre el sitio con sesión de administrador y confirma que devuelve BYPASS, y ábrelo en una ventana privada y confirma que devuelve HIT. Si un usuario identificado obtiene HIT, las reglas de exclusión no están funcionando y hay que corregirlas antes de dejar la configuración en producción.

Cómo purgar la caché

Nginx open source no incluye purga selectiva por URL. La directiva proxy_cache_purge, que permite borrar una entrada concreta con una petición, forma parte de la suscripción comercial NGINX Plus. En la versión libre hay tres caminos:

bash
# 1. Vaciado completo: borra todo el contenido de la caché
sudo rm -rf /var/cache/nginx_fastcgi/*
sudo systemctl reload nginx

El segundo camino es compilar el módulo de terceros ngx_cache_purge, que añade purga por URL. El tercero, el más práctico en WordPress, es instalar un plugin como Nginx Helper, que borra del directorio de caché el archivo correspondiente a cada entrada al publicarla o editarla. Esa combinación —Nginx sirviendo y el plugin invalidando— es la que usa la mayoría de las instalaciones serias.

Cuándo el caching no es la respuesta

Conviene decirlo con claridad: el caching esconde un backend lento, no lo arregla. Si tu aplicación tarda tres segundos en generar una página, con caché los visitantes verán la copia rápida, pero cada regeneración seguirá costando esos tres segundos y cualquier página no cacheable —el carrito, la búsqueda, el panel— seguirá igual de lenta.

Hay tres situaciones en las que el trabajo está en otro lado:

  • Casi todo el tráfico es de usuarios identificados. Si el 90% de las peticiones tienen sesión, la caché compartida apenas se usa y el esfuerzo debe ir a optimizar consultas e índices.
  • El servidor no tiene recursos suficientes. Cuando la CPU vive al 100% incluso con la caché caliente, el límite es de hardware. Ahí la comparación entre hosting compartido, VPS y servidor dedicado ayuda a dimensionar lo que hace falta, y un VPS con recursos garantizados suele ser el siguiente paso.
  • El contenido es genuinamente único por visitante. Un panel de control o una API personalizada no se cachean; se optimizan.

Si tu sitio es un WordPress en hosting compartido, además, es posible que ni siquiera puedas tocar la configuración de Nginx. En ese caso el equivalente es la caché a nivel de servidor que ofrezca el proveedor, un criterio que conviene revisar antes de contratar y que detallamos en la guía de hosting para WordPress en Ecuador.

El caching en Nginx se resume en tres decisiones: qué cachear, por cuánto tiempo y qué excluir. Proxy cache para backends HTTP, FastCGI cache para PHP y microcaching para contenido que cambia a menudo pero recibe mucho tráfico simultáneo. Las directivas que marcan la diferencia en producción son cache_lock, use_stale updating y background_update, porque eliminan tanto la estampida de peticiones como la espera de la regeneración. Y la regla que nunca se negocia: comprobar con X-Cache-Status que las páginas con sesión devuelven BYPASS antes de dejar la configuración funcionando. Si tienes dudas durante la implementación, nuestro equipo de soporte técnico está disponible 24/7 para ayudarte.

¿Listo para llevar tu sitio al siguiente nivel?

Hosting con LiteSpeed, NVMe y soporte 24/7 desde $3/mes.

Ver planes de hosting

Preguntas frecuentes