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:
| Tipo | Qué cachea | Cuándo usarlo | Directiva principal |
|---|---|---|---|
| Proxy cache | Respuestas de un backend HTTP (Node, Python, otro servidor web) | Nginx actúa como proxy inverso delante de una aplicación | proxy_cache_path |
| FastCGI cache | Respuestas de PHP-FPM | WordPress, WooCommerce, Laravel y cualquier PHP | fastcgi_cache_path |
| Microcaching | Lo mismo que los anteriores, pero durante 1-10 segundos | Contenido que cambia a menudo pero recibe muchas visitas simultáneas | proxy_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_sizepuede 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:
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í que10mcubre 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:
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:
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:
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:
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.
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:
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:
| Valor | Qué ocurrió | Qué hacer |
|---|---|---|
MISS | No estaba en caché; se pidió al backend y se guardó | Normal en la primera petición. Repite el curl |
HIT | Se sirvió desde la caché sin tocar el backend | Todo correcto |
BYPASS | Una regla de exclusión impidió usar la caché | Correcto en /wp-admin/; revisa las reglas si ocurre en la portada |
EXPIRED | La copia había caducado y se regeneró | Normal; sube fastcgi_cache_valid si pasa demasiado |
UPDATING | Se sirvió la copia vieja mientras se regeneraba | Correcto, es el efecto de use_stale updating |
STALE | El backend falló y se sirvió la copia vieja | Revisa 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:
# 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.
Hosting con LiteSpeed, NVMe y soporte 24/7 desde $3/mes.