Today I saw a familiar little software moment: someone suggested introducing another microservice.
It had its purpose and I would've made the same choice, maybe. But I recognised a pattern where systems introduce a new responsibility, and then, "new responsibility" started sounding suspiciously like "new service".
I like microservices. Which is probably why this stuck with me. Once a team has a few of them, every new idea begins to orbit the architecture. Need a feature? Service. Need a small extension point? Service. Need to store three values and call an API twice? Obviously, service. Preferably with its own repository, wait… We already have a monorepo. Then just a new folder, pipeline and a name that sounds like a Marvel character. I'm looking at you, Galactus.
The uncomfortable part is that microservices are not bad. That would be too easy. They solve real problems: independent scaling, isolated deployments, clearer ownership, fault boundaries. At the right size, with the right team, under the right pressure, they make sense.
But sometimes we seem to skip the boring question: do we actually need this?
A modular component could be enough. A clean boundary inside the existing app could be enough. A plugin-style extension point could be enough. Build it so it can grow later, sure. But maybe don't immediately give it its own infrastructure passport and send it into production as a tiny nation-state.
There is this fantasy that everything will scale massively one day. The classic "when we have millions of users" argument. Which is technically possible, in the same way that I am technically one viral GitHub repo away from becoming a conference keynote speaker. Possible, yes. Planning your entire architecture around it today, questionable.
Modern software has a tendency to confuse seriousness with complexity. If a thing has message queues, distributed tracing, and twelve dashboards, it feels important. A simple module feels almost suspicious.
Maybe that is what bothers me: overengineering often looks responsible from a distance. Nobody gets blamed for choosing the architecture that sounds scalable. "We made it a microservice" has a professional smell to it. "We kept it simple because the problem was simple" sounds almost naive, even when it is probably the more thoughtful decision.
Still, I get the temptation. Microservices are satisfying. They create neat boxes. They promise separation.
Maybe the better question is not "Should this be a microservice?" but "What pain are we trying to avoid?". If the pain is deployment coupling, team ownership, scaling, or reliability boundaries, then maybe yes. If the pain is simply that the codebase feels a bit untidy, maybe the answer is a refactor, not a new distributed system. And yes, I hate refactors as well.
I did not learn anything new today. More like I re-noticed something old: software usually gets complicated one reasonable decision at a time.