Feature Flags

Feature Flags: la Guía Completa

Qué es un feature flag, por qué usarlo, tipos (release, experiment, ops, permission), rollout progresivo, herramientas del mercado y buenas prácticas.

Ilustración abstracta de llaves y paneles geométricos superpuestos en tonos verde y turquesa, representando controles de activación y liberación progresiva de funcionalidades

El feature flag es el interruptor que separa el momento en que un código llega a producción del momento en que realmente se activa para alguien. Esta guía cubre el concepto desde cero hasta la operación madura: los cuatro tipos de flag, cómo hacer un rollout progresivo sin drama, la comparación neutral entre LaunchDarkly, Unleash, Flagsmith, PostHog y Statsig, y los riesgos reales de deuda técnica que nadie cuenta a la hora de vender la idea. Si llegaste hasta aquí buscando específicamente la diferencia entre feature flag y test A/B, o entre implementar la flag en el cliente o en el servidor, mira las guías dedicadas sobre feature flags x test A/B y client-side x server-side.

Qué es un feature flag, de forma directa

Un feature flag (también llamado feature toggle, señalizador de funcionalidad, o simplemente flag) es una estructura condicional en el código, normalmente un booleano o una regla de segmentación, que decide en tiempo de ejecución si determinado camino del programa se ejecuta o no. En su forma más simple, es esto:

si flag(“nuevo-checkout”) está activa para este usuario, entonces muestra el nuevo checkout, si no, muestra el anterior

El nombre “feature toggles” fue acuñado con ese sentido técnico por Pete Hodgson, en un artículo de referencia publicado en el sitio de Martin Fowler que sigue siendo la cita más común sobre el tema. La idea central que describen es simple de enunciar y poderosa en la práctica: la flag desacopla dos decisiones que, sin ella, quedan atadas una a la otra por la fuerza del proceso de deploy. Sin flag, “el código está en producción” y “la funcionalidad está disponible para el usuario” son la misma cosa, ocurren en el mismo instante, decidido por quien presiona el botón de deploy. Con flag, son dos decisiones independientes: ingeniería decide cuándo sube el código; producto, marketing o el propio sistema deciden cuándo (y para quién) se activa.

Esa separación parece pequeña en la descripción, pero cambia la temperatura de cada deploy. Sin flag, todo deploy de una funcionalidad nueva es un evento de riesgo binario: o funciona para todo el mundo, o corres a revertir el deploy entero (y, con él, cualquier otra cosa que haya subido junto). Con flag, el deploy se convierte en un evento de bajo riesgo (el código está ahí, pero apagado o visible solo para un puñado de cuentas internas) y la liberación se convierte en un evento controlado, gradual, reversible en segundos.

Feature flag no es lo mismo que branch

Una confusión común de quien recién empieza: “¿para qué sirve una flag, si ya tengo branches en Git?” La respuesta es que branch y flag resuelven problemas en momentos diferentes del ciclo de vida del código. Un branch existe antes de la integración: mientras tu código está aislado en una branch de feature, no afecta a nadie, pero tampoco se está probando junto con el resto del sistema, y cuanto más tiempo permanece aislado, más doloroso se vuelve el merge de regreso (el problema clásico del “merge hell”). Una flag existe después de la integración: el código ya está en la branch principal, ya está corriendo en las mismas pruebas automatizadas que todo lo demás, ya fue implementado, y la flag decide si está visible.

Es esa propiedad la que sostiene la práctica de trunk-based development, integrar directo en la branch principal varias veces al día, incluso con funcionalidades a medias, porque la flag garantiza que el código inacabado quede invisible hasta que esté listo. Fowler describe esto como uno de los usos centrales de los feature toggles: permitir que los equipos sigan entregando continuamente sin esperar a que una funcionalidad grande esté 100% lista para hacer merge.

Deploy y release como dos eventos separadosSin feature flag, el deploy y la liberación para el usuario ocurren en el mismo instante. Con feature flag, el código se implementa apagado, y la liberación para el usuario ocurre después, de forma controlada, sin necesitar un nuevo deploy.Sin feature flagCódigo listoDeploy = Releasemismo instanteTodo usuario veriesgo binarioCon feature flagCódigo listoDeploy, flag offnadie ve todavíaRelease cuando quierasgradual, reversible
La flag transforma el deploy en un evento de bajo riesgo (código presente, pero invisible) y la liberación en un evento controlado, separado del calendario de deploy.

