Volver al Blog
engineering||15 min de lectura

Simulación Monte Carlo: Deja de Adivinar Cuándo Entregarás Tu Software

AR
Aral Roca

Creador de Kitmul

El año pasado vi a un CTO prometer a su junta directiva que una funcionalidad estaría lista "para final de Q2." Yo estaba en la sala. Se sacó la fecha de la manga. Lo sé porque llevaba dos semanas trabajando con su equipo y no había manera — el backlog tenía 140 elementos, la velocidad del equipo era un desastre, y dos de los cinco desarrolladores estaban a punto de cogerse la baja por paternidad. Q2 pasó. La funcionalidad se entregó a mediados de agosto. Nadie se sorprendió excepto la junta.

Esto pasa en todas partes. En todas las empresas con las que he trabajado. La pregunta "¿cuándo estará listo?" ha destruido más confianza entre ingeniería y negocio que cualquier caída de producción.

Y mira, lo entiendo. Los directivos necesitan fechas. Los contratos necesitan fechas. Marketing no puede anunciar "en algún momento entre abril y vete tú a saber." Pero la solución no es inventarse un número y rezar. La solución es ser honesto sobre lo que sabes y lo que no.

Por eso construí un simulador Monte Carlo de entregas. No porque el mundo necesitase otra herramienta ágil — dios sabe que hay de sobra — sino porque no paraba de tener la misma conversación con engineering managers que querían dar fechas realistas y no tenían ni idea de cómo hacerlo.

El número que lo arruinó todo

Así es como suele ir mal.

El PM pregunta: "¿cuándo acabamos el backlog?" El lead piensa un rato, añade un buffer porque ya le han quemado antes, y dice "ocho sprints." El PM lo apunta. Se lo dice al VP. El VP se lo dice al cliente. Ahora ocho sprints es una promesa. Pero nunca fue una promesa — fue la intuición de una persona un martes por la tarde después de demasiado café.

¿Y qué significa "ocho sprints" en realidad? ¿El mejor caso? ¿La media? ¿El escenario donde nada sale mal y nadie se pone enfermo y la API de la que dependes no cambia y ese junior mágicamente se convierte en senior de la noche a la mañana? Cuando presiono a la gente con esto suelen decir algo como "bueno, yo diría que tenemos bastantes opciones." Genial. Bastantes opciones. Ponlo en el contrato.

Daniel Kahneman llamó a esto la falacia de la planificación. Estamos programados para subestimar cuánto tardan las cosas. Incluso cuando conocemos este sesgo, seguimos cayendo en él. Hasta el propio Kahneman admitió que cayó mientras escribía el libro sobre sesgos cognitivos. Le llevó años más de lo previsto. La ironía es casi demasiado perfecta.

Solitario, bombas nucleares y tu backlog de sprint

En 1946, un matemático polaco llamado Stanislaw Ulam se estaba recuperando de una operación de cerebro (encefalitis, algo muy feo) y jugaba mucho al solitario. No paraba de preguntarse: ¿qué probabilidad tiene esta mano de ganar? Intentó calcularlo analíticamente. No pudo. Demasiadas permutaciones. Y entonces tuvo una de esas ideas que parecen obvias a posteriori pero que lo cambian todo — ¿y si simplemente juego mil partidas y cuento cuántas gano?

Se lo contó a su colega John von Neumann. Von Neumann, porque era von Neumann, inmediatamente vio la aplicación a los problemas de difusión de neutrones en los que trabajaban en Los Álamos. Necesitaban que el nombre fuera secreto así que lo llamaron "Monte Carlo" por el casino donde al tío de Ulam le gustaba apostar. Y eso es todo — esa es toda la técnica. No intentes calcular la respuesta exacta. Simúlalo a saco y mira qué pasa.

Para la previsión de entregas ágiles es el mismo truco, solo que aplicado a tus datos de sprint en lugar de reacciones nucleares en cadena (discutiblemente menos estresante, aunque algunas dailies se acercan bastante):

  1. Coges el throughput de tu equipo de los últimos sprints — cuántos elementos completasteis en cada uno
  2. Le dices al simulador cuántos elementos quedan
  3. El simulador elige aleatoriamente un throughput de tu historial, lo resta del trabajo restante, elige otro, resta otra vez, y sigue hasta que el trabajo llega a cero
  4. Hace eso 10.000 veces
  5. Te dice: "de 10.000 simulaciones, aquí está cuántos sprints tardaste"

