Build the Modular Monolith First
41–50 of 90 posts
Re: Build the Modular Monolith First
#42I think more startups need to consider building monoliths first. Micro-service architecture definitely has the advantage at scale, but the advantage of monoliths is the speed that you can build and improve them. Microservices require much more planning and architecture discussions compared to monoliths. Microservices also can have incredible performance improvements over monoliths (being able to scale or tailor each…
They are better at avoiding downtime during deployments because everything is built around supporting it - but at huge cost. Offline migrations - which may be taking just seconds/minutes - are so much easier to do. We're talking about order of magnitude difference in complexity of adding new features.
In typescript world, monorepo with shared packages where some are dockerized services (all under same monorepo wide version) is more than enough for most projects. Microservice crowd will call it monolith (because services can't be deployed independently, they likely share SQL database etc), but it's a set of services. You can run it from docker/swarm/k8s - scalability is not really a problem here until you're HUGE (hundreds of developers or hundreds of machines to deploy to). Refactoring, adding new features, dropping stuff etc. - is all easy, usually type checker will guide you to all places that need changing. Single set of migrations. Straight forward e2e. Fast local development where you can spin the whole thing etc. Why people like to complicate their lives when they have this?
Re: Build the Modular Monolith First
#43What actually happens, 100% of the time in my personal experience, is that you end up with both the old monolith and new microservices, the monolith never gets fully broken up, and now you need to support two development paradigms forever.
Has anyone here ever seen a monolith be successfully 100% broken up into microservices?
Re: Build the Modular Monolith First
#44You can try to build a monolith that is modular enough to break up later. But I have never seen it happen, and I’ve been around for a while now. What actually happens, 100% of the time in my personal experience, is that you end up with both the old monolith and new microservices, the monolith never gets fully broken up, and now you need to support two development paradigms forever. Has anyone here ever seen a monolit…
Re: Build the Modular Monolith First
#45I think an important thing to keep in mind when discussing monoliths or Microservices is that you can build modular code without needing multiple binaries, processes, or server instances. If you follow best practices when creating a monolith, creating well-defined modules with clear input and output boundaries, then it should be relatively easy to split those modules into separate programs and create ways for those m…
I think a (but not the only) central conceit of a microservices architecture is that most development teams cannot be trusted to maintain proper separation of concerns, and enforcing at a technical level the inability to call Any Old Function is a big part of what you’re buying into.
Re: Build the Modular Monolith First
#46You can try to build a monolith that is modular enough to break up later. But I have never seen it happen, and I’ve been around for a while now. What actually happens, 100% of the time in my personal experience, is that you end up with both the old monolith and new microservices, the monolith never gets fully broken up, and now you need to support two development paradigms forever. Has anyone here ever seen a monolit…
I'm all for ending old software when the time comes but not everything needs a rewrite to microservices.
Supporting two development paradigms isn't really a thing any reasonably sized organisation should be concerned about.
Especially when you're talking about adding one more build process to hundreds across all your services.
Re: Build the Modular Monolith First
#47The whole monolith vs microservice discussion revolves around a false dichotomy and higly subjective and context-dependend definitions. For example, what if a monolith is integrated into a larger system landscape (e.g. due to an enterprise merger). Is it still a monolith?
Re: Build the Modular Monolith First
#48Re: Build the Modular Monolith First
#49Earlier quoted context omitted.
I think anyone who has taken a large monolith through a significant platform version upgrade or change, like .NET 2 to .NET 4, or Python2 to Python3, or Angular to React, would need a very persuasive argument to make them believe that starting a new project with a monolithic design was a good idea.
I’d tell anyone that thought that that it’s a very shortsighted view. If they had started with microservices there’s a good chance the project wouldn’t be around long enough to even go through that transition.
If you have offline batch processes, don't make the mistake of implementing them in the same codebase as your website just because you already have the DB access and build/deploy tooling set up. If you have an admin portal and a public website that listen on different ports, don't run both listeners in the same process.
'don't build microservices yet' does not have to mean 'start with a monolith'.
Re: Build the Modular Monolith First
#50Microservices vs. monoliths is a false dichotomy in the present day. If you put microservices in a monorepo with a good build tool (like NX), put the common auth/logging/types/dtos/etc. functions in reusable libs, and version/release all the apps together, you get the best of both worlds. At a small scale, you can deploy your whole containerized stack on two big HA instances (monolithic infrastructure, so much easier…
A monorepo of microservices is the best pattern, but only if you have a dedicated team that keeps the monorepo buildable, builds tooling for it, and enforces best practices and the right culture. If you don’t do that, you will end up with a huge mess — I’ve seen it happen. For companies that can’t dedicate the resources to do a monorepo properly, a repo per team is the best approach. The true value of microservices i…
- The monorepo tooling I prefer at startup scale (NX) does have a learning curve, but it has been pretty easy to maintain using automation (good linting, good build/test pipeline, etc.). For me, learning and leveraging the right monorepo tooling is way easier than having to enforce consistency across large numbers of repos with a small team or watch a low-tooling monolith decay into tightly-coupled spaghetti. I am also in a particular situation where the need for eventual scale is obvious, will come very quickly (clients are big), and the thought of having to rush a scale-inexperienced team (management and devs!) through a monolith-to-microservice migration on a tightly coupled codebase while meeting SLAs is so unpleasant that it makes me a bit sick to my stomach to think about it.
- The monorepo framework/tooling matters a lot. For instance, NX is small-scale friendly and largely can be overseen by senior Typescript devs. Bazel, on the other hand, requires a hefty context switch and has a very steep learning curve.
- You are right that releasing all services together does not scale past a certain point. My point is that microservice monorepos let you pivot quickly between all-together (monolithic) releases and individual app releases as appropriate for your scale. With good caching and parallel blue/green deployments, adding new services to an all-at-once build/deploy pipeline just uses a bit more compute for the pipeline without meaningfully impacting the pipeline run times.
- Having to release services serially in a certain order obviously indicates something is seriously wrong under the hood.
- You are very right about monorepo tooling/best practices, but I would extend that to any project that eventually will need to scale. Someone has to take ownership and enforce good practices. Spaghetti code can be harder to prevent in a feature-heavy monolith and certainly is harder to deal with for me if it is in many different repos (i.e., several monoliths).
- You can have more than one monorepo for teams that are very different or have specific needs (i.e., different languages, mobile apps, etc.).
- I wish I were in a situation where my team could commit to avoiding breaking API changes, but it just is not so because of aggressive development timelines. (I am sure this will change in the future as we scale.) All-together versioning/releasing helps deal with (planned, intentional) breaking API changes very efficiently, because (as long as you can tolerate a failed API call once in a while as a blue/green deployment switches traffic) you're basically performing the deployment as if it is a monolith.
Add: 1000% agree about db access. That is very easy to enforce at the architecture/team level.