RH
Article
(01)

Mi verdad sobre Monolitos y Microservicios: Experiencias y elección

En un mundo donde 'microservicios' es el mantra, te cuento por qué sigo apostando por monolitos bien pensados. Menos complejidad, más eficiencia y equipos fe...

Por
515 Vistas
arquitectura softwaremonolitomicroserviciosdesarrollo webexperiencia devbuenas prácticas

¿Monolito? ¿En serio, Roberto? ¡Pero si estamos en 2024!

Uf, ya me veo las cejas levantadas de algunos colegas. Lo sé, lo sé. En el mundillo del desarrollo, parece que si no hablas de microservicios, de Kubernetes, de Serverless y de la última filigrana de arquitectura distribuida, es que te has quedado en la prehistoria. Y mira, no me malinterpretes. He trasteado con microservicios, he visto proyectos que los usan de maravilla y entiendo su atractivo. Pero si te soy sincero, la gran mayoría de las veces, para el tipo de proyectos en los que me muevo, y te lo digo desde la trinchera, un buen monolito bien estructurado nos ha dado más alegrías que quebraderos de cabeza.


Es como esa fiebre que te entra por comprar la cámara más profesional del mercado cuando lo único que vas a hacer son fotos de tu gato. ¿Necesitas un equipo de cine para grabar el cumpleaños de tu sobrino? Pues eso. A veces, la herramienta más potente no es la más adecuada, sino la que mejor se adapta a tus necesidades reales. Y en mi experiencia, la realidad de muchos proyectos no es la de Google o Netflix.


Mi experiencia con la "micro-fiebre"

He estado en equipos donde la palabra 'microservicio' era casi un dogma. Se hablaba de escalabilidad horizontal, de independencia de equipos, de la posibilidad de usar diferentes tecnologías para cada servicio... y todo eso suena a música celestial, ¿verdad? Pero la práctica, amigos, es otra cosa. Recuerdo un proyecto en particular donde empezamos con la premisa de que todo sería microservicios. Éramos un equipo de siete personas. Un proyecto de tamaño medio, un SaaS para gestión interna de empresas. Lo que era una única aplicación con una base de datos, se dividió en cinco o seis "servicios" desde el principio.


Al principio, todo era ilusión. Pero pronto empezaron los retos. El despliegue se convirtió en una odisea. Un cambio pequeño en una entidad transversal, por ejemplo, en la autenticación, implicaba tocar dos o tres repositorios, desplegar dos o tres servicios diferentes, coordinar versiones. Los logs, que antes eran relativamente sencillos de seguir, ahora estaban repartidos por todas partes. ¿Depurar un error que implicaba a dos servicios? ¡Uff! Horas de traceo, de entender la comunicación asíncrona, los reintentos, los fallos de red entre servicios que estaban en la misma máquina virtual. La gente se empezaba a frustrar, el ritmo bajaba. La famosa "independencia" se traducía en "dependencia de un montón de cosas más pequeñas y complejas".


Y ni hablar del coste. No solo el monetario de más infraestructura (bases de datos para cada servicio, servicios de mensajería, balanceadores de carga...), sino el coste cognitivo. Cada nuevo desarrollador que entraba tardaba el doble en entender la arquitectura general, en saber dónde estaba qué y cómo se comunicaba todo. La "velocidad de desarrollo" que nos habían prometido se diluía en la complejidad operacional.


¿Por qué me parece importante el "monolito bien hecho"?

Mira, al final del día, lo que buscamos es construir software que funcione, que sea mantenible y que se pueda entregar rápido y con calidad. Y aquí es donde el monolito, bien diseñado, brilla con luz propia para muchos escenarios. Cuando hablo de "monolito bien estructurado", no me refiero a la "big ball of mud" del pasado, ese monstruo indomable donde todo estaba mezclado sin sentido. Me refiero a un monolito donde las responsabilidades están claras, los módulos están bien separados, con interfaces bien definidas, y donde la cohesión interna es alta y el acoplamiento entre módulos es bajo.


