Caching en la nube: estrategia para reducir latencia y costes

← Volver
Server rack with blinking green lights
Foto de Domaintechnik Ledl.net en Unsplash

El caching es una de las palancas con mejor ratio coste/beneficio en infraestructura cloud. No hace falta escalar verticalmente ni cambiar de proveedor: en la mayoría de arquitecturas, diseñar bien qué se cachea, cuánto tiempo y en qué capa puede reducir la latencia en órdenes de magnitud y recortar la factura de forma medible.

Este post describe cómo estructurar esa estrategia por capas, qué decisiones importan en cada una y cómo calcular el impacto económico antes de implementar.


1. Las tres capas de caché y por qué importa el orden

La caché no es un toggle. Es una decisión de arquitectura que ocurre en múltiples puntos de la cadena:

  • CDN / Edge: intercepta peticiones antes de que lleguen a tu servidor. Ideal para activos estáticos y respuestas de API con baja variabilidad por usuario.
  • Caché de aplicación: almacena el resultado de operaciones costosas (consultas, transformaciones, llamadas a terceros) en memoria dentro del proceso o en un servidor en-memoria como Valkey/Redis.
  • Caché de base de datos: reduce la presión sobre el motor SQL o NoSQL cacheando resultados de consultas frecuentes y costosas.

La regla general es: cuanto más cerca del usuario esté la capa de caché, más barata es la petición. Una respuesta servida desde edge no consume compute, no toca base de datos y, en GCP, se factura a $0.02–0.08/GB frente a $0.08–0.23/GB del egress estándar a internet.


2. Caché en CDN: qué cachear y durante cuánto tiempo

Qué tiene sentido cachear en edge

  • Activos estáticos versionados (JS, CSS, imágenes con hash en el nombre): TTL de hasta 365 días. Cuando el contenido cambia, el nombre del fichero cambia. No hay invalidación a gestionar.
  • Respuestas de API que no varían por usuario: listados públicos, precios, contenido editorial. TTL de minutos a horas según la frecuencia de actualización.
  • Páginas renderizadas en servidor con contenido no personalizado: el candidato más obvio para subir el cache hit ratio.

Qué no cachear en edge

  • Respuestas con datos de sesión o usuario específico.
  • Endpoints de escritura (POST, PUT, DELETE).
  • Respuestas que incluyen tokens CSRF o nonces únicos por petición.

El cache hit ratio como métrica de control

El cache hit ratio (CHR) mide qué porcentaje de peticiones se sirven desde caché sin tocar el origen. Para activos estáticos, un CHR saludable está entre el 80 y el 95%. Para respuestas de API dinámicas con TTL cortos, un 30–50% ya es razonable.

La fórmula de ahorro en egress es directa:

coste_origen × (1 - CHR) = nuevo_coste_origen

Si sirves 10 TB/mes de activos estáticos con un CHR del 70%, el origin recibe solo 3 TB. El egress directo que pagarías en AWS ($0.09/GB) sobre los 10 TB completos cae a 3 TB. La diferencia es inmediata y no requiere ningún cambio en tu código de aplicación.

Headers que determinan si el CDN puede cachear

Los CDN solo cachean lo que tus Cache-Control headers les permiten. Dos errores frecuentes:

  1. Cache-Control: no-store en activos que no cambian — el CDN no guarda nada, cada petición llega al origen.
  2. TTL demasiado corto en contenido estático — el CDN expira la entrada antes de tiempo y vuelve a pedir al origen con más frecuencia de la necesaria.

Configuración recomendada para activos versionados:

Cache-Control: public, max-age=31536000, immutable

Para respuestas de API cacheables con revalidación:

Cache-Control: public, max-age=300, stale-while-revalidate=60

3. Caché de aplicación: Redis, Valkey o Memcached

El contexto actual (relevante para nuevos proyectos)

El ecosistema Redis ha cambiado. En marzo de 2024, Redis Ltd. cambió la licencia de BSD a RSALv2/SSPLv1 a partir de la versión 7.4; después, en mayo de 2025, Redis 8.0 adoptó un modelo de triple licencia (RSALv2, SSPLv1 y AGPLv3). La Linux Foundation respondió creando Valkey a partir de Redis 7.2.4, con soporte de AWS, Google Cloud y otras organizaciones. En la práctica, AWS ElastiCache usa Valkey como motor por defecto en nuevos despliegues, y Google Cloud Memorystore también lo soporta. Valkey ofrece además un 20% de reducción de costes en instancias node-based frente a Redis en ElastiCache.