Sin story points. Sin planning poker. Sin debates de "¿pero una página de login es un 3 o un 5?" a las 9 de la mañana un lunes. Solo tus datos reales, alimentados con aleatoriedad, produciendo un rango de resultados realistas.

Resultados de simulación Monte Carlo mostrando percentiles P50, P85 y P95 para previsión de entregas
Resultados de simulación Monte Carlo mostrando percentiles P50, P85 y P95 para previsión de entregas

P50, P85, P95 — tres números que sustituyeron todas nuestras discusiones

Lo que te importa del resultado son tres percentiles:

P50 — la mitad de las simulaciones terminaron en este sprint. Probabilidad de cara o cruz. Yo uso esto para planificación interna de "estaría bien." Nunca te comprometas externamente con este número.

P85 — el 85% de las simulaciones terminaron en este sprint. Este es el que les digo a los managers que usen. Cuando tu VP pide una fecha, esta es la fecha. No la optimista. Esta.

P95 — el 95% de las simulaciones terminaron en este sprint. Contratos. Presupuestos. Cualquier cosa donde fallar la fecha cueste dinero real. Rellenas hasta aquí y duermes tranquilo por las noches.

Pero hay algo de lo que nadie habla: la diferencia entre P50 y P95 es el dato más valioso de todos. Si P50 dice 7 sprints y P95 dice 8, tu equipo es una máquina. Consistente, predecible, aburrido de la mejor manera posible. ¿Si P50 dice 6 y P95 dice 14? Tienes un problema que ninguna técnica de estimación del mundo va a arreglar. Tu throughput es caótico y necesitas averiguar por qué antes de preocuparte por cuándo.

Tuve un equipo una vez donde la diferencia era de 5 a 19. Diecinueve sprints. Para el mismo backlog. Investigamos y descubrimos que dos de sus sprints tenían throughput cero — el equipo entero había sido absorbido por respuesta a incidentes las dos veces. Cuando excluimos esos datos (eran eventos puntuales, no operaciones normales), la diferencia bajó a 6 a 9. Mucho más útil.

Qué hace el código realmente

El simulador se ejecuta en tu navegador. Nada va a ningún servidor. Soy algo obsesivo con esto — si tus datos de sprint pueden quedarse en tu máquina, deberían quedarse en tu máquina. Se guardan en localStorage también, así que no tienes que volver a meterlos la semana que viene.

El bucle de simulación es casi vergonzosamente simple:

for (let i = 0; i < iterations; i++) {
  let remaining = totalItems;
  let sprints = 0;

  while (remaining > 0) {
    // Elige un sprint aleatorio de tu historial
    const throughput = data[Math.floor(Math.random() * data.length)];
    remaining -= throughput;
    sprints++;
  }

  sprintCounts.push(sprints);
}

Eso es... básicamente todo. Cada iteración elige valores de throughput aleatorios de tu historial hasta que el trabajo se acaba, y registra cuántos sprints tardó. Ordena los 10.000 resultados, lee los percentiles. Las matemáticas son triviales. La conclusión no.

Lo que hace que funcione es que no suaviza nada. ¿Tuviste un sprint horrible donde solo cerraste 3 elementos? Eso se muestrea. ¿Tuviste uno increíble donde liquidaste 20? También se muestrea. La simulación preserva toda la realidad fea del rendimiento de tu equipo en lugar de esconderla detrás de una media.

Me cansé de herramientas que no te avisan cuando los datos son basura

Una de mis mayores quejas con todas las herramientas Monte Carlo que probé antes de construir la mía: se tragan basura encantadas y escupen un gráfico con cara de confiable. Aliméntalas con dos puntos de datos y te darán P50/P85/P95 como si esos números significaran algo con una muestra de dos.

Así que metí cinco comprobaciones que te gritan cuando tus datos son dudosos:

Si solo tienes 2 o 3 sprints — funciona, pero te avisa de que los resultados son básicamente ruido. Necesitas al menos 8-10 sprints para que la ley de los grandes números empiece a funcionar a tu favor.

Los sprints con throughput cero se marcan. No porque sean inválidos (los festivos pasan, los bloqueos pasan), sino porque teclear 0 por accidente cuando querías poner 10 destrozará tu previsión y puede que ni te des cuenta.

Si un sprint muestra 50 elementos cuando tu mediana es 12, la herramienta lo marca como probable outlier. Quizá el equipo cerró en bloque un montón de tickets viejos. Quizá de verdad fueron así de productivos. En cualquier caso, deberías mirarlo.

