Hacker News new | ask | show | jobs
by ludston 1787 days ago
If you compare making a call to a web service vs calling a function to achieve a similar outcome, it is definitely true that you can easily have business logic coupled between these two services. You also have the additional cost of having to handle network errors in the calling function.

However, scaling a monolith (as someone who does this for their day-job) is significantly harder than scaling independent services. This is mainly because performance issues in one function can hog resources that other functions share. This is particularly the case when you have a single, central database where one poorly optimized query can cause performance for all users to degrade severely.

3 comments

To play Devil's advocate, how about just running multiple instances of the monolith behind a load balancer, and using database replicas/shards/load balancing?

Being able to scale individual components/services will be the most efficient solution, but if there doesn't happen to be a particular bottleneck that bogs down everything else (besides the database), it seems like the traditional monolithic load balancing approach may not be so bad.

Especially compared to the effort of trying to split an existing monolith into microservices. And if there are other bottlenecks, you can focus your effort on improving or isolating those parts.

(I only have intermediate experience in this area and certainly way less than you do; definitely not trying to claim anything authoritative.)

Your thinking is along the right lines. The "you can focus your effort on improving or isolating those parts" is the trouble. With a sufficiently complex code-base this has a very high cost, and the number of programmers capable or willing to do this sharply declines.
Your scaling argument is one of the oft cited arguments. I've cited it myself. The reality I've experienced has largely been contradictory, though. The reality is now you have bottlenecks in each of your services and you likely have a much harder time figuring out where the internal and cross-service bottlenecks actually are. You have to add a lot of modern and cutting edge tech to really get an accurately traced performance picture, and the truth is that pretty much nobody does that when they're building their microservices. Only once things start falling over do they consider adding these things that would just be available much more readily in a single process.
Most systems don't need to scale beyond "please no obvious performance bugs", so it makes sense to write most applications as monoliths for the reason that you are stating (i.e. development is faster).

It only makes sense to write services (note, "services", not "micro-services") when it is inevitable and obvious that your software is hitting scaling issues related to some subsystem, or when you have systems that need to be independently reliable. (i.e. ATM's should work even when the banks website is down)

Last time I was scaling a monolith I basically did it purely by splitting up the DB into multiple ones with different purposes and improving query perf just through that.

I would've had to do all the same work to extract it to microservices, but also would've had to do a lot more on top. Had it not been a legacy system, probably worth it - but as it was, leaving it as a monolith querying a now-split-up set of DBs was cheaper and faster.