Módulo 5: Rollback And Incident Response
Presentación del módulo: frenaste la rampa. ¿Ahora qué?
Por qué existe este módulo
El módulo 3 diseñó la rampa completa de recommendations y la simuló: canary 1% avanzó limpio, pero rollout 10% se detuvo en HOLD cuando el guardrail de latencia volvió a romperse (p95Latency en 910ms, techo 800ms). El módulo 4 tomó ese mismo HOLD y lo convirtió en vigilancia real: un dashboard y una alerta que confirman, en vivo, que el guardrail sigue roto — y que la rampa no debe avanzar a 50% mientras eso sea cierto.
Los dos módulos anteriores, juntos, contestaron cuándo frenar. Ninguno de los dos contestó la pregunta que un equipo se hace en el segundo exacto en que la rampa se detiene: ¿y ahora qué hacemos? recommendations sigue expuesta al 10% de la base de Mercado — 25,000 compradores — con una latencia por encima del techo que la guía de métricas fijó. Alguien tiene que decidir, en minutos y no en días, si esos 25,000 compradores dejan de ver recommendations por completo, o si el equipo intenta arreglar el problema mientras la exposición se mantiene. Y esa decisión no puede improvisarse a las tres de la mañana — tiene que estar pensada de antemano.
Este módulo contesta exactamente eso: rollback e incident response. La promesa, resumida:
De "la rampa está frenada" a "revertimos o arreglamos hacia adelante, y respondimos al
incidente sin improvisar un solo paso".
El caso que retoma este módulo
Mismo Mercado, mismo incidente exacto que dejaron los módulos 3 y 4:
// Donde nos deja el modulo 4: el guardrail de latencia sigue roto en rollout 10%,
// confirmado por el dashboard de monitoreo. La rampa esta en HALT. Nadie decidio
// todavia que hacer con los 25,000 compradores ya expuestos.
const handoff = {
feature: 'recommendations',
stage: 'rollout 10%',
usersExposed: 25000,
guardrail: { name: 'p95Latency', value: 910, ceiling: 800, broken: true },
primaryMetric: { name: 'checkoutConversion', lift: 0.1875, win: true },
rampDecision: 'HALT', // de rolloutPlan() (M3) confirmado por guardrailWatch (M4)
};
console.log('=== estado del incidente al abrir este modulo ===\n');
console.log('feature=' + handoff.feature + ' stage=' + handoff.stage + ' usersExposed=' +
handoff.usersExposed.toLocaleString('en-US'));
console.log('guardrail: ' + handoff.guardrail.name + '=' + handoff.guardrail.value + 'ms (techo ' +
handoff.guardrail.ceiling + 'ms) -- roto=' + handoff.guardrail.broken);
console.log('primaryMetric: ' + handoff.primaryMetric.name + ' gana (+' + (handoff.primaryMetric.lift * 100) +
'%), pero eso NO decide nada por si solo');
console.log('rampDecision=' + handoff.rampDecision + ' -- la rampa esta detenida. Este modulo decide que sigue.');
Qué esperar. Al correr el archivo con Node, la salida es exactamente esta:
=== estado del incidente al abrir este modulo ===
feature=recommendations stage=rollout 10% usersExposed=25,000
guardrail: p95Latency=910ms (techo 800ms) -- roto=true
primaryMetric: checkoutConversion gana (+18.75%), pero eso NO decide nada por si solo
rampDecision=HALT -- la rampa esta detenida. Este modulo decide que sigue.
Fíjate en la última línea del código, antes de correrlo: primaryMetric.win es true, y aun así el comentario dice que "eso NO decide nada por si solo". Esa es, en una frase, la trampa que este módulo entero existe para evitar — la tentación de decir "pero el A/B ganó, sigamos" frente a un guardrail que sigue roto. El primario ganando y el guardrail roto son dos hechos independientes, y ninguno de los dos cancela al otro.
Una analogía: el trapecista y la red, no el Ctrl+Z... todavía
Vas a ver dos analogías compitiendo en las próximas lecciones, y vale la pena distinguirlas desde ahora. La primera es la que ya conoces del módulo 2: el kill switch como botón rojo, un solo movimiento que apaga todo. La segunda, que este módulo agrega, es la del trapecista y la red: la red no evita que el trapecista se resbale — evita que ese resbalón sea una caída al piso. El kill switch de recommendations es esa red: no evita que la latencia se rompa en el intento — pero evita que 25,000 personas sigan expuestas a esa latencia rota mientras el equipo decide qué hacer.
La pregunta que este módulo contesta, con esa red ya tendida y probada desde el módulo 2, no es "¿tenemos una red?" — ya la tienen. Es una pregunta distinta y más difícil: una vez que el trapecista cayó en la red, ¿se baja del trapecio por completo (rollback), o vuelve a subir con un ajuste rápido mientras la red sigue tendida (fix-forward)? Esa decisión, y todo lo que rodea responder bien a una emergencia en vivo, es el contenido completo de este módulo.
El mapa de las 8 lecciones de este módulo
Lección Pregunta que contesta
──────── ──────────────────────────────────────────────────────────
L1 (esta) ¿Dónde nos dejaron los módulos 3 y 4, y qué falta decidir?
L2 ¿Por qué el rollback es la red de seguridad, no el plan A automático?
L3 ¿Cuándo revertir por completo, y cuándo arreglar hacia adelante?
L4 ¿Qué es un runbook, y por qué evita improvisar en la crisis?
L5 ¿Por qué mitigar viene antes que diagnosticar la causa raíz?
L6 ¿Cómo se decide la severidad de un incidente, y a quién se despierta?
L7 ¿Cómo se mide qué tan rápido se respondió, y cómo se cierra el incidente?
L8 Proyecto: responde de punta a punta al incidente de recommendations
La lección 2 nombra el rollback como lo que es en esta guía —apagar el flag, no reescribir código— y muestra por qué es, casi siempre, la opción más rápida disponible. La lección 3 construye rollbackDecision(), el modelo que compara el costo de revertir contra el costo de arreglar hacia adelante, y lo corre sobre el caso real de recommendations. La lección 4 formaliza esa decisión en un runbook: los pasos exactos, escritos de antemano, que el equipo sigue sin pensar dos veces cuando el guardrail se rompe. La lección 5 da un paso atrás y nombra el principio que ordena toda respuesta a incidentes: mitigar primero, diagnosticar después — nunca al revés. La lección 6 clasifica el incidente por severidad y decide, con un modelo, quién se entera y cuándo. La lección 7 cierra el ciclo con el MTTR —cuánto tardó realmente la respuesta— y cómo se comunica el cierre. La lección 8, el proyecto, junta las tres piezas ejecutables del módulo —rollbackDecision, el runbook, y mttr— sobre el incidente real de recommendations.
La frontera: qué NO entra en este módulo
- El rollback de infraestructura —revertir un deploy atómico, volver a una versión anterior del build, el pipeline de CI/CD— es territorio de
fullstack-performance-and-deployment-guide, en el ecosistema Fullstack. Ese rollback ocurre a nivel de código en los servidores. El de este módulo ocurre a nivel de feature:recommendationsFlag.enabled = falseno toca el pipeline, no dispara un nuevo deploy, no necesita que nadie del equipo de infraestructura intervenga. Vas a ver la palabra "rollback" en las dos guías — en capas distintas. - Monitorear los guardrails durante la rampa —construir el dashboard, decidir cuándo frenar la subida— ya se resolvió en el módulo 4. Este módulo no repite esa vigilancia; asume que ya se detectó el problema, y empieza justo después: ¿qué se hace con lo que ya se detectó?
- El postmortem —la investigación completa de la causa raíz, sin culpar personas, con su timeline y sus action items— es el módulo 6, que sigue después de este. Este módulo se detiene en el momento en que el incidente se resuelve; qué se aprende de él, con qué profundidad, y cómo se documenta para que no vuelva a pasar, es una pregunta distinta que el módulo 6 contesta con su propio marco.
Errores comunes
Pensar que "ya tenemos el kill switch del módulo 2" significa que este módulo es innecesario. Qué pasa: alguien asume que, como recommendations ya tiene un mecanismo para apagarse al instante, no hace falta ningún proceso adicional — "cuando algo se rompe, lo apagamos y ya". Por qué pasa: el kill switch resuelve la parte mecánica (cómo apagar algo), y es fácil confundir eso con haber resuelto también la parte de juicio (cuándo apagarlo, quién lo decide, qué se hace después). Cómo detectarlo: si le preguntas al equipo "¿y quién decide si esto amerita rollback o fix-forward, y en cuánto tiempo?", y la respuesta es "lo vemos quien esté despierto en ese momento", el proceso no existe todavía, aunque el botón sí. Cómo corregirlo: como las siete lecciones que siguen van a mostrar, el mecanismo (kill switch) es una pieza — la decisión, el runbook, la severidad y la medición son piezas separadas que este módulo construye encima de esa pieza ya existente.
Tratar "el primario ganó" como un argumento a favor de no revertir. Qué pasa: frente a la propuesta de apagar recommendations, alguien objeta "pero está ganando +18.75% en conversión, ¿por qué la vamos a apagar?" — como si el resultado positivo del experimento compensara, de alguna forma, el guardrail roto. Por qué pasa: una cifra positiva grande se siente como una razón fuerte para seguir, y cuesta sostener dos verdades a la vez —"esto funciona" y "esto también está rompiendo algo que no debería romperse"—. Cómo detectarlo: si la conversación sobre revertir o no gira en torno al resultado del A/B en vez de en torno al estado del guardrail, la pregunta se está contestando mal. Cómo corregirlo: como la lección 3 va a formalizar con rollbackDecision(), la variable que dispara la decisión es si un guardrail crítico está roto — el resultado del primario no entra en ese cálculo en absoluto, y no debería.
Asumir que este módulo enseña a evitar incidentes. Qué pasa: alguien espera que este módulo tenga contenido sobre cómo escribir código sin bugs, o cómo diseñar sistemas más robustos, y se frustra al ver que el contenido es, en cambio, sobre qué hacer una vez que algo ya se rompió. Por qué pasa: "incident response" suena, para quien no lo conoció antes, a algo relacionado con prevención. Cómo detectarlo: si esperas encontrar consejos de arquitectura o testing en este módulo, no los vas a encontrar aquí. Cómo corregirlo: este módulo asume que un incidente ya está ocurriendo —el guardrail ya está roto, ya hay usuarios expuestos— y enseña exclusivamente la disciplina de responder bien a eso: rápido, sin improvisar, y sin empeorar las cosas en el camino.
Ejercicios
Ejercicio 1 — Distingue las dos preguntas. El módulo 4 contestó "¿el guardrail sigue roto en rollout 10%?" con un SÍ confirmado por el dashboard. Este módulo 5 contesta una pregunta distinta. Escríbela en una sola frase, usando tus propias palabras, antes de seguir a la lección 2.
Ver solución
Una formulación posible: "Dado que el guardrail está confirmado roto y la rampa está detenida, ¿revertimos recommendations por completo, o intentamos arreglar el problema mientras se mantiene la exposición actual — y cómo ejecutamos esa decisión sin improvisar en el momento?" La diferencia clave con la pregunta del módulo 4: ese módulo detecta y confirma que algo está mal; este módulo decide qué hacer con ese hallazgo, ya confirmado.
Ejercicio 2 — Ubica la frontera correcta. Para cada situación, di si corresponde a este módulo (5), al módulo 4, al módulo 6, o a la guía de Fullstack:
- (a) "El pipeline de CI/CD necesita revertir el build de producción a la versión de ayer."
- (b) "Confirmamos, con el dashboard en vivo, que el guardrail de latencia sigue roto a los 10 minutos de estar en rollout 10%."
- (c) "Decidimos apagar
recommendationscon el kill switch, y necesitamos escribir el reporte de la regresión sin culpar a nadie del equipo." - (d) "El guardrail está roto. ¿Apagamos el flag o parchamos el query lento en caliente?"
Ver solución
- (a) Fullstack —
fullstack-performance-and-deployment-guide, el rollback de infraestructura. - (b) Módulo 4 — monitorear el lanzamiento y confirmar el guardrail en vivo.
- (c) Módulo 6 — el postmortem blameless.
- (d) Este módulo, módulo 5 — exactamente la decisión de
rollbackDecision()que construye la lección 3.
Ejercicio 3 — Predicción con criterio. Sin haber leído todavía la lección 3, y sabiendo que recommendations tiene un kill switch que apaga la exposición en cuestión de minutos (módulo 2), ¿qué te parece más razonable frente al guardrail de latencia roto: revertir de inmediato, o mantener la exposición mientras alguien investiga la causa? Justifica en 2-3 frases, sin usar todavía el vocabulario formal de "rollback" ni "fix-forward".
Ver solución
No hay una respuesta "correcta" sin conocer el costo real de cada opción —eso es exactamente lo que rollbackDecision() va a formalizar en la lección 3—, pero el argumento a favor de revertir de inmediato es fuerte precisamente porque el costo de hacerlo es bajísimo: apagar el kill switch toma minutos y no requiere ningún trabajo adicional. Mantener la exposición mientras se investiga solo tiene sentido si arreglar el problema en caliente fuera igual de rápido o más seguro que apagar — y en este caso, con una latencia ya confirmada rota y afectando a 25,000 personas, no hay ninguna razón todavía para pensar que investigar con la exposición activa sea más rápido que simplemente cortarla primero.
Resumen y siguiente paso
En esta lección retomaste el incidente exacto donde lo dejaron los módulos 3 y 4: recommendations, detenida en rollout 10%, con el guardrail de latencia confirmado roto (910ms, techo 800ms) y 25,000 compradores ya expuestos. Viste el mapa completo de las ocho lecciones de este módulo y la frontera con sus vecinos —el rollback de infraestructura queda en Fullstack, el postmortem queda en el módulo 6—, y nombraste el error central que este módulo previene: dejar que el resultado positivo del experimento influya en una decisión que solo debería depender del estado del guardrail.
Antes de avanzar deberías poder: explicar, en tus propias palabras, por qué "el A/B ganó" y "el guardrail sigue roto" son dos hechos independientes; y ubicar, a grandes rasgos, qué lecciones de este módulo resuelven qué parte de la respuesta al incidente.
La lección 2 empieza por la pieza más simple y ya construida: el rollback como red de seguridad, apoyado en el kill switch del módulo 2 — por qué revertir, en esta guía, casi siempre significa "apagar un booleano", y por qué eso importa tanto.
Recursos
- Google SRE Book, Capítulo 15, "Postmortem Culture: Learning from Failure" — sre.google/sre-book/postmortem-culture. Aunque el postmortem en profundidad es el módulo 6, este capítulo aclara la frontera desde el principio: distingue la respuesta inmediata a un incidente (este módulo) del aprendizaje posterior (el siguiente). En inglés.
- Charity Majors, "Deploys Are the WRONG Way to Change User Experience" — honeycomb.io/blog/deploys-wrong-way-change-user-experience. El argumento de fondo detrás de por qué el rollback de este módulo (un flag) es una operación distinta, y mucho más rápida, que el rollback de infraestructura. En inglés.
- PagerDuty Incident Response Documentation — response.pagerduty.com. La referencia completa de la industria sobre cómo estructurar la respuesta a un incidente, desde la detección hasta el cierre — el mapa que las próximas siete lecciones de este módulo van a recorrer, pieza por pieza. En inglés.