De Microservicios a Monolitos Modulares: Tendencias de Arquitectura 2026
El backlash contra los microservicios
Durante la ultima decada, los microservicios fueron la arquitectura por defecto para cualquier proyecto nuevo. "Si no estas haciendo microservicios, estas haciendo legacy" era el mantra implicito de la industria. Pero en 2025-2026, las voces criticas se han multiplicado y un patron claro ha emergido: muchas empresas estan consolidando sus microservicios en monolitos modulares.
El caso mas sonado fue el de Amazon Prime Video, que en 2023 publico como migraron su servicio de monitoreo de calidad de video de una arquitectura de microservicios serverless a un monolito, reduciendo costos en un 90%. Segment, Shopify e Istio siguieron caminos similares.
El problema no es que los microservicios sean malos — es que la mayoria de equipos adoptaron la complejidad distribuida sin necesitar realmente la escalabilidad independiente que justifica esa complejidad.
¿Que es un monolito modular?
Un monolito modular es una aplicacion que se despliega como una sola unidad pero esta organizada internamente en modulos con limites claros y encapsulados. Cada modulo es dueno de su dominio de negocio, tiene su propia API interna, y puede tener su propia capa de persistencia.
La diferencia clave con un monolito tradicional (big ball of mud) es la disciplina en los limites:
- Los modulos no acceden directamente a las tablas de otros modulos
- La comunicacion entre modulos es a traves de interfaces publicas definidas
- Cada modulo puede evolucionar internamente sin afectar a otros
- Los modulos pueden extraerse a servicios independientes si la escala lo justifica

