🧪 Problem-Driven Systems Lab

🗺️ Contexto#

Una clave de cache caliente expira y, en ese instante, todos los requests que la estaban usando encuentran el hueco a la vez. Ninguno sabe que los otros existen, así que todos van al origen.

Justificación#

Es el fallo que más se parece a una denegación de servicio hecha por uno mismo. El sistema funciona perfecto durante horas y cae en el segundo exacto en que la cache deja de proteger a la base — normalmente de madrugada, cuando un TTL fijo puesto en un deploy hace seis meses vence para mil claves al mismo tiempo.

Lo que lo vuelve difícil de diagnosticar es que la cache estaba haciendo su trabajo. El hit rate del dashboard dice 99%. Lo que el dashboard no muestra es cuántos recálculos simultáneos recibe el origen en el 1% restante.

📇 Ficha del caso#

CategoríaRendimiento
EstadoOPERATIVO
Stacks operativos7 de 7

Cuando la clave caliente expira, los N llamadores concurrentes recalculan el mismo valor y el origen recibe la ráfaga entera.

🧱 Dónde correrlo#

StackVersiónURL en el hubImplementación
🐘 PHPPHP 8.3http://localhost:8100/13/README
🐍 PythonPython 3.12http://localhost:8200/13/README
🟢 Node.jsNode.js 22http://localhost:8300/13/README
☕ JavaJava 21http://localhost:8400/13/README
🔵 .NET.NET 8http://localhost:8500/13/README
🐹 GoGo 1.23http://localhost:8600/13/README
🦀 RustRust 1.83http://localhost:8700/13/README

⚠️ Nota de honestidad del caso: el origen es CPU real (un digest iterativo), no una consulta a una base de datos ni un sleep. Lo que se mide con fidelidad es origin_computations — cuántas veces se ejecuta el trabajo caro. La latencia absoluta en milisegundos depende del runtime y no es comparable entre stacks.


Caso 13 · Cache stampede y thundering herd⬅️ README del caso · ⚖️ Comparativa de los 7 stacks

🗺️ Contexto · 🩺 Síntomas · 🔍 Diagnóstico · 🧠 Causas raíz · 🛠️ Opciones de solución · ⚖️ Trade-offs · 💼 Valor de negocio · 🚨 Postmortem

Ver esta carpeta en GitHub ↗