Para proyectos nuevos en AWS o GCP, la recomendación operativa es usar Valkey salvo que tengas dependencias explícitas de funcionalidades exclusivas de versiones recientes de Redis.

Memcached: cuándo sigue siendo la opción correcta

Memcached sigue siendo relevante para un caso específico: caching de objetos simples con máximo throughput y mínima operativa. Su arquitectura multihilo le da ventaja en escenarios de lectura masiva de valores string sin necesidad de estructuras de datos complejas. Si tu único caso de uso es cachear fragmentos HTML o resultados de queries simples y no necesitas persistencia ni failover automático, Memcached es más sencillo de operar y puede rendir mejor en ese rango estrecho.

Redis/Valkey gana en casi todo lo demás: estructuras de datos nativas (hashes, sorted sets, listas), persistencia opcional, clustering con failover automático y soporte de pub/sub.

Patrones de uso frecuentes

Cache-aside (lazy loading):

def get_product(product_id):
    cached = redis.get(f"product:{product_id}")
    if cached:
        return json.loads(cached)
    
    product = db.query("SELECT * FROM products WHERE id = %s", product_id)
    redis.setex(f"product:{product_id}", 300, json.dumps(product))  # TTL: 5 min
    return product

El cliente gestiona la carga: si no está en caché, consulta la base de datos y escribe el resultado. Simple, predecible, y el fallo de caché no rompe el sistema.

Write-through: se escribe simultáneamente en caché y en base de datos en cada operación de escritura. Garantiza consistencia pero añade latencia en escrituras. Adecuado cuando la consistencia importa más que la velocidad de escritura.

Qué cachear en aplicación

Candidatos claros:

  • Resultados de queries frecuentes y costosas (joins complejos, agregaciones).
  • Datos de configuración que cambian poco (tarifas, catálogos, traducciones).
  • Sesiones de usuario.
  • Resultados de llamadas a APIs externas con rate limiting.

No cachear:

  • Datos que deben ser siempre frescos (stock en tiempo real, saldos financieros).
  • Resultados de operaciones de escritura en curso.

4. Caché de base de datos

La mayoría de motores modernos tienen caché interna de queries o de buffers. Lo que puedes controlar desde aplicación:

  • Query result cache: el query_cache de MySQL está deprecado desde la versión 8.0. PostgreSQL no dispone de una caché de resultados de queries integrada comparable; la alternativa más común y portable es implementarlo a nivel de aplicación con Redis/Valkey.
  • Connection pooling: no es caché de datos, pero reduce la latencia de establecimiento de conexión. PgBouncer para PostgreSQL, ProxySQL para MySQL.
  • Read replicas: para workloads de lectura intensiva, distribuir entre réplicas reduce la carga en el primario y puede mejorar la latencia percibida en consultas.

La caché de aplicación (capa anterior) suele ser más eficaz que depender de la caché interna del motor, porque opera sobre datos ya procesados y con TTL explícito bajo tu control.


5. Decisiones clave: qué cachear, cuánto tiempo, cuándo invalidar

Cuánto tiempo cachear (TTL)

El TTL correcto depende de la tolerancia a datos desactualizados de tu negocio:

Tipo de datoTTL orientativo
Activos estáticos versionados1 año (con cache-busting por nombre)
Contenido editorial1–24 horas
Catálogos / configuración5–60 minutos
Resultados de API externaIgual que el Cache-Control del proveedor
Datos de sesión de usuarioDuración de la sesión
Stock / precios en tiempo realNo cachear, o TTL < 30 segundos con lógica de invalidación

Un TTL demasiado largo genera datos stale que confunden a los usuarios. Uno demasiado corto anula el beneficio del caché. El punto de equilibrio es la frecuencia real de actualización de esos datos, no una cifra arbitraria.

Estrategias de invalidación

La invalidación es la parte difícil. Tres patrones:

  1. Expiración por TTL: el más simple. El dato expira y se recarga en la siguiente petición. Suficiente para la mayoría de casos.
  2. Invalidación activa: cuando el dato cambia (un producto se actualiza, una página se edita), el sistema borra o actualiza la entrada de caché explícitamente. Requiere que la capa de escritura sepa qué claves invalidar.
  3. Cache versioning: en lugar de invalidar, las claves incluyen un identificador de versión. Cuando el dato cambia, se escribe con una nueva clave y se actualiza el puntero. Evita race conditions en entornos concurrentes.

