Monolith
Frontera compartida, no juicio de calidad
Monolith describe un perfil donde una parte sustancial del sistema comparte una frontera de construcción, evolución o deployment. La variante habitual reúne el comportamiento de una aplicación en una unidad desplegable, con componentes que colaboran localmente. El Atlas analiza esa frontera y sus consecuencias; no usa monolith como descalificación.
Richardson presenta una aplicación desplegada como unidad y explica beneficios y límites de esa elección. Monolithic Architecture. El perfil no determina por sí solo si las responsabilidades están bien separadas: un monolito puede tener módulos y contratos claros, o dependencias difíciles de controlar.
Monolith no equivale a Big Ball of Mud. La calidad de la estructura interna requiere otra evaluación. modular-monolith añade una disciplina explícita de límites dentro de la frontera común. architecture-profile explica por qué deployment, datos, comunicación y organización deben examinarse conjuntamente.
Proceso, unidad desplegable y sistema
Un proceso único es una implementación frecuente, pero no una definición suficiente para todos los sistemas. Puede haber varias instancias, workers que ejecutan el mismo artefacto, tareas programadas y dependencias externas. execution-model distingue sus triggers y lifecycles; deployment precisa qué software se instala conjuntamente. Conviene declarar qué aplicación o parte estamos caracterizando y qué se entrega conjuntamente.
Un servidor de base de datos separado no convierte automáticamente el comportamiento de la aplicación en microservicios. Tampoco una segunda instancia elimina la frontera común de release. Si los workers tienen contratos y ciclos de entrega realmente independientes, debe describirse esa distribución en lugar de esconderla bajo una etiqueta global.
La pregunta operativa es qué partes deben reconstruirse, comprobarse o coordinarse cuando cambia una capacidad. La pregunta estructural es qué dependencias propagan ese cambio. Un mismo deployment puede reunir módulos con bajo acoplamiento o imponer cambios transversales frecuentes.
Lectura mediante decision axes
| Eje | Lectura habitual y decisión pendiente |
|---|---|
| Decomposition | Módulos o componentes dentro de una frontera amplia. |
| Dependency Structure | Relaciones internas; la encapsulación no viene garantizada. |
| Communication | Llamadas locales frecuentes, además de integraciones externas. |
| Coordination | Coordinación local más directa cuando comparte recursos transaccionales. |
| Data Ownership | Puede compartir almacenamiento; todavía necesita responsabilidades claras. |
| Isolation | Runtime compartido frecuente; una dependencia puede afectar varias capacidades. |
| Tenancy | Puede alojar uno o varios tenants; el perfil no decide su aislamiento. |
| Deployment | Releases coordinados del conjunto o de su núcleo principal. |
| Execution Model | Peticiones, tareas y workers según implementación. |
| Scaling | Réplicas de la unidad; distintos recursos pueden seguir siendo límites comunes. |
La tabla describe tendencias y preguntas, no garantías. Una frontera de deployment no debe confundirse con una frontera de seguridad, de tenancy o con el alcance de todas las transacciones.
Comunicación y consistencia
La comunicación dentro del proceso evita parte de la latencia, serialización y ambigüedad propia de una llamada remota. Permite recorrer una operación con herramientas locales y reutilizar un contexto de ejecución. Sigue habiendo errores, concurrencia y dependencias lentas.
Cuando varias modificaciones usan el mismo recurso transaccional, una transacción local puede proteger invariantes sin coordinar commits entre servicios. No significa que toda la operación de negocio sea automáticamente atómica: enviar un correo o escribir en otro sistema conserva un límite externo.
dual-write-problem muestra esa separación cuando se intenta actualizar estado y publicar un mensaje. Compartir deployment tampoco autoriza cualquier acceso a datos internos. La claridad de ownership y de contratos ayuda a conservar capacidad de cambio incluso dentro de una misma aplicación.
Scaling y límites de fallo
Monolith no significa non-scalable. Una aplicación puede replicarse horizontalmente y usar cachés, réplicas de lectura o infraestructura distribuida. Microsoft documenta la duplicación de aplicaciones monolíticas y su deployment mediante contenedores. Common web application architectures.
El trade-off es la granularidad: aumentar réplicas puede duplicar capacidades que no necesitan crecer, mientras una base de datos o recurso compartido sigue saturado. Hay que medir dónde está el cuello de botella antes de atribuirlo al perfil.
Un fallo de proceso, agotamiento de memoria o cola de trabajo común puede afectar varios módulos. La modularidad del código no crea aislamiento de recursos. bulkhead y overload ayudan a analizar protecciones concretas; no requieren convertir cada responsabilidad en un servicio.
Delivery, pruebas y equipos
Una unidad principal suele simplificar el arranque local, los tests integrados, el inventario de versiones y la reversión del artefacto. El equipo necesita menos contratos de red internos y puede seguir una operación sin atravesar numerosos servicios.
La contrapartida es coordinar releases. Equipos que trabajan en módulos diferentes pueden compartir pipeline, ventanas de entrega o un cambio de esquema. Eso no impide ownership interno, pero limita algunas formas de autonomía de deployment y de elección tecnológica.
La observabilidad continúa siendo necesaria: tiempos por operación, saturación y fallos por capacidad permiten evitar que el agregado oculte problemas. Las pruebas de módulo y de integración cumplen funciones diferentes. Una suite lenta o una aprobación manual para todo cambio puede ser un problema del proceso de entrega, no una consecuencia inevitable del monolito.
Ejemplo de decisión situada
Supongamos una aplicación de gestión para un equipo pequeño donde pedidos y reservas cambian conjuntamente y el volumen permite replicar el conjunto. Mantener una unidad común puede reducir coordinación distribuida y facilitar una transacción local sobre esos datos.
La elección exige reconocer compromisos: catálogo y pedidos se entregan juntos; una tarea de importación podría competir por recursos; un esquema compartido necesita disciplina. Separar primero responsabilidades internas puede resolver cambios frecuentes sin introducir llamadas remotas.
Si más adelante una capacidad necesita un ciclo de entrega distinto, se evalúa con evidencia. No hay una obligación de extraerla. Fowler defiende considerar el costo de distribución y aprender límites, pero reconoce desacuerdos y experiencia limitada en su argumento. Monolith First.
Composición y uso razonable
Un monolito puede organizar su interior mediante Layered, Hexagonal o Vertical Slice; esas aproximaciones responden preguntas diferentes. También puede publicar o consumir eventos. Event-Driven Architecture no obliga a dividir deployment, y usar un broker no elimina la frontera monolítica de la aplicación.
Es razonable cuando coordinación local, costos operativos y capacidad del equipo pesan más que escalar o entregar capacidades por separado. Se reconsidera ante drivers comprobables, no por prestigio tecnológico. architectural-drivers y architectural-significance permiten justificar ese análisis; architecture-profiles compara alternativas sin convertirlas en niveles de madurez.