7 ms·
Monolith First (2015)
- curious_cat_163 2y agoYes. It does require thinking about the monolith in a way so it can be broken up should the need arise. Going down the monolith path != Having spaghetti as the core abstraction. :)
- brodouevencode 2y agoThere's the ideal path, then the actual. Most monoliths, unchecked and with enough age, turn into spaghetti due to turn over, changing priorities, entropy, etc.
- two_cents 2y agoIn my experience same goes with microservices. Same spaghetti, different abstraction layer,
- brodouevencode 2y agoyou are correct
- AnimalMuppet 2y agoBut at least some microservices architectures turn into macaroni - far too many small, isolated things, with no connection between them. It can have all the disadvantages of an overly-OO design, just at a larger scale.
- kgeist 2y agoThe majority of microservice architectures end up being distributed monoliths.
- brodouevencode 2y agothe problem with the yagni argument is is you aint gonna need it until you do
- rwmj 2y agoUnless you are actually a FAANG, you don't need them. And in the extremely unlikely case you become the next FAANG you'll have plenty of money to throw at the problem.
- brodouevencode 2y agoThis is a gross oversimplification.
- deleted 2y ago[deleted]
- taeric 2y agoI think there is a variant of "you don't currently need it" that people should follow more. Build towards what you think you will need, by all means. But try and only build what you need right now.
- brodouevencode 2y agoThis is a good point, and lines up with the real yagni argument. However, I do not like the readiness that people have with throwing around the yagni argument for things they don't want to support, build, or disagree with, often contorting or oversimplifying it to get their way. The yagni argument itself is reasonable, but is often misused/abused.
- delecti 2y agoYeah. There's a healthy middle ground between boxing yourself in and boxing yourself out. Don't write things before you need them, but if you can tweak an implementation slightly with knowledge of things you're thinking about adding later, that's often a good idea idea.
- Rickasaurus 2y agoRecently was looking at a distributed microservice system at a company that thought they would need massive scale, but pivoted from d2c to enterprise b2b and then found out enterprise b2b companies want data separation. They would have been much better off going monolith first and probably actually sticking with a monolith.
- kgeist 2y agoYou mean it's easier to shard databases per tenant when it's a monolith?
- crmd 2y agoData separation in enterprise-land means customers don’t want components that touch their data to be shared with any other customers. So a shared but sharded database is no good. In practice you often run a standalone stack for each customer, including their own database. This pattern is a nightmare from an operational scaling perspective, but that’s part of why enterprises are asked to pay so much.
- kgeist 2y agoI understand what it means, I'd like to know where the monolith architecture stands in this context. One of our projects was originally a monolith, and each tenant had their own dedicated DB the monolith connected to. Then they switched to the microservice architecture (back when it was the peak of the hype) and rejected the idea of database sharding because each microservice already requires their own DB, and if you also sharded by tenant, then you'd end up with M x N databases (where M is the number of tenants and N is the number of microservices) which sounds like a lot of complexity to manage. I think they once had a bug where one tenant could see data from another tenant because they don't have strong DB boundaries anymore.
- negus 2y agoA monolith is just one microservice. Is there a choice to be made? "We love monoliths so much so we have dozens of them"
- deleted 2y ago[deleted]
- Alifatisk 2y agoA monolith is not a single microservice.
- negus 2y agoAny arguments to support this claim? What's the difference then? If there is three communicating servces: first has 90% of the business logic, second has 7%, and the last one has 3%. Should we call the first one a monolith? And if they don't communicate?
- JackSlateur 2y agoYou can have a single codebase, deployed in multiple kind of configurations One code, multiple roles
- negus 2y agoI mostly use statically linked monorepos with microservices. The services use the common utils from the repo. What's the difference except for not having dead code and unused dependencies in the artifacts in my case?
- crazygringo 2y ago> Any arguments to support this claim? What's the difference then? The "micro" in "microservice". Microservices are meant to do one "micro" thing well, whether it's image hosting or credit card transactions or supplying the content of a tweet or whatever. A monolith does all the things, or most of the things. It's not "micro". You don't need arguments to support it, these are just the definitions of the terms. It's semantics. A monolith can't be a single microservice because it's not micro.
- the_clarence 2y agoYes strive to find one good language and use it everywhere. Then when greater languages like Rust come out you have a problem.
- exabrial 2y agoYes? but that really isn't the problem. You can do both monoliths and micro-services badly. The real thing that makes software easy to maintain is consistency with itself. If you have one guy that formats his code with spaces and another tabs, that creates friction in the codebase. If you have one guy that always uses `const` or `final`, but another guy that doesn't, again hard to maintain. The hard problems are boundaries between business logic is divided. If the application is consistent in how it divides responsibilities, it'll be a pretty clean codebase and pretty easy to navigate and maintain. If you have two different rouge agents that disagree on coding styles and boundaries, you'll have a pretty difficult codebase to navigate. The easiest codebases have consistent function signatures, architecture, calling conventions, formatting, style, etc and avoid "clever" code.
- kemitche 2y agoI firmly believe that monolith vs microservice is much more a company organization problem than a tech problem. Organize your code boundaries similar to your team boundaries, so that individuals and teams can move fast in appropriate isolation from each other, but with understandable, agreeable contracts/boundaries where they need to interact. Monoliths are simpler to understand, easier to run, and harder to break - up until you have so many people working on them that it becomes difficult for a team to get their work done. At that point, start splitting off "fiefdoms" that let each team move more quickly again.
- ActionHank 2y agoKind of side steps the fundamental scaling issue though. In a banking app there will be more requests for the account balance than there are logins, but logins will likely take longer. Your argument is more around who is allowed to touch which and who is responsible when it breaks, but not around one of the core reasons to choose microservices.
- nprateem 2y agoYou scale the whole thing. There's no issue at all.
- brodouevencode 2y agoTo what end? To support that 1:10000 transaction that takes the most time and needs the most scaling? Just burn a wad of $20s, that will be easier.
- nprateem 2y agoYes. It's better than burning £100ks by over complicating things and wasting your developer's time. Most startups fail. You need to cover as much ground as possible while you have runway, not cock about with microservices.
- 2y ago
- loughnane 2y ago> Almost all the successful microservice stories have started with a monolith that got too big and was broken up The less certain you are about a system's requirements the more you should prefer a monolith. A well-understood system (eg an internal combustion engine) has well-defined lines and so it _can_ make sense to put barriers in between components so that they can be tweaked/replaced/fixed without affecting the rest of the system. This gives you worthwhile, but modest overall performance improvements. But if you draw the lines wrong you end up with inefficiencies that outweigh any benefit modularity could bring. Start with a monolith and break it up as the system's ideal form reveals itself.
- david422 2y agoMy co-worker gave me the quote - "if you have more microservices than clients, you're doing it wrong". Not sure if it was original or not but makes sense to me.
- from-nibly 2y agoAlso if you have more microservices than you have requests per second.
- throwaway984393 2y ago[dead]
- danielovichdk 2y agoWhenever this man write anything the cargo cults are flocking. That's totally okay as long as you are aware. I recommend you to learn to think for yourself given the context you are in, along with the power and social dynamics of such.
- deleted 2y ago[deleted]
- deleted 2y ago[deleted]
- dangoodmanUT 2y agoJust see things like Redpanda, Cloudflare, etc. These complex systems are made easier by being built as a single binary
- apitman 2y agoI like to follow a pattern I call monomicro. Basically I develop separate programs for different functionality, but make them embeddable so they can be composed and run in the same memory space for small deployments. The code that runs https://lastlogin.net https://lastlogin.net is a good example. For LastLogin it runs as a globally distributed cluster on fly.io, but it's also fully embeddable in any Golang program to act as an auth layer.
- mrweasel 2y agoThere is also room for the in-between, not a monolith, but also not "micro" services. It is actually possible to have a number of services working together, each on their own a small monolith. I've done multiple projects where we have fairly large service working together. Sometimes they function on their own, other times they hand of a task to another service in order to complete the entire process. Sometimes they need each other to enrich something, but if the other service isn't running that's okay for a short time. It is also worth remembering that if all your microservice needs to be running at the same time, you just have a distributed monolith, which is so much worse than a regular monolith.
- ChrisArchitect 2y agoRelated recently: Modular Monoliths Are a Good Idea https://news.ycombinator.com/item?id=41534179 https://news.ycombinator.com/item?id=41534179
- forrestthewoods 2y agoThe philosophy that has served me well is "do the simplest possible thing". Sometimes problems are intrinsically complicated and the solution is required to be complex. But even in that case it's important to do the simplest thing you can get away with! My experience is that people, myself included, almost always over-engineer unless they focus really hard on doing the simple thing. It takes concentrated effort to avoid architecture astronauts and their wildly convoluted solutions. It's orders of magnitude easier to add complexity than to remove it. Do the simple thing!
- kgeist 2y agoA few years ago, after having worked on a microservice-oriented project for some time, I joined a team which developed a monolith. To be honest, it felt like a breath of fresh air. What previously took coordination across multiple teams and repositories, tens of API schemas, complex multi-stage releases (your average feature usually touches lots of microservices), complicated synchronization of data stored in tens of DB, with a whole theory on microservice communication and a whole DevOps team with their own "platform" -- now it's just a bunch of commits in the same repository, a single release. To prevent code from becoming complex spaghetti, they simply use the modular monolith architecture (modulith). There's simply a linter which makes sure module boundaries are not violated (so they are encapsulated properly, just like in microservices). Want to support more load? Just increase the number of workers/servers. The single DB becomes too large? Just split it into several DBs and connect to different physical machines as needed. Now I'm pretty skeptical of the whole microservice thing. To be honest, I can't name a single advantage microservices over monoliths anymore. All problems are solvable with a monolith just fine, without all the complexity. The only time we needed to physically split a part of the monolithic codebase into a separate repository was when the infosec department asked us to store and process personal data inside isolated infrastructure to conform to some regulations.
- xg15 2y agoI think microservices can be useful for nontechnical reasons: They let you take the "org chart becomes architecture" from an unseen, not really understood force into something explicit that you can observe and manage. Instead of multiple teams working on the same codebase and stepping on each other's toes, each team can have clear ownership of "their" services. It also forces the teams to think about API boundaries and API design, simply because no other way of interaction is available. It also incentivices to build services as mostly independent applications (simply because accessing more services becomes harder to develop and test) - which in turn makes your service easier to develop against and test in (relative) isolation. However, what's of course a bit ridiculous is to require HTTP and network boundaries for this stuff. In principle, you should get the same benefits with a well-designed "modulith" where the individual modules only communicate through well-defined APIs. But this doesn't seem to have caught on as much as microservices have. My suspicion is that network boundaries as APIs provide two things that simple class or interface definitions don't: First, stronger decoupling: Microservices live in completely separated worlds, so teams can't step on each other's toes with dependency conflicts, threading, resource usage, etc. There is a lot of stuff that would be part if the API boundary in a "modulith" that you wouldn't realize is, until it starts to bite you. Second, with monoliths, there is some temptation to violate API boundaries if it let's you get the job done quickly, at the expense of causing headaches later: Just reuse a private until method from another module, write into a database table, etc. With network/process boundaries, this is not possible in the first place. It's a whole bunch of very stupid reasons, but as they say, if it's stupid and works, it ain't stupid.
- kgeist 2y ago>org chart becomes architecture Tbh, it didn't work for us: our org chart changes more frequently than the codebase's architecture (people come and go, so teams are combined, split, etc. to account for that, many devs also like rotation, because it's boring to work on the same microservices forever), so in the end basically everyone owns everything. Especially when to implement a feature, you have to touch 10 microservices -- it's easier and faster to do everything yourself, than to coordinate 10 teams. >Second, with monoliths, there is some temptation to violate API boundaries if it let's you get the job done quickly, at the expense of causing headaches later: Just reuse a private until method from another module This is solvable with a simple linter: it fails at build time if you try to use a private method from another module. We use one at work, and it's great.
- dang 2y agoRelated. Others? Monolith First (2015) - https://news.ycombinator.com/item?id=26190584 https://news.ycombinator.com/item?id=26190584 - Feb 2021 (340 comments) Monolith First (2015) - https://news.ycombinator.com/item?id=14778685 https://news.ycombinator.com/item?id=14778685 - July 2017 (163 comments)
- TrianguloY 2y agoAnother one here working with microservices and almost-hating it. Also > By starting with microservices you get everyone used to developing in separate small teams from the beginning, and having teams separated by service boundaries makes it much easier to scale up the development effort when you need to. Nop, not for my team at least, most features require touching several microservices, so now you have either as many merge conflicts as edges (if one team is responsible for fixing what breaks in the other sides, yes, that happens) or need to have twice the meetings with twice the people to make sure each side is doing what the other expects.
- alganet 2y agoMonolith as the final goal is probably a good way to think about the issue. Janky modular stuff first, full of inefficiencies, few formalities, designed to move fast and _not be in production_. Once it's up and running (in a test setup), you can "see the shape of it" and make it into a more cohesive thing (a "monolith"). This is consistent with how many other crafts older than programming have coalesced over centuries. I suspect there's a reason behind it. You don't start with an injection-molded solid piece of metal with carefully designed edges that can be broken later (or shaven off) in different ways. You machine something that you don't understand yet using several different tools and practices, then once the piece does what you want (you got a prototype!), you move the production line to injection molding. The resulting mold is way less flexible than the machining process, but much more cohesive and easy to manage. Of course, programming is different. The "production lines" are not the same as in doing plane parts. In programming you "fly the plane" as soon as it is "air worthy" and does improvements and maintenance in mid-flight. It's often a single plane, no need to make lots of the same model. So, with that in mind, there's an appeal for carefully planning context boundaries. It's easier to ditch the old radar system for a new one, or replace the seats, or something like that, all during flight. If the plane breaks down mid-flight, the whole thing is disastrous. So we do stuff like unit testing on the parts, and quality assurance on a "copy of the plane" with no passengers (no real users). Wait, aren't those approaches similar to old traditional production lines? Rigs to test component parts individually, fixtures (that comes from the machining world), quality assurance seals of approval, stress tests. So, why the hell are we flying the plane as soon as it is barely air worthy in the first place? It creates all those weird requirements. > When you begin a new application, how sure are you that it will be useful to your users? Well, I don't have any clue. But _almost all_ applications I ever built were under serious pressure to be useful real fast. Barely flying was often enough to stop the design process, it got passengers at that point so no need to go back to the drawing board. What it often required by the stakeholders is not a better production process, it's just making the barely flying plane bigger. I know, I know. Borrowing experience from other industries is full of drawbacks. It's not the same thing. But I can't just explain the absurdities of this industry (which are mostly non-related to engineering) in any other way. All of this reminds me of that "If Microsoft made cars..." joke, but it's not funny anymore.
- ghomem 2y agoI love Martin Fowler's one pager called Snowflake server - it aged very well and I still use it as a reference in the cloud era. And this text is also good advice IMO. What I feel that is missing on what he calls the "Microservices Premium" is a clear statement that this premium is paid in "ops" hours. That changes the game because of the "ops" resource scarcity. In fact, the microservices dilemma is an optimization problem related to the ops/dev ratio that is being wrongly treated as a conceptual problem. This is the simplest analysis I could come up with: https://logical.li/blog/ops-dev-ratio/ https://logical.li/blog/ops-dev-ratio/
- Scubabear68 2y agoI think the overall thesis here is accurate. I can fill in the blanks where Fowler is light on anecdotal evidence. I have done many architecture reviews and private equity due diligence reviews of startup systems. Nearly all the micro services based designs were terrible. A common theme was a one or two scrum team dev cohort building out dozens of Micro services and matching databases. Nearly all of them had horrible performance, throughout and latency. The monolith based systems were as a rule an order of magnitude better. Especially where teams have found you don’t have to deploy a monolith just one way. You can pick and choose what endpoints to expose in various processes, all based on the same monolithic code base. Someday the Internet will figure out Microservices were always a niche architecture and should generally be avoided until you prove you need it. Most of the time all you’re doing is forcing app developers to do poorly what databases and other infrastructure are optimized to do well.