Eviction policies

Cuando la caché se llena, el sistema decide qué descartar. En Redis/Valkey las políticas más relevantes:

  • allkeys-lru: descarta las claves menos usadas recientemente. Buena opción general.
  • volatile-lru: solo descarta claves con TTL configurado, respetando las que no tienen expiración.
  • allkeys-lfu: descarta las menos frecuentemente usadas. Mejor cuando el patrón de acceso es estable.

Configurar explícitamente la eviction policy evita comportamientos inesperados cuando la memoria se agota.


6. Impacto en costes: cómo calcularlo antes de implementar

El ROI del caching tiene dos vectores: reducción de egress y reducción de compute.

Reducción de egress (CDN)

ahorro_mensual = egress_total_TB × precio_GB_origen × CHR_objetivo

Ejemplo con AWS CloudFront: si sirves 5 TB/mes de activos desde S3 ($0.09/GB = $450/mes) y pasas a un CHR del 80%, el origin recibe 1 TB. El egress de origen baja a $90. CloudFront añade su propio coste de egress, pero la reducción neta es significativa.

Reducción de compute (caché de aplicación)

Cada cache hit es una query que no se ejecuta en base de datos. Si una query tarda 50ms en RDS y se ejecuta 10.000 veces al día, y el caché la sirve en 1ms, el ahorro en tiempo de CPU es medible. En un modelo serverless (Lambda, Cloud Functions), donde pagas por tiempo de ejecución, el ahorro se traduce directamente en factura.

Coste del servicio de caché

Para referencia de presupuesto: en AWS ElastiCache, una instancia Valkey cache.t4g.micro (0.5 GB) cuesta aproximadamente $12/mes. Las instancias reservadas ofrecen hasta un 40% de descuento sobre el precio on-demand.

El breakeven es rápido cuando el tráfico de la aplicación es significativo. Un nodo pequeño de Valkey puede absorber millones de peticiones al día y pagar su coste con el primer día de reducción de queries a la base de datos.


7. Observabilidad del caching

Un sistema de caché sin métricas es un sistema opaco. Lo mínimo a monitorizar:

  • Cache hit ratio por capa (CDN, aplicación, DB).
  • Latencia de caché (p50, p95, p99): si el caché está siendo más lento que la base de datos, algo falla.
  • Memoria usada vs. disponible: anticipa problemas de evicción antes de que ocurran.
  • Tasa de evicción: si es alta, el caché está demasiado lleno o el TTL es demasiado largo para el patrón de uso.
  • Errores de conexión: un fallo del servicio de caché no debería tumbar la aplicación. Implementa fallback explícito.

En AWS, CloudWatch expone métricas de ElastiCache sin configuración adicional. En GCP, Cloud Monitoring hace lo mismo con Memorystore. Si usas Redis/Valkey autoalojado, el comando INFO stats y INFO memory dan la información base; herramientas como Prometheus con el exporter oficial cubren el resto.

Este post es continuación natural de los posts sobre observabilidad en la nube y control de costes FinOps. La estrategia de caché es uno de los cambios de arquitectura con mayor impacto en ambas dimensiones: reduce la latencia que verás en tus dashboards de métricas y aparece como línea de ahorro inmediata en tu factura cloud.


Resumen de decisiones

DecisiónRecomendación práctica
Motor de caché en AWSValkey (motor por defecto en ElastiCache, 20% más barato que Redis)
Motor de caché en GCPValkey o Redis según compatibilidad requerida
Cuándo usar MemcachedSolo si necesitas simplidad operativa máxima y caching de strings sin estructuras complejas
TTL para activos estáticos versionados1 año + cache-busting por nombre de fichero
InvalidaciónTTL para la mayoría de casos; invalidación activa solo donde la consistencia es crítica
Eviction policyallkeys-lru como punto de partida
ObservabilidadCache hit ratio + latencia p95 + tasa de evicción como métricas mínimas

Si estás auditando la infraestructura de un proyecto y quieres saber dónde aplica una estrategia de caché y cuánto puede reducir la factura, escríbeme.