Monolith or Microservices

  • I’m currently facing a new project and wondering whether microservices would really do us any favors—or whether, at the beginning, they’re just fancy distributed complexity. A monolith may sound “old-fashioned” at first, but a well-modularized monolith is often much faster to build, test, and deploy.

    When did you reach the point where you **really** had to split things up? And what were the first problems: deployments, team size, performance, different tech stacks? I’d love to hear real-world experiences, not just the usual architecture slides 🙂

    This post has been automatically translated.

  • I would almost always start with a modular monolith. Microservices rarely solve a technical problem that you couldn’t first solve within a single process—but they do add network failures, distributed debugging, version compatibility issues, and significantly more operational overhead. “We could deploy individual parts independently” is only a good argument for me once that is actually necessary in day-to-day operations.

    For us, splitting things up only became worthwhile when multiple teams were constantly blocked by the same releases and one area really had its own scaling or availability requirements. Before that, the biggest pain point wasn’t performance but discipline within the monolith: clear module boundaries, no direct database access across modules, and ideally tests that also verify those boundaries. If you can’t manage that, microservices usually just become a distributed spaghetti system.

    This post has been automatically translated.

  • I see it similarly to DenkMal: A modular monolith is often the best place to start, **if** the module boundaries are taken seriously. That means no shared “God DB,” no internals imported across all packages, and ideally clear interfaces between the modules. Otherwise, splitting it up later really will be painful.

    For us, it wasn’t the sheer load that was the trigger, but different change and operating cycles: An import service had to be scaled and deployed separately, while the rest of the application remained relatively stable. In that case, you can first extract exactly that part instead of immediately building ten services. I already considered logs, metrics, and tracing essential beforehand—without proper observability, distributed debugging is really no fun. How are you planning the database boundaries in your modular monolith?

    This post has been automatically translated.

  • I would place more emphasis on deployment and operational effort as well. We initially had a modular monolith that worked great, but at some point the build and test pipeline became the bottleneck: Every small change triggered the entire test suite and had to go through the same release process. That was more annoying than the runtime performance itself.

    But we didn’t immediately break everything up into microservices. Instead, we extracted only a relatively clearly defined notification service. It had its own retry logic, different scaling requirements, and it wasn’t allowed to block the main application in the event of an outage. That worked well—although only because we had logging, metrics, and tracing reasonably under control beforehand. Without proper correlation IDs, troubleshooting would really have turned into a ghost hunt.

    I think the “no God DB” rule is particularly important here. A service that is officially independent but constantly reads another service’s tables directly is basically just a distributed monolith with added latency 😄 That’s why, if a split ever becomes necessary, I would encapsulate data access behind module APIs from the outset, even in the monolith, even if that means a bit more boilerplate at first.

    What I’d find interesting: How strictly do you separate the modules technically within the monolith? Do you use language/framework mechanisms, dedicated packages with architecture tests, or simply team conventions? In our case, conventions alone eventually weren’t enough.

    This post has been automatically translated.

  • The pipeline point is more decisive for me than “we need more performance.” If every change has to go through a huge testing and release machine, that’s a real organizational problem. But even then, I’d first check whether tests can be parallelized, modules built separately, or deployments decoupled before immediately introducing network boundaries.

    When splitting things up, data storage is often underestimated. As long as multiple services read from and write to the same tables directly, you may have microservices on the diagram, but in practice you have a distributed monolith with worse debugging. So for me, a hard requirement would be: a separate area of business responsibility, including data access, plus monitoring and tracing from day one. How did you solve data consistency in the services you separated out—synchronous API calls, events, or deliberately accepting some temporary inconsistency?

    This post has been automatically translated.

  • For me, the crucial test is: Can a module really be made self-contained in terms of both its domain and its data? If not, having a separate process usually only adds more opportunities for errors – and the famous “one transaction across five services” becomes especially fun 🙃

    That’s why, when starting out, I’d prepare logs, metrics, and tracing properly right alongside the module boundaries. Not necessarily Kubernetes and 23 deployments right away, but in a way that ensures a service extracted later won’t be operated blindly. How did you handle data ownership in your extractions – a separate data store per service, or initially via events/adapters from the existing database?

    This post has been automatically translated.

  • That's exactly why I may have become a tradesperson. I have no idea what you're talking about here. ;)

    This post has been automatically translated.

    Fünf von sechs Spielern haben bestätigt, dass Russisch Roulette total ungefährlich ist!

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!