← Volver al blog

arquitectura · · 4 min de lectura

Arquitectura de software que escala: decisiones que tomas hoy y pagas mañana

Monolito modular, microservicios, capas y límites claros: una guía práctica para diseñar sistemas que crecen con tu negocio sin reescribirlos cada año.

Bryan BolívarIngeniero de Sistemas
Diagrama de módulos organizados en tres capas conectadas, con un módulo central resaltado en naranja

Cada sistema tiene una arquitectura, aunque nadie la haya diseñado. La diferencia es si la elegiste tú o si fue el resultado accidental de cientos de decisiones pequeñas. Y esas decisiones se cobran tarde: cuando el equipo crece, cuando llega un cliente grande o cuando una funcionalidad “sencilla” tarda tres sprints porque toca medio sistema.

Estas son las ideas que aplicamos al diseñar plataformas que necesitan crecer.

La arquitectura es un problema de cambio

Una buena arquitectura no es la que tiene más diagramas ni la que usa la tecnología de moda. Es la que permite cambiar el sistema con poco riesgo y poco costo. Por eso la primera pregunta no es técnica: ¿qué partes del negocio van a cambiar más en los próximos dos años?

Las reglas de precios, los medios de pago o las integraciones con terceros suelen cambiar mucho. La gestión de usuarios o la facturación base, bastante menos. La arquitectura debe aislar lo volátil para que su evolución no arrastre al resto.

Empieza con un monolito modular

Para la mayoría de productos nuevos recomendamos un monolito modular: una sola aplicación desplegable, dividida internamente en módulos con límites estrictos.

src/
  facturacion/   → dominio, casos de uso, adaptadores
  inventario/
  clientes/
  compartido/    → solo utilidades sin lógica de negocio

Cada módulo expone una interfaz pública y oculta su implementación. Ningún módulo lee directamente las tablas de otro. Con esa disciplina obtienes casi todos los beneficios de los microservicios (equipos independientes, código entendible) sin pagar su costo operativo: redes que fallan, consistencia eventual, trazas distribuidas y despliegues coordinados.

Los microservicios resuelven un problema de organización, no de rendimiento. Si no tienes varios equipos que se bloquean entre sí, probablemente todavía no los necesitas.

Cuándo sí separar un servicio

Extraer un módulo a un servicio independiente tiene sentido cuando se cumple al menos una de estas condiciones:

  • Escala distinta: una parte recibe diez o cien veces más carga que el resto (por ejemplo, la ingesta de eventos o la búsqueda).
  • Ritmo de cambio distinto: un equipo necesita desplegar varias veces al día sin esperar al resto.
  • Requisitos técnicos distintos: un proceso de machine learning en Python junto a un backend en Node.js, o un componente con exigencias de seguridad especiales.

Si los límites del monolito modular están bien definidos, esa extracción es un trabajo de semanas, no una reescritura.

Capas: el dominio en el centro

Dentro de cada módulo separamos tres responsabilidades:

  1. Dominio: las reglas del negocio, sin dependencias de frameworks, bases de datos ni APIs externas. Es el código más valioso y el más fácil de probar.
  2. Aplicación: los casos de uso que orquestan el dominio (“emitir factura”, “reservar inventario”).
  3. Infraestructura: base de datos, colas, proveedores externos. Se conecta al dominio mediante interfaces.

La regla de oro: las dependencias apuntan hacia el dominio. Cambiar de proveedor de pagos o de base de datos debería tocar un adaptador, no tus reglas de negocio.

Datos: el acoplamiento que nadie ve

El acoplamiento más peligroso no está en el código, sino en la base de datos. Cuando cinco módulos leen y escriben la misma tabla, cualquier cambio de esquema se vuelve una negociación.

Algunas prácticas que nos funcionan:

  • Cada módulo es dueño de sus tablas; los demás consultan a través de su interfaz.
  • Para comunicar cambios entre módulos usamos eventos de dominio (“FacturaEmitida”), con el patrón outbox cuando necesitamos garantizar que el evento se publique.
  • Las migraciones son compatibles hacia atrás: primero se agrega, luego se migra y al final se elimina.

Decisiones documentadas

Cada decisión importante queda registrada en un ADR (Architecture Decision Record): una página con el contexto, las opciones evaluadas, la decisión y sus consecuencias. Seis meses después, cuando alguien pregunte “¿por qué hicimos esto así?”, la respuesta existe y no depende de la memoria de nadie.

Observabilidad desde el primer despliegue

No puedes escalar lo que no puedes ver. Desde la primera versión incluimos:

  • Logs estructurados con un identificador de solicitud que atraviesa todo el sistema.
  • Métricas de negocio y técnicas: pedidos por minuto, latencia p95, tasa de errores.
  • Alertas basadas en síntomas que siente el usuario, no en cada pico de CPU.

Lista de verificación

Antes de dar por buena una arquitectura, revisamos:

  • ¿Podemos explicar los límites de cada módulo en una frase?
  • ¿Un desarrollador nuevo puede hacer un cambio en un módulo sin entender todo el sistema?
  • ¿Podemos reemplazar un proveedor externo tocando un solo adaptador?
  • ¿Sabemos, con datos, cuál es el cuello de botella actual?

La arquitectura no se diseña una vez: se cuida en cada sprint. Si tu plataforma se está volviendo lenta de cambiar, hablemos y revisamos juntos por dónde empezar.

// contacto

Hablemos de tu proyecto