Diseñar un sistema para +10 millones de usuarios no es solo cuestión de agregar servidores. Estas son las estrategias reales que implementamos en RUNT 2.0.
El desafío
RUNT 2.0 es el Registro Único Nacional de Tránsito de Colombia. Procesa registros vehiculares, licencias, infracciones y más para toda la población del país. Los picos de tráfico pueden superar los 50K requests por segundo, especialmente en fechas de vencimiento de documentos.
Caché distribuido
Implementamos una estrategia de caché multinivel: L1 en memoria de la aplicación (Caffeine), L2 en Redis cluster. Las consultas más frecuentes (verificación de estado vehicular, consulta de licencias) se cacheaban con TTL variable según la volatilidad del dato. Esto redujo la carga a Oracle en un 70%.
Particionamiento de datos con Oracle
Las tablas principales tenían miles de millones de registros. Implementamos particionamiento por rango temporal y por región geográfica. Las consultas que antes tomaban 30 segundos pasaron a ejecutarse en menos de 200ms.
Patrones de resiliencia
- ▹ Circuit Breaker: Con Resilience4j para cada integración externa. Cuando un servicio downstream fallaba, el circuito se abría y respondíamos con datos cacheados.
- ▹ Bulkhead: Thread pools separados por tipo de operación. Un pico en consultas vehiculares no podía afectar el registro de licencias.
- ▹ Rate Limiting: Protección contra abusos y bots, con límites diferenciados por tipo de cliente (ciudadano, organismo de tránsito, sistema integrado).
Micro-frontends con Module Federation
El frontend se dividió en micro-apps independientes (SSIS, FUEC, RNA, RNS, SOP) usando Webpack Module Federation con Angular 16+. Cada equipo podía deployar independientemente sin afectar a los demás módulos.
Lección clave
La escalabilidad no es solo técnica. Requiere diseño organizacional: equipos autónomos, ownership claro, y la disciplina de medir antes de optimizar. El profiling real en producción siempre revela cuellos de botella que nunca hubieras predicho.