Todas las contribuciones
Ingenieríamicroservicesarchitecturedevops

De monolito a microservicios: guía práctica para empresas en crecimiento

Guía técnica para migrar de una arquitectura monolítica a microservicios. Patrones, antipatrones, decisiones de dominio y lecciones aprendidas en producción.

Numoru EngineeringPublicado el 5 de abril de 202615 min de lectura
Compartir
6 sem → diario
Ciclo de release post-strangler
Caso cliente al final
3 squads
De 1 equipo bloqueado a 3 autónomos
Unlock de team-scale
$45-180k
Ticket engagement de migración
Por tamaño de org
9-18 mo
Duración típica del programa
Strangler fig

Cuándo NO migrar a microservicios

Antes de hablar de cómo, hablemos de cuándo no deberías:

  • Tu equipo tiene menos de 10 ingenieros: El overhead operacional de microservicios (networking, observabilidad, deploy independiente) supera los beneficios.
  • Tu monolito funciona bien: "Microservicios" no es sinónimo de "moderno". Un monolito bien estructurado es más fácil de mantener.
  • No tienes problemas de escala diferenciada: Si todas las partes de tu sistema necesitan la misma capacidad, microservicios añade complejidad sin beneficio.

La razón correcta para migrar es: necesitas escalar, deployar o evolucionar partes del sistema de forma independiente, y tu monolito se ha convertido en un cuello de botella organizacional.

Señales de que es hora de migrar

  1. Deploys son arriesgados: Un cambio en el módulo de pagos requiere redesployar todo el sistema, incluyendo el catálogo de productos.
  2. Equipos se bloquean mutuamente: El equipo de checkout espera a que el equipo de inventario termine su feature porque comparten la misma base de código.
  3. Escala desproporcional: Tu API de búsqueda recibe 100× más tráfico que tu módulo de reportes, pero ambos corren en los mismos servidores.
  4. Ciclos de release largos: Los releases son mensuales porque coordinar todos los cambios en un solo deploy es complejo.

Estrategia: Strangler Fig, no Big Bang

Nunca reescribas todo de cero. La estrategia Strangler Fig (higuera estranguladora) consiste en:

  1. Identificar el dominio más independiente con el mayor beneficio de separación
  2. Extraerlo como servicio detrás de la misma API
  3. Enrutar tráfico gradualmente (10% → 50% → 100%)
  4. Repetir con el siguiente dominio

Paso 1: Bounded Contexts

Antes de tocar código, mapea tus bounded contexts con el equipo:

Monolito actual:
├── Users & Auth        → Contexto: Identity
├── Product Catalog     → Contexto: Catalog
├── Shopping Cart       → Contexto: Cart
├── Checkout & Payments → Contexto: Payments
├── Order Fulfillment   → Contexto: Fulfillment
├── Notifications       → Contexto: Notifications
└── Reporting           → Contexto: Analytics

Cada contexto tiene datos propios, reglas propias y un equipo responsable. Si dos contextos comparten tablas en la base de datos, necesitas resolver esa dependencia antes de separarlos.

Paso 2: La primera extracción

Elige el servicio que:

  • Tiene menor acoplamiento con el resto del sistema
  • Tiene mayor beneficio de escala independiente
  • El equipo responsable está motivado y disponible

En la mayoría de los casos, Notifications o Analytics son buenos candidatos iniciales: tienen pocas dependencias entrantes, no están en el path crítico de la transacción, y el equipo puede fallar sin afectar al checkout.

Paso 3: El patrón de comunicación

Para la comunicación entre servicios:

PatrónCuándo usarloCuándo evitarlo
HTTP/REST síncronoConsultas simples, baja latencia requeridaOperaciones que pueden fallar y necesitan retry
Eventos asincrónicos (Kafka/NATS)Notificaciones, analytics, procesos eventualCuando necesitas respuesta inmediata
gRPCComunicación interna de alto volumenAPIs públicas, compatibilidad con browsers

Regla de oro: Si el servicio A necesita esperar la respuesta de B para continuar, usa síncrono. Si A solo necesita que B eventualmente se entere, usa eventos.

Antipatrones que hemos visto

El microservicio distribuido monolítico

Servicio A → Servicio B → Servicio C → Servicio D → Base de datos compartida

Si todos tus microservicios comparten una base de datos y se llaman en cadena síncrona, no tienes microservicios — tienes un monolito distribuido con latencia extra y más puntos de falla.

El nano-servicio

Un servicio por cada entidad de la base de datos. UserService, AddressService, PhoneService... Si un cambio de dominio requiere modificar 5 servicios, la granularidad es excesiva.

CRUD como servicio

Si tu "microservicio" es un wrapper de una tabla con endpoints GET/POST/PUT/DELETE y cero lógica de negocio, no es un servicio — es una capa de acceso a datos innecesaria.

Lo que necesitas desde el día 1

No extraigas el primer servicio sin tener esto resuelto:

Observabilidad

  • Distributed tracing (Jaeger/Tempo): Cada request debe ser trazable a través de todos los servicios
  • Logs centralizados (ELK/Loki): Un solo lugar para buscar errores
  • Métricas (Prometheus/Grafana): Latencia p50/p95/p99 por servicio, tasa de errores, saturación

CI/CD por servicio

Cada servicio tiene su propio pipeline:

  • Build independiente
  • Tests independientes
  • Deploy independiente
  • Rollback independiente

Si un deploy de Payments falla, no debería afectar a Catalog.

Service mesh o API gateway