Si todos tus valores son idénticos — por ejemplo, exactamente 10 elementos cada sprint — la herramienta básicamente te dice "no me necesitas, la respuesta es una división." Lo cual, oye, justo.

Y si tu coeficiente de variación supera el 50%, te avisa de que tu throughput es volátil y la horquilla va a ser amplia. Eso no es problema de la herramienta. Es un problema de proceso del equipo. Normalmente son cambios de alcance a mitad de sprint, o gente tirando en distintas direcciones, o dependencias de otros equipos que son impredecibles. Arregla la causa y luego ejecuta la previsión.

Un ejemplo con números reales

Supongamos que los últimos 10 sprints de tu equipo fueron así — y elijo números realistas, no de libro de texto:

Sprint Hecho
1 8
2 12
3 10
4 7
5 14
6 11
7 9
8 13
9 6
10 11

80 elementos en el backlog. Metes eso en el simulador Monte Carlo y lo ejecutas.

P50 sale 8 sprints. P85 sale 9. P95 sale 11.

Ahora en vez de decirle al PM "unos 8 sprints, creo?" le dices: "estamos al 85% de confianza de que estará en 9 sprints. Si necesitas una garantía, planifica para 11. Yo no prometería menos de 9 a nadie externo." El PM tiene algo con lo que trabajar. Algo con niveles de confianza adjuntos. Si decide comprometerse a 9, está haciendo una apuesta informada, no una a ciegas.

Y honestamente la conversación cambia por completo. En vez de discutir si 8 sprints es "suficientemente ambicioso" (una frase real que un PM me dijo una vez, todavía me persigue), estás hablando de tolerancia al riesgo. Que es de lo que tendría que haber ido la conversación desde el principio.

Story points, te quiero, pero tenemos que hablar

Usé story points durante años. Fibonacci, tallas de camiseta, lo que quieras. Era creyente. Incluso discutí con gente en Twitter por ello. Estaba equivocado. O al menos, me estaba perdiendo una opción mejor.

Los story points se inventaron para desacoplar la estimación del tiempo. Estimas complejidad, mides velocidad, derivas el timeline. Elegante en teoría. ¿En la práctica?

Las reuniones de estimación. Dios mío, las reuniones de estimación. Cuarenta y cinco minutos debatiendo si migrar el servicio de autenticación es un 13 o un 21. La senior piensa que es un 13 porque ya lo ha hecho antes. El junior piensa que es un 21 porque ha visto cómo está el servicio de auth. Los dos tienen razón desde su perspectiva y el número en el que se ponen de acuerdo (normalmente gana el que habla más alto) no ayuda a nadie a planificar nada.

Y la velocidad en puntos-por-sprint es extrañamente inestable. Deriva. Los equipos inconscientemente calibran sus estimaciones para dar un número de velocidad con el que su manager parece contento. Lo he visto pasar. Nadie lo admite, pero pasa.

Monte Carlo simplemente... esquiva todo eso. Cuentas elementos hechos por sprint. No puntos, no horas. Elementos. Hecho o no hecho. Binario. La entrada es objetiva y la salida es probabilística y la reunión de estimación entera desaparece de tu calendario. Allen Holub y la gente de #NoEstimates llevan años con este mensaje. Monte Carlo es la matemática que hace su argumento concreto.

Cuándo este enfoque se cae a pedazos

Sería un pésimo ingeniero si no te dijera cuándo NO usar esto.

¿Tu backlog no para de crecer? Monte Carlo no te puede ayudar. Si estás añadiendo 15 elementos por sprint y completando 10, la única previsión honesta es "nunca." Arregla el flujo de entrada primero.

¿Tu backlog es una mezcla loca de elementos de tamaños muy distintos? Un ticket es "corregir el typo de la página 404" y otro es "rediseñar el flujo de checkout"? Contar elementos no tiene sentido. Necesitas partir las cosas hasta que sean más o menos comparables. Honestamente deberías estar haciendo eso igualmente, pero Monte Carlo te fuerza a ello.

¿Tu equipo acaba de cambiar radicalmente? ¿Nuevas incorporaciones, bajas, reorganización? Tus datos históricos no representan a tu equipo actual. Tíralos y empieza de cero. Ya sé que duele. La simulación asume que el futuro se parece al pasado. Si el pasado es irrelevante, la simulación también.

¿Backlog minúsculo? ¿Tipo 5 elementos? La diferencia entre un "sprint bueno" y un "sprint malo" es enorme respecto al total. Monte Carlo funciona mejor con 30+ elementos restantes donde la aleatoriedad se promedia a lo largo de muchos sprints simulados. Para 5 elementos, simplemente... hazlos. Ya verás cuándo están.

