# Patrones de caché con Redis: cache-aside, TTL e invalidación

**Categoría:** Bases de datos · **Nivel:** Avanzado · **Lectura:** 20 min
**Publicada:** 2026-07-28 · **Actualizada:** 2026-07-28 · **Autoría:** Underc0de
**Versión HTML (canónica):** https://underc0de.org/guias/bases-de-datos/patrones-de-cache-con-redis-cache-aside-ttl-e-invalidacion/

## Respuesta rápida

Saber [qué es Redis](../bases-de-datos-en-memoria-y-cache-con-redis/index.md) —una base de datos en memoria, rapidísima— es el primer paso; usarlo *bien* para **cachear** es otra habilidad, y depende de los **patrones**. El patrón de caché más común es **cache-aside** (caché «al lado»): cuando la aplicación necesita un dato, **primero mira en la caché** (Redis); si está (*acierto* o *hit*), lo devuelve al instante; si no está (*fallo* o *miss*), va a la **base de datos** real, obtiene el dato, lo **guarda en la caché** para la próxima vez, y lo devuelve. Así, las lecturas repetidas del mismo dato se sirven desde la memoria (rapidísimo) en vez de golpear la base de datos una y otra vez. El problema evidente: ¿y si el dato **cambia** en la base de datos? La copia en la caché queda **obsoleta**, y la aplicación serviría datos viejos. Hay dos herramientas para manejar esto. La primera, y la más simple, es el **TTL** (*time to live*, «tiempo de vida»): al guardar un dato en la caché, se le pone una **caducidad automática** —«esto vale 5 minutos»—, tras la cual Redis lo **borra solo**, forzando que la próxima lectura vaya a la base y traiga el dato fresco. El TTL acota el tiempo máximo que un dato puede estar desactualizado, sin necesidad de hacer nada. La segunda, más precisa pero más difícil, es la **invalidación**: cuando un dato cambia en la base de datos, **borrar (o actualizar) su copia en la caché** de forma explícita, para que la próxima lectura la refresque de inmediato. La invalidación da datos siempre frescos, pero es **notoriamente difícil** de hacer bien —hay un famoso chiste que dice que «las dos cosas difíciles de la informática son invalidar la caché y nombrar variables»—, porque hay que acordarse de invalidar *en todos los sitios* donde el dato puede cambiar, y es fácil olvidar uno y servir datos viejos. La estrategia práctica combina ambas: **TTL como red de seguridad** (que garantiza frescura eventual aunque falle la invalidación) más **invalidación** donde la frescura inmediata importe. Y la regla de fondo: **cachear lo que se lee mucho y cambia poco**, y aceptar que **toda caché implica un compromiso entre velocidad y frescura**.

## El patrón cache-aside

Esta guía da por sabido [qué es Redis](../bases-de-datos-en-memoria-y-cache-con-redis/index.md) —una base de datos en memoria extremadamente rápida— y se centra en *cómo usarlo* para cachear, que es una cuestión de **patrones**. El patrón fundamental es **cache-aside**, que en español sería «caché al lado»: la caché se coloca *junto a* la base de datos, y la aplicación la consulta primero. El flujo es el corazón de casi toda estrategia de caché, así que conviene tenerlo claro.

> **Acierto y fallo: mirar la caché primero**
>
> El patrón cache-aside funciona con una lógica simple de **«mirar primero, ir a la base si falta»**. Cuando la aplicación necesita un dato: **(1)** mira en la **caché** (Redis). **(2)** Si el dato **está** —lo que se llama un **acierto** (*cache hit*)—, lo devuelve directamente desde la memoria, en microsegundos, sin tocar la base de datos. **(3)** Si el dato **no está** —un **fallo** (*cache miss*)—, la aplicación va a la **base de datos real**, obtiene el dato, lo **guarda en la caché** (para que la próxima vez sea un acierto), y lo devuelve. La ganancia viene de la **proporción de aciertos**: si un dato se lee muchas veces pero cambia poco, la primera lectura es un fallo (lenta, va a la base) pero *todas las siguientes* son aciertos (rapidísimas, desde la memoria). En una aplicación con muchas lecturas repetidas, esto **descarga enormemente la base de datos** y acelera las respuestas. La clave del rendimiento de una caché es maximizar los aciertos, y por eso importa tanto *qué* se cachea (lo que se lee mucho) y *cuánto tiempo* se conserva.