Para routing, rate limiting, circuit breaking y mTLS entre servicios. Opciones:

  • Istio/Linkerd para Kubernetes
  • Kong/Traefik como API gateway
  • NGINX con configuración manual (viable para < 10 servicios)

Caso real: De 6 semanas a releases diarios

Un marketplace con el que trabajamos tenía:

  • Monolito de 4 años en Python/Django
  • 15 ingenieros en 3 equipos
  • Releases cada 6 semanas con ventana de deploy de 4 horas
  • 3 incidentes mayores en los últimos 6 meses por deploys fallidos

Lo que hicimos

  1. Mes 1: Mapeamos bounded contexts, identificamos 6 dominios, priorizamos Notifications y Analytics como primeras extracciones
  2. Mes 2-3: Extraímos Notifications como servicio en Go con NATS para eventos. Montamos observabilidad (Grafana + Jaeger + Loki)
  3. Mes 3-4: Extraímos Payments como servicio en Go con PostgreSQL propio. Implementamos saga pattern para coordinación con el monolito
  4. Mes 4-5: CI/CD independiente por servicio en GitHub Actions. Feature flags con LaunchDarkly
  5. Mes 5-6: Extraímos Catalog. A este punto el equipo ya dominaba el patrón

Resultados

MétricaAntesDespués
Frecuencia de deployCada 6 semanasDiario
Ventana de deploy4 horas< 5 minutos
Incidentes por deploy~0.5< 0.05
Tiempo de onboarding3 semanas1 semana (por servicio)
Escala del equipo15 → bloqueados15 → 3 squads autónomos

Impacto de negocio

Business & commercial impact

Cómo Numoru vende una migración

La oferta productizada es un Architecture Fitness Assessment ($9,500, 3 semanas) que produce un yes/no sobre si microservicios tienen sentido y, si sí, la lista priorizada de seams. Desde ahí, un retainer por fases maneja el programa strangler — típicamente 9-18 meses — con exit criteria claros en lugar de un rebuild abierto.

Ticket por comprador (Numoru, USD)

Scale-up SaaS (30-100 eng)
Desbloquear ciclo de deploy + onboard squads nuevos.
$80,000 – 180,000
12-18 mo + $6k/mes MSP
E-commerce alto tráfico
Separar checkout + catálogo + search.
$55,000 – 140,000
9-12 mo
Fintech post-IPO-prep
Boundary de compliance + reducir blast-radius.
$120,000 – 280,000
18 mo + audit
Modernización IT corporativa
Romper monolito legacy on-prem para cloud + autonomía.
$180,000 – 450,000
RFP
Solo assessment
CTO quiere opinión externa antes de comprometer.
$9,500
3 sem
Public case studySoftware consulting · Global · 2015-2024

Martin Fowler — Strangler Fig / MonolithFirst

Challenge
Codificar por qué los equipos se queman con migraciones big-bang y cómo evitarlo.
Solution
El blog de Fowler y casos ThoughtWorks popularizaron el patrón strangler fig. La recomendación sigue: la mayoría de los wins vienen de autonomía de equipo, no de calidad de código.
Results
Migraciones públicas
100+
Catalogadas en ThoughtWorks
Mejora cycle-time
3-10×
Típico multi-trimestre
Blast radius incidentes
-60 a -90%
Post-descomposición
Public case studyResearch industria · Global · 2024

DORA / State of DevOps

Challenge
Medir delivery performance vs decisiones de arquitectura y diseño organizacional.
Solution
El equipo DORA de Google publica el reporte anual correlacionando arquitectura, estructura de equipo y deploy cadence.
Results
Elite performers
18%
Deploy múltiple por día
Low performers
31%
Release menos de mensual
Predictor de independencia de equipo
Fuerte
De status elite

Migración strangler para SaaS de 30 ingenieros (12 meses)

Payback: 6 months
Assumptions
Tamaño equipo30 eng
Ciclo release actual6 sem
Release post-migraciónDiario
Revenue en riesgo por ciclo lento$1.2M / año
Overhead de infra agregado$40,000 / año
Engagement de migración$140,000
MSP ongoing$6,000 / mes
Migración (one-time)−$140,000
MSP (12 mo × $6k)−$72,000
Overhead de infra−$40,000
Velocity de revenue capturado+$780,000
Runway de hiring extendido+$240,000
Contribución neta año 1+$768,000
Assessment
$9,500one-time
3 sem. Yes/no + plan.
  • Review DDD
  • Mapeo deploy-graph
  • Priorización seams
  • Exit criteria + scorecard
Retainer strangler
$80,000 – 220,000engagement
Programa 9-18 mo con checkpoints.
  • Extracción seam por seam
  • Observabilidad-first
  • Enablement platform team
  • Revisión ejecutiva trimestral
  • Planes de rollback
MSP
$4,000 – 12,000/ mes
Mantener saludable la plataforma.
  • Hardening CI/CD + infra
  • Review de costo + right-sizing
  • Audit trimestral
  • On-call incidentes

Conclusión

La migración a microservicios no es un proyecto técnico — es un proyecto organizacional que usa técnicas técnicas. Si tu estructura de equipos no cambia, tus servicios terminarán replicando las dependencias del monolito (Ley de Conway).

Empieza por el dominio más independiente, invierte en observabilidad antes de extraer nada, y recuerda: el objetivo no es tener microservicios — es tener equipos que pueden entregar valor de forma independiente.

¿Quieres resultados así para tu empresa?

Iniciar conversación
Compartir