Conceptos Básicos de Caching
8 ejemplos para empezar con el caching para APIs de Node.js - 6 básicos y 2 intermedios.
Busca en todas las páginas de la documentación
8 ejemplos para empezar con el caching para APIs de Node.js - 6 básicos y 2 intermedios.
npm install ioredis
npm install -D typescript@5.6 tsx @types/nodeEjecuta Redis localmente: docker run -d -p 6379:6379 redis:7. Consulta ioredis para detalles de conexión.
import Redis from "ioredis";
const redis = new Redis(process.env.REDIS_URL!);
export async function getProduct(sku: string, loadFromDb: (sku: string) => Promise<Product | null>) {
const key = `product:${sku}`;
const cached = await redis.get(key);
if (cached) return JSON.parse(cached) as Product;
const product = await loadFromDb(sku);
if (product) {
await redis.set(key, JSON.stringify(product), "EX", 300);
}
return product;
}EX 300) limita la obsolescenciaRelacionado: ioredis - configuración del cliente
| Tipo de datos | TTL típico | Invalidación |
|---|---|---|
| Catálogo de productos | 5-15 min | En actualización de administrador |
| Sesión de usuario | Deslizante de 24h | El cierre de sesión elimina la clave |
| Banderas de configuración | 30-60s | Pub/sub o TTL corto |
| Contadores de límite de tasa | Ventana de 1 min | Expiración automática |
export async function updateProduct(sku: string, data: Partial<Product>, save: () => Promise<Product>) {
const updated = await save();
await redis.del(`product:${sku}`);
return updated;
}const NS = `api:${process.env.APP_ENV}:v1`;
function productKey(sku: string) {
return `${NS}:product:${sku}`;
}v1 a v2 en cambios de forma de caché que rompen la compatibilidadexport async function getWithFallback<T>(
fetchCache: () => Promise<T | null>,
fetchOrigin: () => Promise<T>
): Promise<T> {
try {
const hit = await fetchCache();
if (hit !== null) return hit;
} catch (err) {
console.warn({ msg: "cache_unavailable", err: (err as Error).message });
}
return fetchOrigin();
}await redis.set(key, JSON.stringify(value), "EX", ttl);
const raw = await redis.get(key);
const value = raw ? (JSON.parse(raw) as T) : null;async function getOrLoad(key: string, ttlSec: number, loader: () => Promise<string>) {
const hit = await redis.get(key);
if (hit) return hit;
const lockKey = `${key}:lock`;
const acquired = await redis.set(lockKey, "1", "EX", 10, "NX");
if (!acquired) {
await new Promise((r) => setTimeout(r, 50));
return (await redis.get(key)) ?? loader();
}
try {
const value = await loader();
await redis.set(key, value, "EX", ttlSec);
return value;
} finally {
await redis.del(lockKey);
}
}Relacionado: Bloqueos Distribuidos - advertencias de bloqueo
| Patrón | ¿Quién carga en caso de fallo? | Patrón de Node |
|---|---|---|
| Cache-aside | Código de la aplicación | La mayoría de los manejadores de Express/Fastify |
| Read-through | Librería de caché | Menos común en Node |
| Write-through | Escritura síncrona en caché + DB | Mayor costo de consistencia |
Generalmente no. Cachea las lecturas GET con semántica de clave clara. Las mutaciones invalidan.
En memoria por instancia causa aciertos inconsistentes entre réplicas. Redis para caché compartida.
70%+ en claves "calientes" específicas es saludable. Una tasa baja significa claves incorrectas o TTL demasiado corto.
Sí, con un TTL corto (30-60s) para proteger la DB de fallos repetidos para claves ausentes.
CDN/Cache-Control para lecturas estáticas públicas. Redis para datos personalizados o protegidos por autenticación.
allkeys-lru es común en nodos de caché dedicados. Monitorea las alertas de uso de memoria.
Incluye tenantId en el prefijo de la clave. Nunca permitas la fuga de caché entre inquilinos.
@nestjs/cache-manager envuelve almacenes incluyendo Redis. Se aplican las mismas reglas de TTL e invalidación.
Versiones de la pila: Esta página fue escrita para Node.js 24.18.0 (LTS Activo), npm 10+, TypeScript 5.6+, Express 5, Fastify 5 y NestJS 11.
Revisado por Chris St. John·Última actualización: 19 jul 2026