¿Cómo funcionan juntos los feature flags y los staged rollouts para reducir el riesgo de un release?
Dos perillas independientes, no una: el staged rollout limita quién recibe código riesgoso, el feature flag limita quién ve comportamiento riesgoso.
APRENDE HACIENDOPon a prueba tu intuición3 pasos
¿Cómo funcionan juntos los feature flags y los staged rollouts para reducir el riesgo de un release?
Usa los ejemplos y la explicación de la lección para comprobar tu idea.
Reflexión personal. No se envía a ningún servicio de IA.Un staged rollout en Play Store o un phased release en App Store controla quién recibe un binario — el APK/AAB o el IPA compilado. Un feature flag controla quién ve un comportamiento dentro de un binario que ya está instalado. Esta pregunta busca ver si entendés que son dos mecanismos de reducción de riesgo independientes, no dos nombres para la misma idea, y que el verdadero poder aparece cuando los corrés juntos.
#Dos perillas independientes
Pensá en cada release como si tuviera dos perillas que se giran por separado. La primera es el porcentaje de rollout en la store: el 5% de los usuarios que buscan actualización reciben el binario nuevo, después el 20%, después el 50%, después el 100%. La segunda es el porcentaje de rollout del flag, controlado por un servicio de remote config — Firebase Remote Config, LaunchDarkly, Statsig, o un endpoint de configuración propio: el 5% de los usuarios que ya tienen el binario nuevo tienen el checkout nuevo activado, independientemente de cómo se distribuyó el binario. Un build puede estar al 100% de rollout en la store mientras una feature riesgosa adentro se mantiene en 1% de exposición del flag durante semanas.
#Qué detecta cada perilla que la otra no puede
El staged rollout a nivel store detecta problemas que viven en el binario mismo: un crash nativo en una combinación de dispositivo/OS que no probaste, una regresión en el arranque, un memory leak, un ANR disparado por un servicio en segundo plano. Nada de eso lo puede deshacer un flag remoto, porque el código malo ya se envió — apagar un flag solo cambia qué camino de código se ejecuta, y un crash en código de inicialización muchas veces corre antes de que cualquier chequeo de flag sea siquiera posible.
Los feature flags detectan problemas que viven en la lógica de negocio y el comportamiento de producto: un checkout nuevo con un cálculo de impuestos sutilmente mal hecho, un funnel de onboarding rediseñado que hunde la conversión, un algoritmo de ranking de búsqueda reescrito que devuelve peores resultados. Nada de eso necesariamente tira abajo la app, así que frenar un rollout de store — que solo detiene las instalaciones nuevas del binario, no toca los dispositivos que ya actualizaron — no ayuda ni cerca tan rápido como apagar un booleano del lado del servidor, que toma efecto en el próximo fetch de configuración, muchas veces en minutos.
#La trampa del rollout correlacionado
#Kill switches y métricas de guardrail
La otra mitad de esta respuesta es el kill switch: un flag cuyo valor por defecto, cuando el fetch de configuración falla o hace timeout, es "apagado" para todo lo riesgoso y "prendido" para todo lo ya probado. Combinalo con métricas de guardrail conectadas a tu monitoreo — tasa de sesiones libres de crash, tasa de finalización del checkout, latencia p95 del endpoint nuevo — para que una persona o un job automatizado pueda mantener el rollout de store en su porcentaje actual, o apagar el flag, antes de que el radio de impacto crezca. El rollback automatizado es la versión más madura de esto: un job programado observa los umbrales de alerta de Crashlytics o Sentry y llama a la API del proveedor de flags para desactivar el flag por sí solo, sin necesidad de una persona.
class CheckoutFeatureGate(private val remoteConfig: FirebaseRemoteConfig,private val analytics: AnalyticsClient,) {// Salt independiente del bucket de rollout de Play Store — nunca lo derives// del mismo hash de device-id usado para el staged rollout del binario.fun isNewCheckoutEnabled(userId: String): Boolean {val enabled = try {remoteConfig.getBoolean("checkout_v2_enabled")} catch (e: Exception) {false // fail closed: falló el fetch de config, usá el camino probado}// Registrá la exposición una vez por sesión para que producto pueda// atribuir el movimiento de métricas al flag, independiente del % de la store.analytics.logExposure("checkout_v2", enabled, userId)return enabled}}// Uso en el call site — el flag es lo único que decide el camino.val checkoutScreen = if (featureGate.isNewCheckoutEnabled(userId)) {CheckoutV2Screen()} else {CheckoutV1Screen()}
#Limpiar después del rollout completo
Un flag que lleva un mes al 100% con métricas de guardrail limpias es "deuda de flags" desde el momento en que deja de ser una decisión y pasa a ser una rama permanente en el código de la que nadie recuerda el motivo. Tratá "sacar el flag y borrar el camino de código viejo" como parte del release, no como un follow-up opcional — agendalo para el mismo sprint en el que llegás al 100%, o se vuelve arqueología seis meses después.
🧠 Feature flags vs. staged rollouts
0/3 · 0/3 answered1. Un crash solo ocurre en una combinación específica de fabricante/OS, dentro de código que forma parte del binario mismo. ¿Qué mecanismo limita cuántos usuarios lo sufren?
2. ¿Por qué es riesgoso derivar el bucket de rollout del flag y el bucket de rollout de la store del mismo hash de device-id?
3. ¿Qué debería hacer un feature flag por defecto cuando el fetch de configuración remota falla o hace timeout?