Live data from Hacker News

Monolith First (2015)

martinfowler.com

211–220 of 356 posts

Re: Monolith First (2015)

#211
One issue with any form of modularization is that dependency cycles are not desirable and have the side effect of creating a need for ever more modules. The reason is that any dependency cycle can be trivially broken by adding another module.

You get dependency cycles when two dependent services need the same thing and you lack a good place to put that thing. You start with modules A and B. Then B need something that A has and then A needs something that B has. You can't do it without introducing a dependency cycle. So, you introduce C with the new thing. And A and B depend on C but B still also depends on A. And so on.

True weather you do Corba, COM, SOAP, Web RPC, OSGi, Gradle modules, etc. The only difference is the overhead of creating those modules is different and has varying levels of ceremony, management needs, etc. Also refactoring the module structure gets more complicated with some of these. And that's important because an organically grown architecture inevitably needs refactoring. And that tends to be a lot more tedious once you have micro services. And inevitably you will need to refactor. Unless you did waterfall perfectly and got the architecture and modularization right in one go. Hint: you won't.

Finally, the same kind of design principles you use for structuring your code (e.g. SOLID, keeping things cohesive, maximizing cohesiveness, Demeter's law, etc.) also applies to module design. Services with lots of outgoing dependencies are a problem. Services that do too much (low cohesiveness are a problem). Services that skip layers are a problem. The solutions are the same: refactor and change the design. Except that's harder with micro-services.

That's why Martin Fowler is right. Start with a monolith. Nothing wrong with those and should not stop you practicing good design. Using microservices actually makes it harder to do so. So, don't introduce microservices until you have to for a good technical or organizational reason (i.e. Conway's law can be a thing). But don't do it for the wrong reason of it being the hip thing to do.

Re: Monolith First (2015)

#212
post #4

A more common scenario I see is that people start with a monolith that ends up inheriting all the conceptual debt that accumulates as a project evolves. All this debt builds up a great desire for change in the maintaining team. A champion will rise with a clean architecture and design in microservice form that addresses all high visibility pain points, attributing forecasted benefits to the perceived strengths of mic…

> I would propose alternative is to fix your monolith first. If the team can't rewrite their ball of mud as a new monolith, then what are the chances of successfully rewriting and changing architecture? Often, the problems with the monolith are * different parts of the monolith's functionality need to scale independently, * requirements for different parts of the monolith change with different velocity, * the monolit…

> different parts of the monolith's functionality need to scale independently,

I hear this a lot. Can you give me an example? Can't I just add more pods and the "parts" that need more will now have more?

Agreed on the other reasons (although ideally the entire monolith should be CI/CD so release cadence is irrelevant, but life isn't perfect)

Re: Monolith First (2015)

#213

One issue with any form of modularization is that dependency cycles are not desirable and have the side effect of creating a need for ever more modules. The reason is that any dependency cycle can be trivially broken by adding another module. You get dependency cycles when two dependent services need the same thing and you lack a good place to put that thing. You start with modules A and B. Then B need something that…

How does a monolith solve dependency cycles, assuming you don’t put all your code in the same module?

Re: Monolith First (2015)

#214
post #169

Earlier quoted context omitted.

Monoliths don't have to be deployed as single instance. In any case, too many rush for micro-services with the intent reason to use the network as a package boundary. Have you ever tried to debug spaghetti RPC calls across the network? I sadly have.

It is possible that there are architectures other than ‘monolith’ and ‘microservices’. Component architectures are also a thing. If it doesn’t all deploy in one go, I don’t think it’s a monolith.

Certainly, the microservices cargo cult has ensured that everything that isn't a microservices, is now a monolith.

Re: Monolith First (2015)

#215
post #213

One issue with any form of modularization is that dependency cycles are not desirable and have the side effect of creating a need for ever more modules. The reason is that any dependency cycle can be trivially broken by adding another module. You get dependency cycles when two dependent services need the same thing and you lack a good place to put that thing. You start with modules A and B. Then B need something that…

How does a monolith solve dependency cycles, assuming you don’t put all your code in the same module?

It doesn't but it simplifies moving stuff around. I use an IDE and can rename at will. With microservice, it's rename. Commit, wait for the thing to build and deploy, open a different project fix all the names, etc. That requires a lot of coordination and is also risky if you get it wrong.

With a monolith, you change everything, create 1 commit. And after that passes CI/CD it can be live in minutes.

Re: Monolith First (2015)

#216
post #31

Earlier quoted context omitted.

When the same practices used to sell microservices get applied to modules, packages and libraries, there is no need to put a network in the middle to do the linker's job. But too many are eager to jump into distributed computing without understanding what they are bring into their development workflow and debugging scenarios.

If you think of microservices as a modularization tool - a way to put reusable code in one place and call it from other places - then you are missing the point. Microservices don’t help solve DRY code problems. Monoliths aren’t merely monolithic in terms of having a monolithic set of addressable functionality; they are also monolithic in terms of how they access resources, how they take dependencies, how they are bui…

most of what you said was solved decades ago in linking

Re: Monolith First (2015)

#217
"Monolith vs microservices" is a bit like "Fullsize SUV vs multiple sedans". They are used differently, so you should pick that which fits your purposes. And the idea that you have to do one or the other is a bit ridiculous. I've seen plenty of businesses that organically landed on a mix of monolith and microservice and things in between. Don't get caught up in formalism.

Re: Monolith First (2015)

#218
post #212

Earlier quoted context omitted.

> I would propose alternative is to fix your monolith first. If the team can't rewrite their ball of mud as a new monolith, then what are the chances of successfully rewriting and changing architecture? Often, the problems with the monolith are * different parts of the monolith's functionality need to scale independently, * requirements for different parts of the monolith change with different velocity, * the monolit…

> different parts of the monolith's functionality need to scale independently, I hear this a lot. Can you give me an example? Can't I just add more pods and the "parts" that need more will now have more? Agreed on the other reasons (although ideally the entire monolith should be CI/CD so release cadence is irrelevant, but life isn't perfect)

So the alternative is to have a monolith deployed with different "identities" based on how it's configured. So you configure and scale out different groups of the monolith code independently, to satisfy different roles and scale up or down as needed.

However, sometimes the resources needed to load at start up can be drastically different, leading to different memory requirements. Or different libraries that could conflict and can also impact disk and memory requirements. For a large monolith, this can be significant.

So at what point do you go from different "configuration", to where enough has changed it's a truly different service? The dividing line between code and configuration can be very fluid.

> the entire monolith should be CI/CD so release cadence is irrelevant

But if one module has a bug and is failing testing, or features partially completed, it blocks releasing all the other code in the monolith that is working.

Re: Monolith First (2015)

#219

Microservices are hard. Monoliths are hard too. Focus on the product and the customer, build what they need. Architecture is a means to make a successful product.

Agreed and I'll add that the architecture must evolve into its most efficient form in tandem with the success of the product.

Re: Monolith First (2015)

#220
post #180

Earlier quoted context omitted.

> we have about 50 engineers The plan worked.

Clearly something is working if you've got 50 engineers turning out bug-filled code and systems, and yet the business keeps on living.

> and yet the business keeps on living

Sure, they just change the business plan. Move into as many new markets as possible, focus more on new sales than maintaining customers, ship more features/products than you can maintain, etc.

If the company gets twice as big but revenue/growth remains the same, that's a sinking ship.

Post reply on HN