Por qué usar feature flags

La motivación central es reducir el riesgo de cada cambio en producción, y se despliega en cuatro beneficios concretos que aparecen, con variaciones de nombre, en prácticamente toda la documentación seria sobre el tema (LaunchDarkly, Unleash y Atlassian abordan variaciones de estas mismas ventajas).

Deploy desacoplado del release

Como ya se describió arriba: puedes integrar e implementar código con la frecuencia que ingeniería exija (varias veces al día, en el caso de equipos de entrega continua madura), sin que eso signifique exponer cada cambio a todo el público de inmediato. Esto rompe el vínculo peligroso entre “con qué frecuencia hago deploy” y “cuánto riesgo asumo por deploy”.

Rollback instantáneo, sin nuevo deploy

Si una funcionalidad nueva causa un problema en producción, apagar la flag revierte el comportamiento en segundos, sin necesidad de abrir un nuevo pull request, esperar a que el pipeline de build y pruebas corra de nuevo, y hacer un nuevo deploy bajo presión (el escenario más propenso a errores que existe en ingeniería). Este es, según la propia documentación de LaunchDarkly y la literatura sobre continuous delivery, uno de los mayores beneficios operacionales de las flags: transformar un incidente que tardaría minutos u horas en revertirse en un clic.

Liberación segmentada y controlada

En lugar de “todos ven o nadie ve”, la flag permite decidir exactamente quién ve: solo el equipo interno, solo una cuenta beta específica, solo el 5% del tráfico, solo usuarios de un país, solo quienes están en un plan específico. Esa granularidad es lo que permite validar una funcionalidad de alto riesgo (una reformulación del checkout, por ejemplo) con exposición mínima antes de asumir el riesgo total.

Personalización y permisos de largo plazo

No toda flag es temporal. Algunas viven para siempre, controlando el acceso a una funcionalidad premium, a un recurso disponible solo en determinado plan, o a una configuración que varía por cliente en un producto multi-tenant. Esta categoría (que detallamos abajo como flag de permission) no se trata de reducir el riesgo de deploy, sino de modelar una regla de negocio.

Los cuatro tipos de feature flag

No toda flag sirve al mismo propósito, y confundir los tipos es la raíz de buena parte de la deuda técnica que aparece más adelante en esta guía. La categorización más citada en la literatura, incluyendo el artículo de Fowler/Hodgson y la documentación de LaunchDarkly, organiza las flags según dos ejes: cuánto tiempo viven (temporal x permanente) y quién decide el valor (una persona, un sistema, o el propio código de negocio).

Los cuatro tipos de feature flag por duración y propósitoRelease y experiment son típicamente flags de corta duración, días a pocas semanas. Ops y permission tienden a vivir mucho más tiempo, meses o de forma permanente.vida útil típica de la flagdíaspermanenteReleaseesconde códigohasta estar listoExperimentcomparavariacionescon datoOpskill switchcircuit breakeroperaciónPermissionplan, tier,acceso premium
Release y experiment nacen para morir pronto. Ops y permission suelen vivir semanas, meses, o permanentemente, porque codifican una regla de operación o de negocio, no un estado transitorio de entrega.

Release flags

Esconden una funcionalidad incompleta o no validada hasta que está lista para todos. Es el uso más básico y más común: permitir que ingeniería haga merge y deploy de trabajo en curso sin afectar al usuario. Vida útil: corta, días a pocas semanas. La flag debería eliminarse tan pronto la funcionalidad esté 100% liberada y estable, lo que rara vez ocurre en la práctica (más sobre esto en la sección de riesgos).

Experiment flags

Dividen el tráfico entre dos o más variaciones para medir el efecto de cada una en una métrica, con rigor estadístico (muestra calculada, significancia, tiempo mínimo de ejecución). Es la categoría que sostiene el test A/B: toda herramienta de experimentación usa flags por debajo del capó para decidir qué variación ve cada usuario, pero no toda flag es un experimento. La diferencia conceptual entre las dos cosas, y cuándo una se convierte en la otra, está detallada en la guía sobre feature flags y test A/B. Vida útil: corta y bien definida, el tiempo del experimento (normalmente una a pocas semanas), con decisión de “mantener o descartar” al final.

