Skip to content
SP StackPractices
intermediate Por StackPractices

Estrategias de Caching

Implementa estrategias de caching efectivas para bases de datos, APIs y frontends usando Redis, CDNs y caches de navegador.

Nota para desarrolladores hispanohablantes: Esta guía incluye ejemplos y convenciones de nomenclatura adaptadas a equipos que trabajan en español. Cuando existen diferencias significativas en terminología técnica entre el inglés y el español, se indican explícitamente para facilitar la comunicación en equipos multiculturales.

Visión General

El caching es la técnica más efectiva para mejorar el rendimiento de aplicaciones. Almacenando datos frecuentemente accedidos cerca de los consumidores — en memoria del navegador, bordes de CDN o almacenamiento in-memory — reduces latencia, disminuyes carga de base de datos y mejoras la experiencia del usuario. Elegir la estrategia correcta depende de los requisitos de frescura de datos y patrones de lectura/escritura.

Cuándo Usar

Usa este recurso cuando:

  • Las consultas de base de datos se vuelven un cuello de botella bajo carga
  • Los tiempos de respuesta de API exceden 200ms para endpoints de lectura intensiva
  • Sirves assets estáticos (imágenes, JS, CSS) a usuarios globales via CDN
  • Construyes aplicaciones de alto tráfico donde datos stale son aceptables

Solución

Cache-Aside con Redis (Node.js)

const redis = require('redis');
const client = redis.createClient();

async function getUser(userId) {
  const cacheKey = `user:${userId}`;
  
  const cached = await client.get(cacheKey);
  if (cached) return JSON.parse(cached);
  
  const user = await db.users.findById(userId);
  if (user) {
    await client.setEx(cacheKey, 3600, JSON.stringify(user));
  }
  return user;
}

Stale-While-Revalidate (HTTP)

app.get('/api/products', (req, res) => {
  res.set('Cache-Control', 'public, max-age=60, stale-while-revalidate=300');
  res.json(products);
});

CDN Edge Caching (CloudFront/Vercel)

{
  "routes": [
    {
      "src": "/api/public/.*",
      "headers": {
        "Cache-Control": "public, s-maxage=86400, stale-while-revalidate=86400"
      }
    }
  ]
}

Explicación

EstrategiaPatrónIdeal Para
Cache-AsideLa app revisa cache, fallback a DBLectura intensiva; simple de implementar
Read-ThroughCache actúa como proxy transparente de DBLectura intensiva; la librería maneja lógica
Write-ThroughEscrituras actualizan cache y DB simultáneamenteConsistencia de datos crítica
Write-BehindEscrituras actualizan cache; flush async a DBEscritura intensiva; consistencia eventual
Refresh-AheadRefresh en background antes de expiraciónPatrones de acceso predecibles

Enfoques de invalidación de cache:

  • Basado en tiempo (TTL): Simple pero puede servir datos stale
  • Basado en clave: Incluye versión o hash en la clave de cache
  • Basado en eventos: Invalida cuando los datos cambian vía message bus. Consulta invalidación de caché.

Variantes

CapaTecnologíaLatenciaCaso de Uso
NavegadorLocalStorage, IndexedDB~1msApps offline-first
CDNCloudFront, Cloudflare, Fastly~10-50msAssets estáticos, caching de API en edge
AplicaciónRedis, Memcached~1msSession store, datos hot
Base de datosQuery cache, vistas materializadas~1-10msQueries complejas repetidas
DiscoPage cache, buffers del OS~0.1msLecturas de file system

Mejores Prácticas

  • Ajusta TTLs según volatilidad: Perfiles de usuario (1h), catálogos de productos (24h), precios de acciones (10s)
  • Cachea en múltiples capas: Navegador + CDN + Redis + query cache de DB
  • Usa protección contra stampede: Lock durante cache miss para prevenir thundering herd
  • Monitorea hit rates: Por debajo de 80% señala mala configuración o TTL demasiado corto
  • Versiona tus claves de cache: Incluye versión de app para invalidar en deploy

Errores Comunes

  1. Cachear todo: Datos estáticos sí; datos específicos de usuario o cambiantes frecuentemente no
  2. Sin estrategia de invalidación: Datos stale persisten indefinidamente sin TTL o eventos
  3. Thundering herd: 1000 requests golpean un cache cold simultáneamente; usa locking
  4. Cache poisoning: Input de usuario no validado almacenado en cache compartido afecta a todos los usuarios
  5. Ignorar cache warming: Deploys a producción arrancan con caches vacíos y alta latencia

Preguntas Frecuentes

P: ¿Cómo prevengo cache stampedes? R: Usa un mutex o Redis SET NX (lock) para que solo un request reconstruya el cache mientras otros esperan.

P: ¿Debería cachear respuestas GraphQL? R: Sí, pero cachea por hash de query + variables. Apollo Server tiene caching de respuestas built-in.

P: ¿Cuál es la diferencia entre Redis y Memcached? R: Redis soporta estructuras de datos (listas, sets, sorted sets) y persistencia. Memcached es más simple y ligeramente más rápido para caching plain key-value.