I spent three years convinced that microservices were the answer to everything. Every new project, every side project, every internal tool — I’d break it down into services. API gateway here, auth service there, notification service over there.
Then I burned out. Not from the architecture itself, but from the overhead. Let me tell you what actually changed my mind.
The Breaking Point
It was a small internal tool — basically a dashboard for tracking customer support tickets. Four people were going to use it. Four.
What did I build? A Node.js API, a Python worker for background jobs, a separate auth service, and a React frontend. Plus Docker Compose to tie it all together locally. The setup took longer than the actual feature development.
When my manager asked why it took two weeks to ship a simple CRUD app, I didn’t have a good answer.
What I Learned
Here’s the thing about microservices: they solve real problems. Distributed teams can work independently. You can scale specific parts of your system. You can use different tech stacks for different needs.
But they also bring problems you don’t think about until you’re knee-deep:
- Local development gets messy. Running five services locally means five terminals, five logs, five things that can break.
- Debugging becomes a detective game. A single user action might trigger three services. Good luck tracing that request across containers.
- Deployment isn’t simple anymore. You need orchestration, service discovery, health checks. Kubernetes isn’t optional — it’s mandatory.
- Data consistency gets hard. Distributed transactions are a whole different beast. Eventually consistency sounds great until customers ask why their data isn’t showing up.
When Monolith Makes Sense
After that experience, I started asking myself one question before choosing microservices:
“Will the team size or system complexity actually benefit from this?”
For most projects under these conditions, a monolith is fine:
- Team of 1-5 developers
- No need to scale individual components independently
- Simple data relationships
- Startup speed matters more than future flexibility
You can always extract services later. It’s much harder to merge them back.
The Middle Ground
I’m not saying microservices are always bad. They’re not. But I’ve learned to be honest about what I’m building.
Now I start with a modular monolith — clean separation of concerns within one deployment. Services talk to each other internally. When a part genuinely needs to scale independently or a different team owns it, then we extract it.
That internal tool I mentioned? I rebuilt it as a single Express app over a weekend. It works great. The four people using it don’t care about my architecture decisions.
Bottom Line
Don’t let architectural perfectionism slow you down. Build what you need first. Extract when it hurts. That’s it.