Ops flags (operacionales)

Controlan el comportamiento operacional del sistema en producción: un kill switch que apaga una integración externa problemática, un circuit breaker que corta una llamada a un servicio tercero inestable, un control de carga que reduce funcionalidad bajo un pico de tráfico. A diferencia de la release flag, el objetivo aquí no es esconder algo incompleto, es darle al equipo operacional un botón de emergencia. Vida útil: suele ser larga, a veces permanente, porque el riesgo operacional que mitiga (una dependencia inestable, un pico estacional) no desaparece.

Permission flags (entitlements)

Controlan qué puede acceder un usuario específico, cuenta u organización, típicamente por plan de suscripción, rol dentro de la cuenta, o contrato específico (un recurso liberado solo para un cliente enterprise, por ejemplo). A diferencia de las otras tres categorías, aquí la flag no se trata de gestionar riesgo de entrega, sino de modelar una regla de negocio, lo que LaunchDarkly llama “entitlements” en su documentación. Vida útil: permanente, mientras exista la segmentación de plan.

release = esconder hasta estar listo · experiment = comparar con dato · ops = botón de emergencia · permission = quién puede acceder

Feature flags x test A/B: dónde se cruza la línea

Vale la pena deshacer la confusión más común antes de seguir adelante, porque aparece en casi toda conversación sobre el tema: feature flag y test A/B no son la misma cosa, y uno no es una versión simplificada del otro.

La flag es el mecanismo: una condicional que decide, para un usuario dado, qué camino de código ejecutar. El test A/B es un método estadístico que usa ese mecanismo para responder una pregunta específica: “¿la variación B convierte más que la variación A, con confianza suficiente para confiar en eso?” Esto exige cosas que una release flag común nunca necesita tener: asignación aleatoria y estable de cada usuario a un grupo, cálculo del tamaño de muestra antes de empezar, y una prueba de significancia al final.

En la práctica, esto significa que toda experimentación A/B usa flags, pero la mayoría de las flags de un sistema (las de release, ops y permission, que son la mayoría en cualquier producto maduro) nunca se convierte en un experimento formal. Simplemente encienden o apagan un comportamiento, sin estadística alguna detrás. Es común que surja la confusión porque la misma herramienta (LaunchDarkly, Unleash, un SaaS de A/B como Donnu A/B) suele ofrecer ambos recursos en la misma plataforma, lo que difumina la línea en la cabeza de quien opera el producto en el día a día.

Cubrimos esta frontera con profundidad, incluyendo cuándo una release flag simple debería convertirse en un experimento de verdad y qué cambia en la implementación, en la guía dedicada feature flags x test A/B.

Client-side x server-side: dónde ocurre la decisión de la flag

Otra decisión de arquitectura que aparece pronto en cualquier adopción de feature flags es dónde el código evalúa la flag: en el navegador o app del usuario (client-side) o en tu backend (server-side). No es solo un detalle de implementación, es una elección con implicaciones reales de seguridad, performance y complejidad.

Client-side es más simple de instalar (un SDK de JavaScript, por ejemplo) y es la elección común para marketing, onboarding y cambios de interfaz. El costo: la lógica de la flag (incluso, en implementaciones ingenuas, los propios valores de flags apagadas) viaja en el bundle que llega al navegador del usuario, lo cual es inaceptable para reglas de negocio sensibles o datos que no deberían filtrarse a quien no tiene la flag activa.

Server-side mantiene la decisión enteramente en tu backend: el cliente nunca ve el código ni los valores de las flags que no se le aplican, lo cual es el estándar recomendado para permisos, datos privados y cualquier lógica que no debería ser inspeccionable por quien abre el DevTools del navegador. El costo es una llamada de red adicional (o una sincronización periódica de configuración) y una pieza más de infraestructura para mantener en funcionamiento.