Limites de modulo y encapsulacion
El exito de un monolito modular depende enteramente de la calidad de sus limites de modulo. Un modulo bien definido sigue estos principios:
- Alta cohesion — todo lo que cambia junto vive junto
- Bajo acoplamiento — los modulos se comunican a traves de contratos estables
- Encapsulacion — los detalles internos no se exponen a otros modulos
- Alineacion con el dominio — los limites del modulo reflejan los bounded contexts de DDD
Veamos como se estructura un modulo en Spring Boot con Spring Modulith:
1// Estructura de paquetes de un monolito modular con Spring Modulith
2//
3// com.example.shop/
4// ├── order/ ← Módulo de pedidos
5// │ ├── Order.java ← Aggregate root (package-private)
6// │ ├── OrderItem.java ← Entidad interna (package-private)
7// │ ├── OrderRepository.java ← Repositorio (package-private)
8// │ ├── OrderService.java ← API pública del módulo
9// │ └── OrderCompleted.java ← Evento de dominio
10// ├── inventory/ ← Módulo de inventario
11// │ ├── InventoryService.java ← API pública
12// │ ├── Stock.java ← Entidad interna
13// │ └── StockReserved.java ← Evento de dominio
14// └── payment/ ← Módulo de pagos
15// ├── PaymentService.java ← API pública
16// └── PaymentConfirmed.java ← Evento de dominio
17
18// OrderService.java — API pública del módulo de pedidos
19package com.example.shop.order;
20
21import org.springframework.modulith.events.ApplicationModuleListener;
22import org.springframework.context.ApplicationEventPublisher;
23import org.springframework.stereotype.Service;
24import org.springframework.transaction.annotation.Transactional;
25
26@Service
27@Transactional
28public class OrderService {
29
30 private final OrderRepository orderRepository;
31 private final ApplicationEventPublisher events;
32
33 public OrderService(OrderRepository orderRepository,
34 ApplicationEventPublisher events) {
35 this.orderRepository = orderRepository;
36 this.events = events;
37 }
38
39 public OrderSummary createOrder(CreateOrderRequest request) {
40 var order = Order.create(request.customerId(), request.items());
41 orderRepository.save(order);
42
43 // Publicar evento de dominio — otros módulos reaccionan
44 events.publishEvent(new OrderCompleted(
45 order.getId(),
46 order.getCustomerId(),
47 order.getTotalAmount()
48 ));
49
50 return order.toSummary();
51 }
52
53 // Solo expone un DTO, nunca la entidad interna
54 public OrderSummary findOrder(Long orderId) {
55 return orderRepository.findById(orderId)
56 .map(Order::toSummary)
57 .orElseThrow(() -> new OrderNotFoundException(orderId));
58 }
59}
Spring Modulith: modulos de primera clase en Spring
Spring Modulith es el framework oficial de Spring para construir monolitos modulares. Proporciona tres capacidades fundamentales:
- Verificacion de estructura — tests automatizados que validan que los modulos respetan sus limites
- Eventos de dominio — comunicacion asincrona entre modulos con garantia de entrega
- Documentacion automatica — genera diagramas de dependencias entre modulos
1// ModularityTests.java — Verificar los límites del módulo
2package com.example.shop;
3
4import org.junit.jupiter.api.Test;
5import org.springframework.modulith.core.ApplicationModules;
6import org.springframework.modulith.docs.Documenter;
7
8class ModularityTests {
9
10 ApplicationModules modules = ApplicationModules.of(ShopApplication.class);
11
12 @Test
13 void shouldBeCompliant() {
14 // Falla si un módulo accede a clases internas de otro
15 modules.verify();
16 }
17
18 @Test
19 void shouldGenerateDocumentation() {
20 new Documenter(modules)
21 .writeModulesAsPlantUml() // Diagrama UML
22 .writeIndividualModulesAsPlantUml()
23 .writeModuleCanvases(); // Canvas por módulo
24 }
25}
26
27// InventoryEventListener.java — Reaccionar a eventos de otro módulo
28package com.example.shop.inventory;
29
30import com.example.shop.order.OrderCompleted;
31import org.springframework.modulith.events.ApplicationModuleListener;
32import org.springframework.stereotype.Component;
33
34@Component
35class InventoryEventListener {
36
37 private final StockRepository stockRepository;
38
39 InventoryEventListener(StockRepository stockRepository) {
40 this.stockRepository = stockRepository;
41 }
42
43 @ApplicationModuleListener
44 void onOrderCompleted(OrderCompleted event) {
45 // Reservar stock automáticamente cuando se completa un pedido
46 event.items().forEach(item -> {
47 var stock = stockRepository.findByProductId(item.productId());
48 stock.reserve(item.quantity());
49 stockRepository.save(stock);
50 });
51 }
52}
modules.verify() en tu pipeline de CI para que las violaciones no lleguen a produccion.
.NET Aspire: el enfoque de Microsoft
En el ecosistema .NET, Aspire representa la respuesta de Microsoft al problema de la complejidad distribuida. Aunque Aspire no es exclusivamente para monolitos modulares, proporciona herramientas que facilitan tanto la arquitectura modular como la distribuida.
Aspire ofrece:
- App Model — define la topologia de tu aplicacion como codigo
- Service Discovery — resolucion automatica de dependencias entre componentes
- Dashboard — observabilidad integrada con OpenTelemetry
- Health checks — verificacion automatica de estado de dependencias