Piénsalo así: en un monolito, la comunicación entre "módulos" (o dominios funcionales, si quieres llamarlos así) es simplemente una llamada a una función o a una clase en memoria. Rápido, directo, sin latencias de red, sin problemas de serialización/deserialización, sin la complejidad de la mensajería asíncrona o los puntos de fallo distribuidos. El despliegue es una unidad. Los logs están en un solo sitio. La depuración es mucho más sencilla. Para equipos pequeños o medianos, esto se traduce directamente en:

  • Menos complejidad operativa: Menos cosas que monitorizar, menos servicios que desplegar, menos infraestructura que mantener.
  • Mayor velocidad de desarrollo: Los desarrolladores entienden el sistema más rápido, los cambios son más fáciles de propagar y probar.
  • Reducción de costes: Tanto en infraestructura como en horas de trabajo dedicadas a la gestión de la complejidad.
  • Cohesión de equipo: En lugar de repartir el conocimiento y la responsabilidad de forma extrema, el equipo puede tener una visión más global y colaborar de forma más fluida.

Lo que he aprendido: Cómo hacer un monolito feliz

La clave no es evitar la complejidad, sino gestionarla. Y un monolito bien estructurado es una forma fantástica de gestionar la complejidad inherente al software. Aquí van algunas de mis "reglas de oro" para construir un monolito que no se convierta en tu peor pesadilla:


1. Modularidad interna desde el día uno: Aunque sea un solo proyecto, trátalo como si estuviera compuesto por mini-aplicaciones lógicas. Define límites claros entre dominios (Usuarios, Pedidos, Productos, Notificaciones...). Usa patrones como "arquitectura hexagonal" o "DDD" (Domain-Driven Design) para mantener estas capas bien separadas y evitar acoplamientos indeseados.


2. Interfaces claras: Si un módulo necesita interactuar con otro, que lo haga a través de una interfaz bien definida, como si fuera un contrato. Esto te da flexibilidad para cambiar implementaciones internas sin afectar a otros módulos.


3. Pruebas robustas: Al tener todo en un solo sitio, es más fácil escribir pruebas de integración y de extremo a extremo que te den confianza. No escatimes aquí.


4. "Vertical Slicing" o "Feature Slices": En lugar de organizar tu código por capas técnicas (controladores, servicios, repositorios), organízalo por funcionalidades o dominios. Así, todo lo relacionado con "Pedidos" (su controlador, su servicio, su repositorio, sus modelos) está junto. Esto facilita la comprensión y la refactorización.


5. Refactoriza sin miedo: El monolito permite refactorizar grandes partes de la aplicación con mayor confianza, ya que las dependencias son más fáciles de identificar y gestionar dentro de un mismo codebase.


6. ¿Y si crecemos mucho?: La belleza del monolito modular es que, si un día de verdad necesitas escalar una parte de la aplicación de forma independiente (¡y solo si de verdad lo necesitas!), puedes "sacar" ese módulo y convertirlo en un microservicio con mucha menos fricción, porque ya está diseñado para ser una unidad cohesiva. Esto se conoce como el patrón "Strangler Fig" o "Figuera Estranguladora".


Reflexiones finales: La herramienta adecuada para el trabajo

Al final, la elección entre monolito y microservicios no es una cuestión de "moderno vs. anticuado" o "bueno vs. malo". Es una cuestión de adecuación. Para proyectos pequeños, medianos o incluso grandes que no tienen las necesidades de escalabilidad extrema o la complejidad de organización de equipos que sí tendrían empresas como Amazon, el monolito bien estructurado es, en mi humilde opinión, la opción más sensata, eficiente y menos dolorosa.


Me ha ahorrado incontables horas de frustración, dinero en infraestructura y ha permitido a mis equipos centrarse en lo que realmente importa: entregar valor al usuario. Así que la próxima vez que te digan que el monolito está muerto, diles que no, que está vivo y coleando, y que bien cuidado, es un caballo de batalla que te llevará muy lejos sin caerte del lomo.


¿Y tú, qué piensas? ¿Has tenido experiencias similares? ¡Me encantaría leer tus comentarios!

© 2026
Roberto Hernando
|