Los equipos maduros normalmente usan ambos, cada uno donde tiene sentido: client-side para lo que es visual y de bajo riesgo, server-side para lo que es sensible o decide acceso. La comparación completa, con la arquitectura de cada enfoque, la latencia típica y cómo las herramientas del mercado resuelven el problema del “flicker” (la página parpadeando la versión equivocada antes de aplicar la flag), está en la guía test A/B client-side x server-side, que cubre la misma dicotomía aplicada a la experimentación.

Rollout progresivo y canary release

El rollout progresivo es la técnica de liberar una funcionalidad para una fracción creciente del público, en lugar de pasar de 0% a 100% de una vez. Es donde una release flag entrega el mayor valor práctico, porque transforma “¿va a funcionar en producción?” de una pregunta que solo se responde después del hecho consumado en una pregunta que se responde poco a poco, con dato real y exposición controlada.

Curva de rollout progresivo a lo largo del tiempoEl rollout progresivo típico comienza en una fracción pequeña del tráfico, como el 1%, sube al 5%, luego al 25%, luego al 50%, y solo entonces llega al 100%, con verificación de métricas de salud entre cada etapa.% del tráfico expuestoetapas del rollout1%5%25%50%100%
Cada etapa permanece activa el tiempo suficiente para observar métricas de salud (error, latencia, guardrail de negocio) antes de avanzar a la siguiente. Cualquier degradación interrumpe el avance y, si es necesario, regresa la asignación a 0%.

Canary release es un caso específico y más restringido de rollout progresivo: en lugar de segmentar por porcentaje de usuarios, liberas primero para un subconjunto de servidores o instancias (el término viene de los canarios usados en minas para detectar gas antes de que afectara a los mineros), observas la salud de la infraestructura en ese subconjunto, y solo entonces expandes al resto de la flota. Es una técnica de deploy de infraestructura tanto como de flag, y ambas se combinan bien: un canary release en la infraestructura, con una release flag controlando quién, dentro de ese canary, realmente ve la funcionalidad nueva.

El patrón de rollout progresivo más citado sigue etapas parecidas a estas, ajustadas al volumen de tráfico y al apetito de riesgo del equipo:

Etapa Público típico Qué se observa
Interno Equipo y QA (dogfooding) Bugs obvios, antes de que cualquier usuario real los vea
1% Fracción mínima de producción Tasa de error, latencia, excepciones en el log
5-10% Muestra mayor, aún pequeña Las métricas de negocio empiezan a tener sentido
25-50% La mitad o más del público Confirma que el comportamiento se sostiene a escala
100% Todo el público Rollout completo; la flag puede empezar a considerarse para su eliminación

Cada avance de etapa debería estar condicionado a métricas de guardia (guardrail): tasa de error, latencia, e indicadores de negocio que no pueden empeorar. Si alguna se degrada, la respuesta es reducir la asignación de vuelta, no seguir adelante con la esperanza de que “se estabiliza solo”.

Herramientas del mercado (visión neutral)

No existe “la mejor herramienta de feature flag”, existe la adecuada para tu contexto: tamaño del equipo, presupuesto, si ya pagas por analítica o experimentación en alguno de esos proveedores, y cuánto control de infraestructura quieres mantener internamente. Un retrato neutral de lo que ofrece cada una, según la documentación pública de cada proveedor:

Herramienta Modelo Enfoque declarado
LaunchDarkly SaaS comercial Plataforma de feature management madura, con segmentación avanzada, experimentación integrada y fuerte énfasis en gobernanza y auditoría para equipos grandes
Unleash Código abierto (core) + SaaS opcional Puede ser alojado por el propio equipo (self-hosted) con el core bajo licencia open source; enfoque declarado en soberanía de datos y ausencia de vendor lock-in
Flagsmith Código abierto + SaaS También ofrece opción self-hosted; se posiciona como alternativa con buenos SDKs y API REST simple, plan gratuito generoso para equipos pequeños
PostHog SaaS (con self-host) Feature flags como parte de una suite de producto más amplia (analítica, session replay, experimentos), útil para quien ya usa PostHog para otras cosas
Statsig SaaS comercial Fuerte integración entre feature flags y experimentación estadística, con énfasis en métricas y tests A/B nativos sobre la misma infraestructura de flag

Criterios que suelen pesar más en la elección, en la práctica, que el nombre de la marca:

Esta comparación es un retrato de lo que cada proveedor declara públicamente; los precios, límites del plan gratuito y funciones específicas cambian con frecuencia, así que vale la pena confirmar en la documentación oficial de cada uno antes de decidir.

Riesgos y buenas prácticas

El feature flag reduce el riesgo de deploy, pero introduce un riesgo diferente si no se gestiona: complejidad que se acumula silenciosamente hasta convertirse en deuda técnica difícil de deshacer. Los riesgos más citados en la literatura sobre el tema, y la práctica que resuelve cada uno:

Flag zombi (deuda técnica)

Es el riesgo más discutido de todos: una flag que ya cumplió su papel (la funcionalidad está 100% liberada y estable desde hace meses) pero que nadie eliminó del código. Sigue ahí, con el if y el else enteros, exigiendo que cualquier persona que lea ese fragmento entienda los dos caminos posibles, aunque uno de ellos ya nunca se ejecute. Multiplicado por decenas o cientos de flags acumuladas a lo largo de años, el resultado es un código donde nadie tiene certeza de qué combinaciones de flags son siquiera posibles, y la superficie de prueba explota.

Buenas prácticas para evitarlo:

Explosión combinatoria de estados

Cada flag activa duplica, en teoría, el número de combinaciones posibles de comportamiento del sistema. Con pocas flags esto es irrelevante; con decenas corriendo al mismo tiempo, se vuelve imposible probar manualmente todas las combinaciones, y las interacciones inesperadas entre dos flags (una activa un flujo nuevo, otra cambia una dependencia de ese flujo) se convierten en una fuente real de bugs en producción que solo aparecen para una fracción específica de usuarios.

Mitigación: mantener el número de flags simultáneamente activas lo más bajo posible (refuerza el punto anterior sobre eliminación), documentar dependencias conocidas entre flags, y usar una testing matrix (tabla de combinaciones relevantes, no todas las matemáticamente posibles) para los escenarios que realmente importan para el negocio.

Testing matrix de combinaciones de flags relevantesEn lugar de probar todas las combinaciones matemáticamente posibles entre flags activas, una testing matrix lista solo las combinaciones que realmente importan para el negocio, marcando cuáles ya fueron verificadas.EscenarioFlag AFlag BVerificadousuario nuevoonoffcuenta legadaononpendienteplan enterpriseoffon
La matriz prioriza combinaciones plausibles y relevantes para el negocio (usuario nuevo, cuenta legada, plan específico), no la lista completa de 2 elevado al número de flags, que crece demasiado rápido como para ser útil.

Consistencia de la experiencia del usuario

Un usuario que alterna entre pestañas, dispositivos, o recarga la página no puede ver la funcionalidad aparecer y desaparecer de forma inconsistente. Esto exige una unidad de segmentación estable (normalmente un hash determinístico del ID del usuario o de un identificador anónimo persistente), la misma preocupación que ya existe en el test A/B para garantizar que cada visitante siempre vea la misma variación.

Gobernanza y auditoría

En equipos más grandes, “quién cambió esta flag, cuándo, y por qué” necesita tener respuesta. Las herramientas dedicadas de feature management resuelven esto de forma nativa con log de auditoría; las soluciones caseras (una tabla en la base de datos, una variable de entorno) normalmente no lo tienen gratis, y vale la pena considerar agregarlo antes de que la ausencia se convierta en un incidente sin explicación.

Performance y punto único de falla

La evaluación de una flag no puede convertirse en un cuello de botella ni en un punto de falla: si el servicio que resuelve las flags cae, el sistema necesita degradar hacia un comportamiento predeterminado seguro (normalmente, la flag apagada), nunca bloquear la aplicación entera esperando una respuesta que no llega. Es el mismo principio de “fallar silenciosamente hacia el estado seguro” que cualquier snippet de terceros incrustado en una página debería seguir.

Cómo se relacionan los feature flags con el motor de experimentación de Donnu

Todo lo que esta guía describió sobre las flags de release, ops y permission ocurre antes de que entre en juego cualquier estadística: son decisiones de encender/apagar/segmentar, sin hipótesis, sin muestra calculada, sin valor p. El punto en que una flag común se convierte en experimentación de verdad es cuando dejas de preguntar “¿esto está encendido para quien yo quiero?” y pasas a preguntar “¿esta variación convierte más que la otra, con confianza suficiente para decidir con base en eso?”.

