Mi primer sistema distribuido en producción: millones de filas, microservicios y ningún agente de IA

Hoy es normal abrir un agente de IA, describirle un problema de arquitectura y recibir en minutos un diagrama, el código base y una lista de riesgos. Pero mi primer sistema distribuido en producción lo construí antes de que existiera todo eso. Sin copilotos ni agentes: solo documentación, prueba y error, y muchas horas mirando logs.
Y hay un detalle que todavía me hace reír: no sabía que era para el gobierno. Para mí era un proyecto más, con requerimientos, entregas y un montón de cosas nuevas por aprender. Recién después entendí dónde iba a vivir ese código: en el Portal Nacional de Transparencia de la Defensoría del Pueblo de Ecuador, el sitio donde la ciudadanía consulta y descarga la información pública de las instituciones del Estado.
Si lo hubiera sabido desde el inicio, probablemente me habría paralizado. A veces no saber el tamaño del reto es lo que te deja empezar.
El contexto: aprender y aplicar al mismo tiempo
Yo había aprendido hacía poco los conceptos que suenan en todas las charlas de arquitectura: microservicios, colas de mensajes, resiliencia, alta disponibilidad. Los entendía en teoría y había hecho ejercicios. Pero una cosa es un tutorial y otra muy distinta es un sistema en producción que va a usar todo un país.
Ese proyecto fue donde la teoría chocó con la realidad.
El problema: archivos CSV muy pesados
El corazón del sistema era aparentemente simple. Las instituciones subían su información de transparencia mediante un formulario, y esa información venía en archivos CSV, algunos con millones de filas. Con esos archivos había que hacer dos cosas muy distintas:
- Guardarlos tal cual, para que cualquier visitante del portal pudiera descargarlos.
- Procesarlos fila por fila: validar cada registro y guardarlo en una base de datos que alimentaría un súper buscador para que la ciudadanía encontrara información rápidamente.
La arquitectura quedó dividida en dos microservicios principales:
- Microservicio A: recibía el formulario con el CSV y sus datos asociados, guardaba el archivo para su descarga pública y luego se lo pasaba al siguiente servicio.
- Microservicio B: leía los millones de filas del archivo, validaba cada registro y lo guardaba en MongoDB, que era la base que consultaba el buscador.
En un diagrama se ve limpio: una caja, una flecha y otra caja. El problema estaba justamente en la flecha.
Lo más difícil: la comunicación entre servicios
De todo el proyecto, lo más complicado fue la comunicación y la transferencia de esos archivos tan pesados entre microservicios.
Cuando aprendes microservicios, los ejemplos suelen mandar mensajes pequeños: un ID, un evento, un JSON de pocos campos. Nadie te prepara para mover un archivo de cientos de megas entre dos servicios sin que algo se rompa en el camino. Aparecen preguntas que en el tutorial no existían:
- ¿Qué pasa si el servicio B se cae a mitad del archivo?
- ¿Cómo evitas que un archivo enorme se quede en memoria y tumbe el servicio?
- ¿Cómo sabes qué filas ya se procesaron y cuáles no?
- ¿Qué haces con las filas inválidas: detienes todo o continúas y reportas?
- ¿Cómo evitas que el servicio A se quede bloqueado esperando a que B termine?
Ahí entendí de verdad para qué sirven las colas, la resiliencia y la alta disponibilidad. Dejaron de ser palabras de una charla y se volvieron decisiones concretas con consecuencias reales.
La solución: no mover el archivo, mover la ruta
La clave fue darme cuenta de que el archivo no tenía que viajar entre servicios. Lo que tenía que viajar era la información de dónde estaba.
Así quedó el flujo:
- El microservicio A recibía el formulario y guardaba el CSV en un almacenamiento compartido. Ese mismo archivo era el que después descargaban los visitantes del portal, así que se guardaba una sola vez y servía para las dos cosas.
- Apenas el archivo quedaba guardado, A emitía un evento por Redis con un mensaje pequeño: básicamente, la ruta del archivo.
- Un worker en Python escuchaba esos eventos. Cuando llegaba uno, tomaba la ruta, abría el archivo directamente desde el almacenamiento compartido y empezaba a leer las filas, validarlas y guardarlas en MongoDB.
- El buscador consultaba MongoDB, y la ciudadanía podía encontrar la información en segundos.
Con este diseño, el microservicio A respondía rápido al usuario porque no tenía que esperar a que se procesaran millones de filas. El mensaje que viajaba por Redis era diminuto, sin importar si el archivo pesaba 1 MB o 500 MB. Y el trabajo pesado quedaba en un proceso dedicado a eso, que podía tomarse su tiempo.
Este enfoque tiene nombre en el mundo de la arquitectura: el patrón claim check. En lugar de mandar la carga completa por el canal de mensajes, la guardas en un lugar compartido y envías solo un “ticket” para reclamarla. En ese momento, para mí, simplemente era la solución que tenía sentido.
Lo que me llevé
La flecha del diagrama es la parte más difícil. Separar un sistema en servicios es fácil; lo complejo es cómo se hablan, qué pasa cuando uno falla y cómo se recupera el otro.
Los datos grandes cambian todas las reglas. Lo que funciona con 100 filas no funciona con millones. Memoria, tiempos, reintentos y validaciones tienen que pensarse a esa escala desde el principio.
La teoría solo se vuelve conocimiento cuando la usas. Aprendí más de microservicios en ese proyecto que en todos los cursos anteriores juntos.
No necesitas saberlo todo para empezar. Llegué a ese proyecto con conceptos recién aprendidos y mucha inseguridad. Lo resolví de todos modos: investigando, probando y equivocándome. Esa experiencia me dio la confianza para todo lo que construí después.
¿Y hoy?
Hoy, con agentes de IA, probablemente habría llegado a una primera versión mucho más rápido. Pero no estoy seguro de que la hubiera entendido igual. Hay aprendizajes que solo llegan cuando el problema te obliga a pensar cada pieza por tu cuenta.
Si estás empezando con arquitecturas distribuidas, mi consejo es simple: usa todas las herramientas que tengas, incluida la IA, pero asegúrate de entender por qué funciona lo que construyes. Esa diferencia se nota el día que algo falla en producción.
Cuento más historias como esta en TikTok: @andydev22.