Módulo 3: Gradual Rollout
Presentación del módulo: de tener el flag a subir por una rampa
Por qué este módulo
El módulo 2 te dejó con una herramienta concreta: el feature flag. Con isEnabled(user, flag) puedes decidir, usuario por usuario, quién ve recommendations en este momento — y con el kill switch puedes apagarla al instante si algo sale mal, sin esperar un nuevo deploy. Es una herramienta poderosa, y resuelve un problema real: separar el código en producción del código visible. Pero resuelve solo la mitad del problema.
La otra mitad es esta: un flag, por sí solo, no te dice qué porcentaje usar, en qué orden, ni cuándo cambiarlo. Podrías tener el flag más sofisticado del mundo y aun así usarlo mal — configurar rolloutPercent: 1.0 el primer día, porque "ya tenemos el flag, para qué esperar". El flag te da el interruptor. No te da el plan de cuándo moverlo. Ese plan — la rampa: 1% → 10% → 50% → 100%, con una razón explícita para pasar de una etapa a la siguiente — es exactamente lo que construye este módulo.
Módulo 2 (ya recorrido) Módulo 3 (aquí)
────────────────────── ─────────────────────────────
¿Puedo prender/apagar POR USUARIO? → ¿En qué ORDEN subo el porcentaje?
isEnabled, killSwitch la rampa: canary, criterios, rings
un flag con un número fijo ese número cambiando con evidencia
Una analogía: entrar al mar caminando, no de un clavado
Cuando alguien entra al mar por primera vez en el día, casi nadie se avienta de cabeza sin más. Primero mete los tobillos — el agua está fría, o no tanto, y ya sabe algo que no sabía en la arena. Después avanza hasta las rodillas: si hay una corriente rara o el fondo cambia de golpe, todavía puede dar la vuelta sin haber arriesgado nada serio. Después la cintura. Recién ahí, con toda esa información acumulada, decide si nadar de verdad. El clavado de cabeza no es más valiente — es simplemente saltarse toda la información que los tobillos, las rodillas y la cintura ya te habrían dado, gratis, antes del momento en que de verdad importa.
Un rollout gradual es exactamente esa secuencia, aplicada a recommendations: el canary al 1% son los tobillos — casi nada en juego, pero ya te dice algo real—. El 10% son las rodillas. El 50% es la cintura. El 100% es nadar mar adentro, y para cuando llegas ahí ya sabes, con evidencia acumulada en cada paso anterior, que el agua se porta como esperabas. La alternativa — lanzar al 100% el primer día — es el clavado de cabeza: no es más rápido de forma útil, es simplemente renunciar a toda la información que las etapas intermedias te iban a dar antes de que el error, si existe, le llegue a todo el mundo a la vez.
Ejemplo trabajado: dónde termina el módulo 2 y dónde empieza el 3
Antes del primer concepto nuevo, dejemos clara la frontera exacta entre lo que el flag ya resuelve y lo que falta:
// Recordatorio de por donde nos dejo el modulo 2: un feature flag que decide, con
// isEnabled(user, flag), si un usuario ve recommendations SEGUN el rolloutPercent
// que el flag tiene configurado en este momento. El modulo 2 resolvio el "on/off
// por usuario" -- lo que NO resolvio es COMO y CUANDO ese rolloutPercent cambia.
const flagToday = { name: 'recommendations', rolloutPercent: 0.01, killSwitch: false };
console.log('=== Donde nos dejo el modulo 2 ===\n');
console.log('Flag "' + flagToday.name + '": rolloutPercent=' + (flagToday.rolloutPercent * 100) + '%, killSwitch=' + flagToday.killSwitch);
console.log('\nisEnabled(user, flag) ya decide, usuario por usuario, quien ve la feature HOY.');
console.log('Pregunta que el modulo 2 deja abierta: manana, la semana que viene, ese');
console.log('rolloutPercent (1%) sube a 10%? a 50%? cuando exactamente, y con que');
console.log('criterio? Esa es la pregunta completa que resuelve este modulo.');
Qué esperar. Al correr el archivo con Node, la salida es exactamente esta:
=== Donde nos dejo el modulo 2 ===
Flag "recommendations": rolloutPercent=1%, killSwitch=false
isEnabled(user, flag) ya decide, usuario por usuario, quien ve la feature HOY.
Pregunta que el modulo 2 deja abierta: manana, la semana que viene, ese
rolloutPercent (1%) sube a 10%? a 50%? cuando exactamente, y con que
criterio? Esa es la pregunta completa que resuelve este modulo.
Fíjate en el número rolloutPercent: 0.01 en el objeto flagToday. Es solo un número — el flag lo aplica con total obediencia, sin preguntar si 1% es el valor correcto para hoy o si ya deberías estar en 10%. Ese número tiene que venir de algún lado, y cambiar de algún lado, con alguna razón. Este módulo entero es esa fuente: la rampa completa, la razón para moverse de una etapa a la siguiente, y quién ve la feature primero en cada una.
El mapa de este módulo
Ocho lecciones, cada una agregando la pieza siguiente de la rampa:
Lección Pregunta que contesta
──────── ──────────────────────────────────────────────────────────
L1 (esta) ¿Qué agrega este módulo sobre el flag del módulo 2?
L2 ¿Cómo es la rampa completa, de canary a 100%?
L3 ¿Por qué empezar tan chico — y cuándo "chico" deja de dar señal?
L4 ¿Qué hace, en concreto, que una etapa "avance"?
L5 ¿Cuánta gente real queda expuesta en cada etapa de la rampa?
L6 ¿Quién ve la feature primero, más allá del porcentaje?
L7 ¿Cuánto hay que esperar en cada etapa antes de mirar los datos?
L8 Proyecto: diseña y simula la rampa completa de recommendations
La lección 2 dibuja la rampa entera de un vistazo y ejecuta rolloutPlan() — el modelo central del módulo — sobre el rollout real de recommendations, mostrando por primera vez que la rampa se detiene en una etapa cuando el guardrail de latencia se rompe. La lección 3 se enfoca en la primera etapa, el canary, y en un límite que es fácil ignorar: un canary puede ser tan chico que, aunque el problema exista, no genera suficientes eventos para que nadie lo note. La lección 4 nombra con precisión qué significa "avanzar" — un criterio explícito, no una corazonada ni un reloj. La lección 5 reutiliza blastRadius() del módulo 1 y lo aplica a las cuatro etapas de la rampa a la vez, mostrando dónde ocurre el salto más grande de exposición. La lección 6 agrega una dimensión que el porcentaje solo no cubre: quién, específicamente, ve la feature primero — empleados, después beta, después todos—. La lección 7 cierra el marco con el tiempo: cuánto esperar en cada etapa antes de que los datos sean confiables. Y la lección 8, el mini-proyecto, junta las seis piezas sobre recommendations: diseña la rampa completa y simula, con rolloutPlan(), el avance real dado el guardrail que ya conoces.
La frontera: qué NO entra en este módulo
- El feature flag y el kill switch en sí ya están resueltos — módulo 2. Aquí se usan: el
rolloutPercentde un flag es, precisamente, el número que la rampa de este módulo va cambiando etapa por etapa. - Qué vigilar exactamente durante la rampa — los guardrails de la guía de métricas, los dashboards, las alertas — es el módulo 4. Aquí vas a usar una medición de guardrail ya dada (por ejemplo,
p95Latency: 910msen una etapa) para decidir si avanzas; el módulo 4 enseña cómo se obtiene y se vigila esa medición en vivo. - Qué hacer ante un
HOLD— revertir, arreglar hacia adelante, el runbook — es el módulo 5. Este módulo llega hasta la decisión de frenar; la acción concreta después de frenar es la lección siguiente de la guía.
Dentro de este módulo: el foco entero es la mecánica de la rampa — cuántas etapas, en qué orden, con qué criterio se avanza, quién la ve primero, y cuánto se espera en cada una.
Errores comunes
Confundir "ya tenemos el flag" con "ya tenemos un plan de rollout". Qué pasa: un equipo que terminó el módulo 2 configura el flag y lo pone directo en rolloutPercent: 1.0, con el argumento de "para eso construimos el flag". Por qué pasa: el flag se siente como el trabajo difícil ya hecho, y mover un número de 1.0 a otro valor cualquiera parece un detalle menor comparado con haber construido el mecanismo técnico completo. Cómo detectarlo: nadie en el equipo puede decir, de memoria, en qué porcentaje está el rollout hoy y por qué está ahí en vez de en otro. Cómo corregirlo: trata el flag y la rampa como dos entregables distintos — el flag es el interruptor, la rampa (este módulo) es el plan de cuándo y por qué moverlo, con un criterio explícito por adelantado.
Tratar el rollout gradual como una serie de decisiones improvisadas, una por una, en vez de una rampa diseñada de antemano. Qué pasa: el equipo avanza el canary al 1%, y solo cuando llega ahí empieza a discutir a qué porcentaje ir después, con qué criterio, y cuánto esperar. Por qué pasa: diseñar las cuatro etapas completas por adelantado exige pensar en escenarios que todavía no pasaron, y es más cómodo resolver cada decisión cuando ya está encima. Cómo detectarlo: en la etapa actual de un rollout, nadie puede contestar todavía "¿y cuál es el criterio exacto para pasar a la siguiente etapa?" — la conversación empieza recién ahí. Cómo corregirlo: como vas a hacer en el mini-proyecto de la lección 8, diseña las cuatro etapas —porcentaje, criterio de avance, y a quién expone— antes de prender el flag por primera vez, no a medida que cada etapa se cumple.
Asumir que este módulo ya te dice qué métrica vigilar para decidir si algo "se ve bien". Qué pasa: alguien espera que la lección 4 (criterios de avance) le entregue la lista completa de guardrails de Mercado — latencia, quejas, churn — con sus techos exactos. Por qué pasa: "criterio de avance" suena a que debería incluir el catálogo completo de qué medir, y es natural esperar esa lista aquí. Cómo detectarlo: la pregunta que surge es "¿pero qué otras métricas, además de la latencia, debería estar mirando en cada etapa?" — esa es, literalmente, la pregunta del módulo 4. Cómo corregirlo: este módulo te enseña la forma de un criterio de avance (una condición explícita, verificable, definida antes de ver el resultado) usando el guardrail de latencia que ya conoces del caso de Mercado; el catálogo completo de qué vigilar y cómo, en vivo, es el módulo siguiente.
Ejercicios
Ejercicio 1 — Ubica la pregunta en el módulo correcto. Para cada pregunta sobre el lanzamiento de recommendations, di si la contesta el módulo 2 (feature flags), este módulo 3 (rollout gradual) o el módulo 4 (monitorear el lanzamiento):
- (a) "¿Cómo apago
recommendationsal instante si algo se rompe a las 3am?" - (b) "¿A qué porcentaje debería estar el rollout hoy, dado que ayer estaba en 1% y el guardrail se mantuvo dentro del techo?"
- (c) "¿Qué dashboard exacto muestra el
p95Latencyen tiempo real mientras sube el rollout?"
Ver solución
- (a) Módulo 2. El kill switch —apagar sin re-deploy— es su territorio exacto.
- (b) Módulo 3 (este). Decidir el porcentaje de la siguiente etapa, dado que la etapa actual cumplió su criterio, es la mecánica de la rampa que enseña este módulo.
- (c) Módulo 4. El dashboard específico que vigila el guardrail en vivo, con sus alertas, es monitoreo — la siguiente guía del arco.
Ejercicio 2 — Explica la diferencia con tus propias palabras. Un compañero de equipo dice: "No entiendo para qué necesitamos un módulo aparte para el rollout — ya tenemos el flag del módulo 2, con eso alcanza." En 2-3 frases, explica por qué tener el flag no es lo mismo que tener un plan de rollout.
Ver solución
El flag resuelve una pregunta binaria y por usuario: "¿esta persona específica ve la feature ahora mismo, sí o no?" — y lo hace de forma determinista, con isEnabled(user, flag). Lo que el flag no resuelve es la pregunta de secuencia: qué porcentaje usar hoy, cuál mañana, y con qué evidencia pasar de uno al otro. Sin ese plan, el flag es un interruptor que alguien puede mover a 100% el primer día sin ningún obstáculo técnico que lo impida — el riesgo no desaparece porque el mecanismo exista, desaparece cuando alguien usa el mecanismo con un plan de etapas y criterios, que es exactamente lo que construye este módulo.
Ejercicio 3 — Predicción con criterio. Sabes, desde el módulo 1, que el guardrail de latencia de recommendations ya está roto en la muestra del experimento (p95 a 910ms, techo 800ms). Sin haber leído todavía la lección 2, ¿esperas que la rampa de este módulo llegue limpia hasta el 100%, o esperas que se detenga en alguna etapa intermedia? Justifica tu respuesta con lo que ya sabes del radio de impacto (módulo 1).
Ver solución
Lo esperable es que la rampa se detenga en alguna etapa intermedia, no que llegue limpia al 100%. La razón: el guardrail de latencia no es una posibilidad — ya se confirmó roto, dentro del propio experimento, con una muestra de miles de usuarios. Una rampa diseñada con criterios reales (no cosméticos) tiene que reaccionar a esa evidencia en algún punto: si el criterio de avance de cada etapa de verdad depende de que p95Latency se mantenga bajo el techo de 800ms, y ese techo ya se rompió una vez con una muestra comparable a alguna de las etapas intermedias, lo consistente es que la rampa lo detecte y frene ahí — exactamente lo que vas a ver ejecutado en la lección 2.
Resumen y siguiente paso
En esta lección trazaste la frontera exacta entre lo que el módulo 2 ya te dio —el flag, isEnabled, el kill switch— y lo que este módulo agrega: la rampa completa, con sus etapas, su criterio de avance, quién la ve primero, y cuánto se espera en cada paso. Viste la analogía que va a acompañar todo el módulo —entrar al mar caminando, no de un clavado— y el mapa de las ocho lecciones que construyen, pieza por pieza, esa rampa sobre el caso real de recommendations.
Antes de avanzar deberías poder: explicar con tus propias palabras por qué un feature flag, por sí solo, no es un plan de rollout; y ubicar, a grandes rasgos, qué pregunta sobre el lanzamiento de recommendations resuelve este módulo y cuál queda para el módulo 4.
La lección 2 dibuja la rampa completa —1% → 10% → 50% → 100%— y ejecuta por primera vez rolloutPlan(), el modelo que vas a reutilizar el resto del módulo, sobre el rollout real de recommendations. Vas a ver, con números, exactamente en qué etapa se detiene.
Recursos
- Google SRE Workbook, Capítulo 16, "Canarying Releases" — sre.google/workbook/canarying-releases. El capítulo de referencia sobre desplegar un cambio primero en una porción limitada de producción; la base conceptual de la rampa completa que este módulo desarrolla etapa por etapa. En inglés.
- Martin Fowler (bliki), "CanaryRelease" — martinfowler.com/bliki/CanaryRelease.html. La definición de referencia: "una técnica para reducir el riesgo de introducir una nueva versión en producción, exponiéndola lentamente a un subconjunto chico de usuarios antes de exponerla a toda la infraestructura" — el resumen de una frase de todo este módulo. En inglés.
- LaunchDarkly, "7 Reasons Percentage Rollouts Reduce Deployment Risk" — launchdarkly.com/blog/how-percentage-rollouts-minimize-deployment-risks. Una introducción práctica, desde la industria de feature management, a por qué subir el porcentaje de forma gradual reduce el riesgo — el argumento de negocio detrás de la rampa. En inglés.