Es exactamente en ese segundo momento cuando entra el motor de test A/B: Donnu usa el mismo mecanismo de segmentación estable de un feature flag (cada visitante cae en una variación y permanece en ella) para alimentar un test con diseño estadístico honesto detrás, desde el cálculo del tamaño de muestra hasta la lectura bayesiana del resultado al final. Si ya usas feature flags para controlar releases y quieres transformar una de ellas en un experimento con rigor, la guía de feature flags x test A/B detalla exactamente esa transición.

Hazlo automático en Donnu

Acabas de ver la diferencia entre apagar una funcionalidad por seguridad y comparar dos variaciones con rigor estadístico: la primera es gestión de flags, la segunda es experimentación. Donnu A/B se enfoca en la segunda parte: cuando una de tus flags de release o experiment necesita convertirse en una decisión basada en datos, con tamaño de muestra calculado, lectura bayesiana honesta y sin el flicker que arruina la experiencia del usuario, no necesitas construir ese motor estadístico desde cero.

Comienza una prueba gratuita de 14 días y mira cómo es llevar una funcionalidad de “está encendida” a “sabemos que funciona mejor”. Si quieres profundizar antes, mira la diferencia completa entre feature flags y test A/B y la comparación entre ejecutar la decisión en el cliente o en el servidor.

Referencias

Preguntas frecuentes

¿Qué es un feature flag, en una frase?
Es un interruptor en el código que decide, en tiempo de ejecución y sin necesidad de un nuevo deploy, si una funcionalidad queda visible o activa para un usuario, un grupo de usuarios o el 100% del público, permitiendo separar el momento en que el código sube a producción del momento en que realmente se libera.
¿Un feature flag es lo mismo que un test A/B?
No. La flag es el mecanismo de control (encender/apagar/segmentar código); el test A/B es un método estadístico que usa ese mecanismo para comparar dos versiones y decidir cuál convierte más, con significancia y muestra calculadas. Toda experimentación usa flags por debajo, pero la mayoría de las flags (las de release, ops y permisos) nunca se convierte en un experimento. Mira la comparación completa en nuestra guía dedicada sobre feature flags y test A/B.
¿Un feature flag sustituye el control de versiones (Git)?
No, resuelven problemas diferentes y se complementan. Git controla el historial y la integración del código fuente; la flag controla el comportamiento en producción después de que el código ya fue integrado e implementado. Es exactamente esa separación la que permite hacer merge al trunk todos los días sin exponer una funcionalidad inacabada, la práctica que Martin Fowler llama trunk-based development apoyada en feature toggles.
¿Cuál es el mayor riesgo de usar feature flags?
La deuda técnica de flag zombi: señalizadores que ya cumplieron su papel (la funcionalidad ya está 100% liberada y estable) pero que nunca se eliminaron del código. Cada flag viva multiplica los caminos de ejecución a probar y aumenta la probabilidad de que dos señalizadores interactúen de una forma que nadie previó. La corrección es proceso, no herramienta: dueño por flag, fecha de expiración y una rutina periódica de limpieza.
¿Feature flag client-side o server-side, cuál elegir?
Depende de dónde necesita tomarse la decisión y de qué está en juego. Client-side (en el navegador o en la app) es más simple de instalar y común en marketing y onboarding, pero expone la lógica de la flag en el bundle enviado al usuario. Server-side es más robusto para reglas de negocio sensibles, permisos y datos privados, porque la decisión nunca sale de tu backend. La comparación completa, con el trade-off de cada lado, está en la guía sobre client-side x server-side.
¿Necesito una herramienta paga para empezar a usar feature flags?
No necesariamente. Es posible empezar con una flag simple leída de una variable de entorno o de una tabla en la base de datos. Herramientas dedicadas como LaunchDarkly, Unleash, Flagsmith, PostHog o Statsig entran cuando necesitas segmentación por atributo de usuario, rollout porcentual, panel para el equipo no técnico y auditoría, sin tener que escribir esa infraestructura a mano.