## TTL e invalidación

El punto delicado de toda caché es qué pasa cuando el dato **cambia**. Las dos herramientas, comparadas:

| Herramienta | Cómo funciona | Ventaja / límite |
|---|---|---|
| TTL (caducidad) | El dato caduca solo tras un tiempo y se borra | Simple y automático; permite datos viejos hasta que caduca |
| Invalidación | Se borra la copia en la caché al cambiar el dato | Datos siempre frescos; difícil de hacer bien |

> **Atención**
>
> Hay un chiste célebre entre programadores: «solo hay dos cosas difíciles en informática: invalidar la caché y nombrar variables». Tiene mucho de verdad. El **TTL** es la parte fácil: le ponés al dato una **caducidad** («esto vale 5 minutos») y Redis lo **borra solo** al vencer, así que la próxima lectura va a la base y trae el dato fresco. El TTL es simple, automático y no requiere que la aplicación haga nada especial —su único precio es que un dato puede estar desactualizado **hasta** que caduque (como mucho, esos 5 minutos)—. La **invalidación** es la parte difícil: consiste en **borrar la copia en la caché en el momento exacto** en que el dato cambia en la base, para que la caché nunca sirva algo viejo. Suena simple, pero es un campo minado: hay que **acordarse de invalidar en todos los lugares** donde ese dato puede cambiar —cada punto del código que lo modifica, y también cambios que vengan de *otras* aplicaciones o de scripts—, y basta **olvidar uno** para que la caché sirva datos obsoletos sin que nadie lo note. Por eso invalidar bien es tan difícil. La **estrategia práctica** combina lo mejor de ambas: usar **TTL como red de seguridad** —aunque falle una invalidación, el dato caducará y se refrescará solo, acotando el daño— e **invalidar explícitamente** allí donde la frescura inmediata sea importante. Así se obtiene frescura razonable con robustez: si la invalidación acierta, el dato se refresca al instante; si se olvida, el TTL lo salva.

## Cuándo cachear

Una caché no es gratis: añade complejidad y el riesgo de servir datos viejos. Por eso hay que cachear con criterio. Qué se beneficia y qué no:

| Buen candidato a caché | Mal candidato |
|---|---|
| Datos que se leen mucho y cambian poco | Datos que cambian constantemente |
| Consultas caras que se repiten | Datos que se leen una sola vez |
| Información donde un pequeño retraso es tolerable | Datos donde la frescura al instante es crítica (p. ej. un saldo) |

> **Atención**
>
> La decisión de cachear siempre implica un **compromiso entre velocidad y frescura**. La caché da **velocidad** (sirve desde la memoria), pero a costa de que los datos puedan estar **algo desactualizados** respecto a la base de datos real. Por eso el candidato ideal para cachear es el dato que se **lee mucho** (para que la caché aporte muchos aciertos) y **cambia poco** (para que la desactualización sea rara y breve): el catálogo de productos, la configuración, un perfil que casi nunca cambia. En cambio, cachear datos que **cambian constantemente** da pocos aciertos y muchos problemas de frescura —no vale la pena—; y cachear datos donde la **frescura es crítica** —un saldo bancario, un stock que decide una venta— es peligroso, porque servir un valor viejo puede causar un error real. Una advertencia importante: antes de meter una caché, conviene comprobar si el problema de rendimiento se puede resolver de forma más simple, por ejemplo con un buen [índice](../indices-en-bases-de-datos-como-aceleran-las-consultas/index.md) que haga la consulta rápida sin necesidad de cachear, o con un [pool de conexiones](../pool-de-conexiones-en-bases-de-datos/index.md) bien dimensionado. La caché es potente, pero añade una pieza más que puede fallar y servir datos viejos, así que se usa cuando de verdad aporta —lecturas masivas de datos estables— y no como primera respuesta a cualquier lentitud.

## Errores frecuentes

