No toda la deuda técnica merece pagarse

La deuda técnica no debería priorizarse por su existencia, sino por el coste, el riesgo y las limitaciones que introduce en el sistema.

Basta con que un proyecto lleve unos meses en marcha para que la deuda técnica aparezca en alguna conversación, casi siempre acompañada de las mismas frases:

Tenemos mucha deuda técnica.

Deberíamos dedicar algún sprint a reducirla.

Ambas suelen conducir a la misma conclusión: si existe esa deuda, deberíamos parar para saldarla. Pero quizá el problema empieza ahí.

Quizá estamos llamando deuda a demasiadas cosas. A decisiones que generan un coste, sí, pero también a código que simplemente no nos gusta.

En esa confusión, cualquier diferencia con nuestro ideal técnico termina convertida en una obligación pendiente.

La metáfora de la deuda técnica es brillante porque consigue explicar una idea compleja de forma sencilla: algunas decisiones nos permiten avanzar más rápido hoy a cambio de asumir un coste en el futuro.

Sin embargo, como ocurre con cualquier metáfora, también tiene sus límites.

Cuando hablamos de una deuda económica damos por hecho que, tarde o temprano, habrá que pagarla. Y esa idea ha terminado trasladándose al software casi sin darnos cuenta.

Pero ¿y si no toda la deuda técnica merece pagarse?

La deuda técnica no siempre nace de una mala decisión

En economía existen hipotecas, préstamos para comprar un coche o créditos al consumo. Y aunque todos son deuda, nadie diría que todos son igual de malos.

Lo importante no es la existencia de la deuda, sino el coste que genera y el valor que permite obtener.

Con la deuda técnica ocurre exactamente lo mismo.

Duplicar unas líneas de código para validar una idea rápidamente puede ser una decisión razonable. Del mismo modo, puede serlo posponer un refactor cuando sabemos que el módulo afectado desaparecerá dentro de unos meses.

Incluso mantener un proceso manual durante un tiempo puede tener sentido si automatizarlo hoy retrasaría una funcionalidad importante para el negocio.

La deuda técnica no siempre es consecuencia de una mala decisión. Muchas veces es simplemente el resultado de priorizar.

El coste de pagar también existe

Cuando hablamos de deuda técnica solemos olvidar que eliminarla también cuesta dinero. No solo por el tiempo dedicado, sino porque cada vez que modificamos código volvemos a introducir incertidumbre.

Tenemos que entender de nuevo el problema, desarrollar los cambios, revisarlos, probarlos, desplegarlos y validar que todo sigue funcionando como esperábamos.

Y, por experiencia, no es raro que una regresión inesperada termine revelando que las pruebas protegían bastante menos de lo que creíamos.

Por eso, pagar deuda técnica también es una inversión. Y, como cualquier inversión, debería estar justificada por el valor que aporta.

Sin embargo, es frecuente encontrar equipos que deciden eliminar deuda simplemente porque existe, sin observar primero cómo se comporta realmente el sistema ni preguntarse si está causando un problema, cuánto costaría corregirla o si podemos convivir con ella.

No toda la deuda acumula los mismos intereses

Imaginemos una clase con código duplicado. No es especialmente elegante y todo el equipo coincide en que sería mejor eliminar esa duplicación. Pero lleva cinco años funcionando, nunca ha provocado una incidencia ni dificulta añadir nuevas funcionalidades.

¿Realmente es prioritario dedicar tiempo a refactorizarla? Si no ralentiza el desarrollo, no aumenta el riesgo y no limita la evolución del sistema, quizá ni siquiera sea deuda. Puede que solo sea código que hoy escribiríamos de otra manera.

Ahora pensemos en un proceso manual que alguien tiene que ejecutar cada mañana. O en una consulta que ralentiza una operación crítica. O en una dependencia obsoleta que impide actualizar el resto del sistema.

A priori, pueden parecer problemas pequeños, pero en la práctica generan un coste todos los días. Consumen tiempo, aumentan el riesgo o limitan la capacidad de evolución del producto.

Esa es la deuda que realmente genera intereses. Y muchas veces no somos nosotros quienes los pagamos. Los paga quien ejecuta cada mañana la tarea manual, quien sufre los despliegues problemáticos o quien tiene que sortear continuamente las limitaciones del sistema. Pero, aunque no los veamos, terminan pagándose en tiempo, riesgo y capacidad de evolución.

Cambiar la pregunta

Por eso prefiero no medir la salud técnica por el número de elementos que desaparecen de una lista etiquetada como “deuda”. Ese backlog, además, rara vez se revisa con la frecuencia que imaginábamos al crearlo.

En los proyectos suelo plantear otras preguntas:

  • ¿Qué decisiones están ralentizando realmente al equipo?
  • ¿Cuáles aumentan el riesgo de cada despliegue?
  • ¿Cuáles dificultan la evolución del sistema?
  • ¿Cuáles tienen un impacto tangible para el negocio?

Responder a estas preguntas suele aportar mucho más valor que perseguir cualquier imperfección del código. Porque no todas las imperfecciones tienen el mismo coste. Y no todas merecen el mismo esfuerzo.

De detectar la deuda a decidir su prioridad

Las preguntas anteriores sirven para entender los intereses que está generando una deuda: si ralentiza al equipo, aumenta el riesgo de los despliegues, dificulta la evolución del sistema o tiene un impacto tangible para el negocio.

Pero detectar ese coste no significa que debamos actuar inmediatamente.

También tenemos que compararlo con el esfuerzo y el riesgo de corregirlo, y tener en cuenta durante cuánto tiempo seguiremos conviviendo con esa parte del sistema.

Una tarea manual de veinte minutos puede parecer insignificante. Repetida cada día durante varios años, quizá justifique una inversión considerable. Esa misma inversión tendría mucho menos sentido si el módulo que la provoca va a desaparecer dentro de unos meses.

No se trata de construir una fórmula exacta, sino de evitar que la incomodidad técnica pese más que el coste real del problema.

Convivir con la deuda también es una decisión

No vamos a eliminar todas las imperfecciones de un sistema, ni merece la pena intentarlo.

La arquitectura consiste en entender qué compromisos hemos asumido, cuánto nos están costando y cuáles empiezan a impedir que el producto evolucione. El backlog puede decirnos cuánta deuda hemos anotado. No puede decirnos cuál importa. Para eso hace falta criterio.