Empezar — te lleva unos 90 segundos

  1. Abre el simulador Monte Carlo de entregas
  2. Mete el throughput de los últimos 8-10 sprints (solo el número de elementos hechos cada sprint — mira tu Jira o Linear si no te acuerdas)
  3. Mete los elementos restantes del backlog
  4. Dale a ejecutar

Eso es todo. Vuelve el próximo sprint, añade el nuevo número, mira cómo cambia la previsión. Tus datos se quedan en tu navegador — ni siquiera tengo un servidor al que enviarlos.

Si te va el tooling ágil, también construimos una Calculadora de Capacidad de Sprint para planificar cuánto trabajo puede asumir tu equipo realmente, un tablero de Priorización MoSCoW para cuando necesitas hacer triage sin piedad, y un generador de Diagramas de Flujo Acumulado si quieres visualizar dónde se atasca el trabajo. Todo gratis, todo en el navegador, sin cuenta.

Para los frikis: qué está pasando matemáticamente

(Sáltate esto si no te importa la estadística. No te juzgaré.)

Lo que estamos haciendo es un remuestreo bootstrap. Extraemos muestras con reemplazo de una distribución empírica — tu historial de throughput — y usamos esas muestras para estimar un parámetro que nos interesa, concretamente los percentiles de fecha de entrega. Es no paramétrico, o sea que no asumimos que tus datos siguen una distribución normal ni ninguna otra forma teórica. Menos mal, porque los datos de throughput de sprint casi nunca son normales. Suelen tener sesgo a la derecha con ceros ocasionales.

¿Por qué 10.000 iteraciones? Con 1.000 tus estimaciones de percentiles bailan un poco entre ejecuciones. Con 10.000 se estabilizan. Con 50.000 gastas más cómputo para una mejora insignificante. El teorema del límite central garantiza la convergencia pero la velocidad depende de la varianza de tus datos — equipos con oscilaciones salvajes de throughput necesitan más iteraciones para asentarse. 10.000 es el punto dulce para casi todo el mundo.

Una decisión de diseño de la que estoy contento: la simulación usa remuestreo discreto (elegir sprints históricos reales al azar) en lugar de ajustar una distribución continua. Algunas herramientas asumen que el throughput tiene distribución normal y muestrean de una Gaussiana ajustada. Es más limpio matemáticamente pero está mal. Tus datos tienen una forma. Quizá es bimodal porque alternas entre sprints de crunch y sprints de recuperación. Quizá tiene una cola larga porque una vez al año todo se va al carajo. El remuestreo discreto preserva la forma real de tus datos. Sin suposiciones, sin sorpresas.

La verdad incómoda que esta herramienta expone

Acabo con algo que he notado después de ver a docenas de equipos usar esto.

La herramienta no te dice nada que no supieras ya. Solo hace imposible ignorarlo.

¿Esa horquilla amplia entre P50 y P95? Todo el equipo ya sentía el caos. Simplemente no podían cuantificarlo, así que nunca se convirtió en conversación. ¿Esos sprints outlier? La gente los recordaba pero no podía articular por qué importaban para la planificación. ¿El hecho de que comprometerte a P50 es tirar una moneda al aire? En el fondo todos sospechaban que la fecha límite era irreal. Nadie tenía los datos para empujar en la otra dirección.

Monte Carlo coge la sensación difusa de "nuestras estimaciones suelen fallar" y la convierte en "tenemos un 85% de confianza en 9 sprints y aquí está el gráfico." Mueve la conversación de sensaciones a probabilidad. Y ahí es cuando las cosas empiezan a cambiar.

Si sigues haciendo planning poker cada sprint y sales de ahí con un número en el que nadie cree realmente, prueba a ejecutar una simulación. Solo una vez. Mete tus datos reales y mira qué dice. Lo peor que puede pasar es que confirme lo que ya sabías. Lo mejor que puede pasar es que te dé la munición para tener por fin una conversación honesta sobre cuándo narices se va a entregar eso.

Pruébalo aquí. Es gratis. Tus datos no salen de tu navegador. Y lleva menos tiempo que una ronda de planning poker.

Comparte este artículo

Boletín

Recibe Consejos de Productividad y Nuevas Herramientas Primero

Únete a creadores y desarrolladores que valoran la privacidad. En cada edición: nuevas herramientas, trucos de productividad y novedades — sin spam.

Acceso prioritario a nuevas herramientas
Cancela en cualquier momento, sin preguntas