- **Cachear datos que cambian constantemente.** Pocos aciertos y muchos problemas de frescura; no compensa.
- **Confiar solo en la invalidación sin TTL.** Si se olvida invalidar en un sitio, se sirven datos viejos indefinidamente; el TTL es la red de seguridad.
- **Poner TTL demasiado largos en datos que importan.** Amplían la ventana en la que se sirve información obsoleta.
- **Cachear datos donde la frescura es crítica.** Un saldo o un stock viejo puede causar un error real.
- **Meter una caché para tapar una consulta lenta.** A veces un índice resuelve el problema sin la complejidad de cachear.
- **Olvidar invalidar cuando el dato cambia desde otra aplicación.** La invalidación debe cubrir todos los orígenes del cambio.
- **No medir la proporción de aciertos.** Una caché con pocos aciertos añade complejidad sin apenas beneficio.

## Preguntas frecuentes

**¿Qué es el patrón cache-aside?**
El patrón cache-aside, que en español se puede traducir como caché al lado, es el patrón de uso de caché más común, y consiste en que la aplicación consulta primero la caché cuando necesita un dato, y solo va a la base de datos real si el dato no está en la caché, guardándolo entonces en ella para las próximas veces. Su nombre alude a que la caché se coloca al lado de la base de datos, y es la aplicación la que la gestiona consultándola primero. El flujo del patrón funciona con una lógica de mirar primero la caché e ir a la base de datos solo si falta el dato. Cuando la aplicación necesita un dato, primero lo busca en la caché, que en este contexto suele ser una base de datos en memoria muy rápida. Si el dato está en la caché, situación que se denomina acierto, la aplicación lo devuelve directamente desde la memoria de forma casi instantánea, sin necesidad de acceder a la base de datos, lo que es muy rápido. Si el dato no está en la caché, situación que se denomina fallo, la aplicación acude a la base de datos real, obtiene de ella el dato, lo guarda en la caché para que la próxima vez que se solicite ya esté disponible y sea un acierto, y finalmente lo devuelve. La ganancia de rendimiento de este patrón proviene de la proporción de aciertos que se consigue. Si un dato se lee muchas veces pero cambia poco, la primera lectura será un fallo, más lenta porque hay que ir a la base de datos, pero todas las lecturas siguientes serán aciertos, muy rápidas porque se sirven desde la memoria. En una aplicación con muchas lecturas repetidas de los mismos datos, esto descarga enormemente la base de datos, que deja de recibir esas consultas repetidas, y acelera notablemente las respuestas a los usuarios. Por ello, la clave del rendimiento de una caché es maximizar la proporción de aciertos, lo que depende de cachear los datos adecuados, es decir, los que se leen mucho, y de conservarlos el tiempo apropiado. El patrón cache-aside es la base de casi toda estrategia de caché, pero plantea el problema de qué hacer cuando el dato cambia en la base de datos y la copia en la caché queda obsoleta, para lo cual se emplean el tiempo de vida y la invalidación.

**¿Qué es el TTL o tiempo de vida de la caché?**
El tiempo de vida, conocido en inglés como TTL, es una caducidad automática que se asigna a un dato al guardarlo en la caché, de modo que transcurrido ese tiempo la caché lo borra por sí sola, forzando que la próxima lectura de ese dato vaya a la base de datos y traiga una versión fresca. Es la herramienta más simple para manejar el problema de la obsolescencia de los datos en la caché, que surge porque, una vez que un dato se ha copiado en la caché, si ese dato cambia en la base de datos real, la copia de la caché queda desactualizada y la aplicación podría servir datos viejos. El tiempo de vida aborda este problema estableciendo un límite temporal a la validez de cada dato cacheado. Al guardar un dato en la caché, se le asigna un tiempo de vida, por ejemplo unos minutos, que representa cuánto tiempo se considera válido. Mientras no expire ese tiempo, las lecturas del dato se sirven desde la caché de forma rápida. Cuando el tiempo de vida expira, la caché elimina automáticamente el dato, sin que la aplicación tenga que hacer nada, de modo que la siguiente vez que se solicite, al no estar ya en la caché, se producirá un fallo y la aplicación irá a la base de datos, obtendrá la versión actual y actualizada del dato, y la guardará de nuevo en la caché con un nuevo tiempo de vida. La gran ventaja del tiempo de vida es su simplicidad y su automatismo, ya que no requiere que la aplicación se encargue activamente de refrescar los datos, sino que la propia caché los caduca sola, garantizando que ningún dato permanezca desactualizado indefinidamente. Su límite es que, entre el momento en que un dato cambia en la base de datos y el momento en que caduca en la caché, la aplicación puede seguir sirviendo la versión antigua, por lo que un dato puede estar desactualizado durante un tiempo máximo igual a su tiempo de vida. Por ello, la elección de la duración del tiempo de vida es un compromiso: un tiempo corto reduce la ventana de posible obsolescencia pero disminuye la proporción de aciertos, al caducar los datos más a menudo, mientras que un tiempo largo mejora los aciertos pero amplía la ventana en la que se pueden servir datos viejos. El tiempo de vida se suele combinar con la invalidación explícita, actuando como una red de seguridad que garantiza la frescura eventual de los datos aunque falle la invalidación.