Base de datos por modulo vs base de datos compartida
Una de las decisiones mas debatidas en monolitos modulares es la estrategia de persistencia. Hay tres enfoques principales:
| Estrategia | Ventajas | Desventajas |
|---|---|---|
| Schema por modulo | Aislamiento logico, una sola instancia de BD | Requiere disciplina para no hacer JOINs entre schemas |
| Base de datos por modulo | Aislamiento total, migrable a microservicios | Complejidad operacional, sin transacciones distribuidas nativas |
| Tablas compartidas con ownership | Simple, transacciones ACID completas | Riesgo de acoplamiento si no se respeta el ownership |
1-- Enfoque recomendado: schema por módulo
2-- Cada módulo tiene su propio schema en la misma base de datos
3
4CREATE SCHEMA IF NOT EXISTS orders;
5CREATE SCHEMA IF NOT EXISTS inventory;
6CREATE SCHEMA IF NOT EXISTS payments;
7
8-- Módulo orders: solo este módulo accede a estas tablas
9CREATE TABLE orders.orders (
10 id BIGSERIAL PRIMARY KEY,
11 customer_id BIGINT NOT NULL,
12 status VARCHAR(20) NOT NULL DEFAULT 'PENDING',
13 total DECIMAL(12,2) NOT NULL,
14 created_at TIMESTAMP DEFAULT NOW()
15);
16
17CREATE TABLE orders.order_items (
18 id BIGSERIAL PRIMARY KEY,
19 order_id BIGINT REFERENCES orders.orders(id),
20 product_id BIGINT NOT NULL, -- referencia lógica, NO FK a inventory
21 quantity INT NOT NULL,
22 unit_price DECIMAL(10,2) NOT NULL
23);
24
25-- Módulo inventory: aislado en su propio schema
26CREATE TABLE inventory.products (
27 id BIGSERIAL PRIMARY KEY,
28 name VARCHAR(255) NOT NULL,
29 sku VARCHAR(50) UNIQUE NOT NULL,
30 stock INT NOT NULL DEFAULT 0
31);
32
33-- NO crear foreign keys entre schemas diferentes
34-- La consistencia se mantiene con eventos de dominio
Comunicacion entre modulos
En un monolito modular, los modulos se comunican de dos formas:
- Llamadas sincronas — un modulo invoca la API publica de otro directamente (metodo de servicio)
- Eventos de dominio — un modulo publica un evento y otros reaccionan de forma asincrona
La regla general es: usa llamadas sincronas para queries (necesitas la respuesta ahora) y eventos para comandos (notificar que algo paso, sin esperar respuesta).
Spring Modulith hace esto especialmente elegante con su sistema de eventos transaccionales:
- Los eventos se publican dentro de la transaccion del modulo emisor
- Se persisten en una tabla de outbox para garantizar entrega
- Los listeners se ejecutan en transacciones separadas
- Si un listener falla, se reintenta automaticamente
event_publication y se procesan de forma asíncrona, garantizando at-least-once delivery sin necesitar un message broker externo.
¿Cuando los microservicios siguen teniendo sentido?
El monolito modular no es la respuesta universal. Los microservicios siguen siendo la mejor opcion cuando:
- Escala independiente real — un componente necesita 100x los recursos de otro
- Equipos grandes y autonomos — mas de 50-100 desarrolladores con ownership claro
- Stacks tecnologicos diferentes — un servicio necesita Python/ML mientras otro usa Java
- Requisitos de deployment independiente — necesitas desplegar un componente 10 veces al dia sin tocar los demas
- Aislamiento de fallos critico — el fallo de un componente no debe afectar a otros
La clave es que estas son decisiones que debes tomar basandote en necesidades reales medidas, no en lo que esta de moda en las conferencias.
Ruta de migracion: de microservicios a monolito modular
Si ya tienes microservicios y quieres consolidar, la migracion no es trivial pero sigue un patron predecible:
- Identificar grupos de servicios — encuentra servicios que siempre se despliegan juntos o que tienen comunicacion intensa entre si
- Definir modulos target — mapea cada grupo a un modulo en el monolito
- Consolidar gradualmente — migra un grupo a la vez, manteniendo compatibilidad con los servicios que aun son independientes
- Reemplazar HTTP por llamadas directas — las llamadas entre servicios consolidados pasan a ser invocaciones de metodo
- Unificar persistencia — consolida las bases de datos en schemas dentro de una sola instancia
- Eliminar infraestructura — retira los service meshes, API gateways y herramientas de orquestacion que ya no necesitas
Casos reales y lecciones aprendidas
Veamos que han hecho empresas reales:
- Amazon Prime Video — migro de Step Functions + Lambda a un monolito, ahorrando 90% en costos de infraestructura. La razon: la comunicacion entre microservicios era el cuello de botella
- Segment — consolido mas de 100 microservicios en un monolito modular. El resultado: 5x menos incidentes operacionales y ciclos de desarrollo mas rapidos
- Shopify — nunca abandono completamente el monolito. En lugar de migrar a microservicios, invirtieron en modularizar su monolito Ruby on Rails con componentes bien encapsulados
- Istio — el service mesh de Google consolido 8 microservicios en un solo binario (Istiod), simplificando drasticamente la operacion y el deployment
El patron es consistente: la complejidad distribuida tiene un costo real, y muchas organizaciones descubren que un monolito bien estructurado les da mejor velocidad de desarrollo, menor costo operacional y suficiente escalabilidad para sus necesidades reales.
La leccion mas importante es que la arquitectura debe ser una decision pragmatica basada en las necesidades del equipo y del negocio, no una moda. En 2026, el monolito modular ha dejado de ser "hacer las cosas mal" para convertirse en una opcion arquitectonica legitima y, para muchos equipos, superior.
Comments
Sign in to leave a comment
No comments yet. Be the first!