I once participated in implementing a system as a monolith, and later on handled the rewrite to microservices, to 'future-proof' the system.
The nice thing is that I have the Jira tickets for both projects, and I have actual hard proof, the microservice version absolutely didn't go smoother or take less time or dev hours.
You can really match up a lot of it feature-by-feature and it'll be plainly visible that the microservice version of the feature took longer and had more bugs.
And Imo this is the best case scenario for microservices. The 'good thing' about microservices, is once you have the interfaces, you can start coding. This makes these projects look more productive at least initially.
But the issue is that, more often than not, the quality of the specs are not great to awful, I've seen projects where basically Team A and Team B coded their service against a wildly different interface, and it was only found in the final stretch that these two parts do not meet.
I've noticed that there's another problem with microservices as well. People tend to tie microservices and multi-repo into the same strategy.
Multi-repo appears to make teams faster (builds are faster! fewer merge conflicts!) but, like micro-services, they push complexity into the ether. Things like updating service contracts, library updates, etc. all become more complicated.
I think the real sin is just cutting against the grain on your services and library boundaries.
It's not that hard to version and deploy multiple services and libraries. If you need the flexibility of that separation, it can very much be worth it.
But if you separate them and still treat them like you're in a mono whatever and you cut corners on keeping your separation clean and clear, you're going to have a bad time.
Either pattern has its advantages. It's best to remember that they're just a pattern and you should be doing one or the other for a reason.
Oddly, I would say that this often exposes complexity? Not that that is a valid reason to go all in on it. But some things, like updating service contracts, are complicated. Indeed, anything that makes it look like many services all deployed in unison is almost certainly hiding one hell of a failure case.
In my experience, while monorepo makes shared libraries between services easier, that inevitably turns into "Hey, why not just put a copy of my application inside yours?"
Having gone from multi-repo to monorepo recently, I'd say the opposite. A multi-repo lets you do those things incrementally. A monorepo forces you to do them in one go.
Distributed systems are always more complex than equivalent monolithic ones. Luckily, it looks like most engineers now understand that microservices mostly make sense for big companies where the biggest issue is distributing work between lots and lots of developers in a sensible way.
I agree with you, that big companies just run so much stuff that it makes sense that there should be a control plane, and thats quite unlike how most microservices are supposed to be architected.
In fact this is not even an 'architecture' but a higher level of organizational layer.
I participated in something kind of the opposite of that: multiple microservices in independent repos, but with intertwining dependencies on each other. Adding features meant shotgun surgery across at least 3 repos/services, sometimes more.
I once participated in implementing a system as a monolith, and later on handled the rewrite to microservices, to 'future-proof' the system.
The nice thing is that I have the Jira tickets for both projects, and I have actual hard proof, the microservice version absolutely didn't go smoother or take less time or dev hours.
You can really match up a lot of it feature-by-feature and it'll be plainly visible that the microservice version of the feature took longer and had more bugs.
And Imo this is the best case scenario for microservices. The 'good thing' about microservices, is once you have the interfaces, you can start coding. This makes these projects look more productive at least initially.
But the issue is that, more often than not, the quality of the specs are not great to awful, I've seen projects where basically Team A and Team B coded their service against a wildly different interface, and it was only found in the final stretch that these two parts do not meet.