Diseñar para el día en que algo falle, no para el día en que todo funcione
Un sistema que funciona bien en condiciones normales no dice mucho todavía. Funcionar en el camino feliz es el mínimo esperado, no la prueba real. La prueba real llega cuando algo dentro del sistema deja de responder, y hay que ver qué pasa entonces.
Un equipo desarrolla un sistema de notificaciones automáticas para avisar a los usuarios cuando algo importante ocurre en su cuenta. Lo prueban a fondo antes de lanzarlo: envían miles de mensajes bajo distintas condiciones de carga, miden tiempos de entrega, verifican que el formato se vea bien en cada dispositivo. Todo funciona. El sistema se lanza.
Entornos donde no hay margen para intentarlo dos veces
La mayoría de los diseños se validan contra una sola pregunta: ¿funciona como se espera? Muy pocos se validan contra la segunda, más incómoda: ¿qué pasa exactamente cuando este componente falla a mitad de operación? Esa segunda pregunta es la que separa un sistema que resiste de uno que solo parece funcionar hasta que se le exige.
Nadie probó, en el sistema de notificaciones, qué pasaba si el servicio externo que realmente envía los mensajes se caía a la mitad de un lote de miles. No porque fuera difícil de probar, sino porque en las pruebas de carga siempre estuvo disponible y nadie se preguntó qué pasaría el día que no lo estuviera.
Por qué la mayoría de los diseños no llegan hasta ahí
Diseñar para el camino feliz es más rápido y más barato. Diseñar para los modos de falla exige tiempo adicional, presupuesto adicional, y aceptar que el alcance del proyecto va a crecer una vez que se mapean todos los escenarios donde algo puede salir mal. Es tentador detenerse antes de llegar ahí, sobre todo cuando el sistema ya "funciona" en las pruebas iniciales, como el de notificaciones.
Meses después de lanzado, el servicio externo de envío efectivamente se cae a mitad de un lote. El sistema no lo detecta como un error explícito: simplemente deja de intentar con los mensajes restantes y sigue operando como si nada hubiera pasado. La mitad de los usuarios de ese lote nunca recibe su notificación, y no queda ningún registro que indique que algo falló.
El mecanismo detrás
Diseñar anticipándose a fallas invierte el orden habitual: en vez de preguntar primero si el sistema funciona y dejar las fallas para después, se empieza por mapear los modos de falla posibles, y cada uno recibe una respuesta explícita antes de dar el sistema por terminado.
Después del incidente, el equipo del sistema de notificaciones aplica exactamente esa lógica al problema que ya ocurrió. Mapean qué pasa en cada punto donde el servicio externo puede fallar: al enviar, al confirmar la entrega, al reportar un error. Para cada uno, diseñan una respuesta explícita: si el envío falla, se reintenta un número limitado de veces; si el reintento también falla, la notificación no se descarta, se guarda como pendiente y se genera una alerta visible para que alguien la revise.
El principio que se puede llevar a cualquier proyecto
La siguiente vez que el servicio externo tiene una caída parcial, el sistema la absorbe sin perder ni una notificación: reintenta, y donde el reintento no basta, deja evidencia clara de lo que quedó pendiente en vez de fallar en silencio. La diferencia no fue una solución compleja. Fue haber hecho la pregunta correcta antes de dar el sistema por terminado, en vez de después de que ya había fallado en producción.
Esto cambia lo que significa "terminar" un diseño. No termina cuando el sistema opera bien, termina cuando se sabe, con evidencia, qué hace en cada uno de sus peores escenarios posibles.
La próxima vez que un sistema se dé por terminado, vale la pena preguntar qué tan a fondo se probó contra sus propios modos de falla, no solo contra el día en que todo sale bien.
¿El sistema que más te preocupa hoy ya fue puesto a prueba contra sus propios modos de falla, o solo contra el día en que todo sale bien?