**¿Qué es la invalidación de la caché y por qué es difícil?**
La invalidación de la caché consiste en borrar o actualizar de forma explícita la copia de un dato en la caché en el momento en que ese dato cambia en la base de datos, para que la caché no sirva una versión obsoleta, y es difícil porque hay que acordarse de invalidar en todos los lugares donde el dato puede cambiar, y olvidar uno solo hace que se sirvan datos viejos sin que nadie lo note. Mientras que el tiempo de vida deja que los datos caduquen solos tras un plazo, la invalidación busca una frescura más inmediata y precisa, actuando en el instante mismo del cambio. La idea es que, cuando la aplicación modifica un dato en la base de datos, además de hacer ese cambio, borre o actualice la copia de ese dato en la caché, de modo que la próxima lectura, al no encontrarlo en la caché o encontrarlo ya actualizado, refleje la versión más reciente de inmediato, sin tener que esperar a que caduque. La ventaja de la invalidación es que proporciona datos siempre frescos, eliminando la ventana de obsolescencia que tiene el tiempo de vida. Sin embargo, la invalidación es notoriamente difícil de hacer bien, hasta el punto de que existe un chiste célebre entre programadores según el cual las dos cosas difíciles de la informática son invalidar la caché y nombrar bien las variables. La dificultad radica en que, para que la invalidación funcione correctamente, hay que acordarse de invalidar la copia en la caché en todos y cada uno de los lugares donde el dato puede cambiar. Esto incluye cada punto del código de la aplicación que modifica ese dato, que pueden ser muchos y estar dispersos, pero también los cambios que puedan provenir de otras aplicaciones que accedan a la misma base de datos, o de scripts de mantenimiento, o de modificaciones manuales. Si se olvida invalidar en uno solo de esos lugares, la caché seguirá sirviendo la versión antigua del dato después de que este haya cambiado, y lo peor es que este problema pasa desapercibido, ya que la aplicación funciona con normalidad pero muestra datos incorrectos, lo que puede ser muy difícil de detectar y diagnosticar. Por esta dificultad, la estrategia práctica recomendada es combinar la invalidación con el tiempo de vida, usando el tiempo de vida como red de seguridad, de modo que aunque se olvide invalidar en algún lugar, el dato acabará caducando y refrescándose por sí solo, acotando así el daño de un fallo en la invalidación, mientras que la invalidación explícita se aplica allí donde la frescura inmediata es importante.

