There's a lot of microservices hate, but there are also terrible balls of yarn. It reminds me that many orgs are not good at engineering.

A few rules that have served me well:

1) architect your software, have a diagram.
2) centralize responsibilities in the diagram.
3) not every box in that diagram needs to be a service, some boxes should be shared libraries
4) conversely, not every box should be a shared library
...

...
5) There are two primary reasons to make a box a service: you need parallelism for a box that one machine cannot do, or the box is used by many other boxes and manages state. (Plz reply if you know other good reasons, my list is incomplete)
6) if you do your work right, making a library into a service and vice versa isn't a huge endeavor.
7) the reason monoliths get a bad rap is because people throw sensible abstraction layers away and get a terrible balls of yarn
...
8) the reason microservices get a bad rap because people think they need to move every function into a service.
9) as an engineer, you get paid to do judgement calls and nuanced trade-offs. If you're at the extreme end of a spectrum, you're exceptional, and odds are not in a good way.

@HalvarFlake I wrote a blog post last year with a similar stance on this issue: if you're a small team, avoid microservices as long as possible and only use them if you have the requirements AND the infrastructure to support them. Your approach and advice how to split is very good. I will add that to my list of advices.

https://www.inovex.de/de/blog/low-ops-cloud-native-architecture/

Architecture Best-Practices for Low Ops Cloud Native Applications - inovex GmbH

This blog post gives best practices for designing the software architecture of a cloud-native application with little Ops know-how.

inovex GmbH
@hikhvar i like the modulith term btw! Good post!!!
@HalvarFlake didn't invented that term. Came across this as well and liked it.