As is often stated, microservices is a solution for scaling an engineering org to 100s of developers, not for scaling a product to millions of users.
You can get the separation benefits of microservices in a compiled language with modules that only communicate over well-defined interfaces, constraining each team within their own module without having to introduce a network call between each operation.
Unfortunately that message was way way behind the bombast of "microservices everywhere now" that preceded it for years, to the detriment of many small orgs.
I've seen engineering orgs of 10-50 launch headlong into microservices to poor results. No exaggeration to say many places ended up with more repos & services than developers to manage them.
Microservices is bad for teams without discipline to implement "separation of concerns". They hope that physical network boundaries will force the discipline they couldn't maintain in a single codebase.
While microservices force physical separation, they don't stop "Spaghetti Architecture." Instead of messy code, you end up with "Distributed Spaghetti," where the dependencies are hidden in network calls and shared databases.
Microservices require more discipline in areas like:
Observability: Tracking a single request across 10 services. Consistency: Dealing with distributed transactions and eventual consistency. DevOps: Managing N deployment pipelines instead of one.
For most teams Modular monolith is often the better "first step." It enforces strict boundaries within a single deployment unit using language-level visibility (like private packages or modules). It gives you the "Separation of Concerns" without the "Distributed Spaghetti" network tax.