**¿Cómo evito servir datos obsoletos desde la caché?**
Para evitar servir datos obsoletos desde la caché, la estrategia práctica más robusta consiste en combinar las dos herramientas disponibles, usando el tiempo de vida como red de seguridad que garantiza que ningún dato quede desactualizado indefinidamente, junto con la invalidación explícita allí donde la frescura inmediata sea importante. El problema de los datos obsoletos surge porque, cuando un dato se copia en la caché y luego cambia en la base de datos, la copia de la caché queda desactualizada, y si la aplicación sigue sirviéndola, mostrará información incorrecta. Las dos herramientas para manejar esto tienen fortalezas y debilidades complementarias, y por eso conviene combinarlas. El tiempo de vida es simple y automático, ya que caduca los datos por sí solo tras un plazo, garantizando que ningún dato permanezca desactualizado más allá de ese plazo, pero tiene el límite de que un dato puede estar obsoleto hasta que caduca. La invalidación es precisa, ya que refresca el dato en el momento exacto del cambio, pero es difícil de hacer bien y, si se olvida invalidar en algún lugar, sirve datos viejos sin que nadie lo note. La estrategia combinada aprovecha lo mejor de ambas. Por un lado, se aplica un tiempo de vida a los datos cacheados, de modo que aunque la invalidación falle en algún punto, el dato acabará caducando y refrescándose solo, lo que acota el tiempo máximo durante el cual se puede servir un dato obsoleto y actúa como una red de seguridad frente a los olvidos de la invalidación. Por otro lado, se implementa la invalidación explícita en los lugares donde la frescura inmediata es importante, de manera que cuando esos datos cambian, su copia en la caché se borra o actualiza al instante, ofreciendo datos frescos de inmediato. De este modo, si la invalidación acierta, el dato se refresca al momento, y si se olvida en algún sitio, el tiempo de vida lo salva al caducarlo, obteniéndose así una frescura razonable con robustez. Además de esta estrategia combinada, es importante elegir bien qué datos se cachean, prefiriendo los que cambian poco, para que el problema de la obsolescencia sea poco frecuente, y ajustar la duración del tiempo de vida según la importancia de la frescura de cada dato, usando tiempos más cortos para los datos cuya obsolescencia sea más problemática. También es fundamental asegurarse de que la invalidación cubra todos los orígenes posibles del cambio, incluidos los que provengan de otras aplicaciones o de procesos externos, para no dejar vías por las que el dato cambie sin que la caché se entere. Con estas medidas se minimiza eficazmente el riesgo de servir datos obsoletos.

**¿Qué datos conviene cachear y cuáles no?**
Conviene cachear los datos que se leen mucho y cambian poco, así como las consultas caras que se repiten, mientras que no conviene cachear los datos que cambian constantemente, los que se leen una sola vez, ni aquellos en los que la frescura al instante es crítica. La decisión de cachear siempre implica un compromiso entre velocidad y frescura, ya que la caché aporta velocidad al servir los datos desde la memoria, pero a costa de que esos datos puedan estar algo desactualizados respecto a la base de datos real. Por ello, la elección de qué cachear debe tener en cuenta este compromiso. Los buenos candidatos para cachear son, en primer lugar, los datos que se leen mucho, ya que solo si un dato se solicita repetidamente la caché aporta muchos aciertos y, por tanto, un beneficio real de rendimiento. En segundo lugar, los datos que cambian poco, ya que así la desactualización de la copia cacheada es un evento raro y breve, minimizando el problema de la obsolescencia. Ejemplos típicos de buenos candidatos son el catálogo de productos de una tienda, la configuración de la aplicación, o un perfil que casi nunca cambia, que se leen constantemente pero se modifican con poca frecuencia. También son buenos candidatos las consultas costosas que se repiten, ya que cachear su resultado evita repetir un cálculo o una consulta pesada muchas veces. Por el contrario, los malos candidatos son varios. Los datos que cambian constantemente no conviene cachearlos, ya que la caché quedaría obsoleta enseguida, aportando pocos aciertos útiles y muchos problemas de frescura, de modo que no compensa. Los datos que se leen una sola vez tampoco, ya que la caché solo aporta beneficio con las lecturas repetidas, y cachear algo que no se va a volver a leer no sirve de nada. Y muy especialmente, los datos en los que la frescura al instante es crítica no deben cachearse, o deben hacerlo con extremo cuidado, ya que servir una versión obsoleta podría causar un error real; ejemplos de ello son un saldo bancario o un stock que decide si se puede realizar una venta, donde mostrar un valor viejo tendría consecuencias graves. Además, antes de introducir una caché conviene valorar si el problema de rendimiento se puede resolver de forma más simple, por ejemplo mediante un índice adecuado que acelere la consulta sin necesidad de cachear, ya que la caché añade complejidad y una pieza más que puede fallar. En resumen, se cachea con criterio, reservando la caché para las lecturas masivas de datos estables donde de verdad aporta, y evitándola donde no compensa o donde la frescura inmediata es imprescindible.

**¿Esta guía es lo mismo que la de qué es Redis?**
No, esta guía no es lo mismo que la de qué es Redis, sino que la complementa y la da por supuesta, ya que aquella explica qué es Redis y por qué es tan rápido como base de datos en memoria, mientras que esta se centra en cómo usarlo bien en la práctica para cachear, mediante los patrones de caché. La guía sobre qué es Redis aborda los fundamentos, explicando que Redis es una base de datos en memoria, es decir, que guarda los datos en la memoria en lugar de en el disco, lo que la hace extremadamente rápida, y describe sus características, sus usos generales, incluida la caché como uno de ellos, y por qué su naturaleza en memoria le confiere esa gran velocidad. Es, por tanto, un conocimiento fundamental sobre la herramienta y sus capacidades. Esta guía, en cambio, parte de que ya se sabe qué es Redis y qué lo hace rápido, y se ocupa de una habilidad distinta y de nivel más aplicado, que es cómo usarlo correctamente para cachear, lo cual depende de dominar los patrones de caché. Aborda cuestiones prácticas que no son sobre la herramienta en sí, sino sobre cómo aplicarla, como el patrón cache-aside que define cómo leer los datos consultando primero la caché, el uso del tiempo de vida para caducar los datos automáticamente, el problema de la invalidación para mantener los datos frescos cuando cambian, y el criterio para decidir qué conviene cachear y qué no. Estos aspectos determinan la diferencia entre una caché que acelera realmente la aplicación y una que sirve datos obsoletos o que añade complejidad sin apenas beneficio. La relación entre ambas guías es, por tanto, de complementariedad y de progresión: primero conviene entender qué es Redis y por qué es rápido, que es lo que explica la guía de fundamentos, y después aprender a usarlo bien para cachear, que es lo que enseña esta guía de patrones. Quien no conozca todavía qué es Redis debería empezar por los fundamentos, ya que son la base necesaria para comprender el contexto en el que se aplican estos patrones, mientras que quien ya sepa qué es Redis y qué lo hace rápido encontrará aquí las claves para pasar de conocer la herramienta a usarla eficazmente como caché, evitando los errores habituales relacionados con la obsolescencia de los datos y con cachear lo que no se debe. En conjunto, ambas guías cubren tanto el qué y el porqué de Redis como el cómo usarlo bien para cachear.

## Fuentes

Documentación oficial y material de la comunidad consultados para esta guía. Fecha de consulta: 28 de julio de 2026.

### Aportes de la comunidad Underc0de

1. **Underc0de, foro.** [Bases de datos](https://underc0de.org/foro/bases-de-datos/). Caché y rendimiento.
2. **Underc0de, blog.** [Blog de Underc0de](https://blog.underc0de.org/). Arquitectura de aplicaciones.

### Documentación oficial

1. **Redis.** [Redis Documentation](https://redis.io/docs/). Caché y estructuras de datos.
2. **Redis.** [Key expiration (TTL)](https://redis.io/docs/latest/develop/use/keyspace/#key-expiration). Caducidad de claves.
3. **AWS.** [Caching Best Practices](https://aws.amazon.com/caching/best-practices/). Estrategias de caché.
4. **Microsoft.** [Cache-Aside pattern](https://learn.microsoft.com/azure/architecture/patterns/cache-aside). El patrón cache-aside.

## Guías relacionadas

- [Bases de datos en memoria y Redis](../bases-de-datos-en-memoria-y-cache-con-redis/index.md)
- [Índices](../indices-en-bases-de-datos-como-aceleran-las-consultas/index.md)
- [Pool de conexiones](../pool-de-conexiones-en-bases-de-datos/index.md)
- [Relacional vs no relacional](../relacional-vs-no-relacional/index.md)
- [Índice de Bases de datos](../index.md)
