Monolith vs Microservices: I Picked Wrong - Here's My Experience
I migrated to microservices in 2021 and went back to modular monolith in 2023. 2 years wasted. Microservices is not a tech upgrade - it answers an organizational problem, not a technical one.
0xNN · · 10 min read
I remember 2021. My first startup was growing. Our Rails monolith had 50,000 lines. Deploys got slow, test suite took 20 minutes, one team on the same codebase caused constant conflicts. I read articles about Netflix, Spotify, Uber - all saying: "split into microservices, become scalable." I believed it.
3 months migrating. Split into 8 services. Result? Production became 3x more complex, not 3x faster. Latency went up, debugging became a nightmare, on-call alarms fired every night. The team that had 6 people needed 2 extra DevOps just to manage the kubernetes cluster.
The philosophy I learned the hard way: microservices is not a technology upgrade. Microservices answers an organizational problem, not a technical one. If you think microservices = "more modern," you'll go wrong like I did.
---
The Analogy That Makes It Clear
Imagine you run a restaurant.
Monolith = one big kitchen. All chefs cook in the same place, share stoves, share ingredients, share fridge. When it's busy, everyone's stressed. But if something breaks - stove fails - everyone knows, everyone fixes together. Coordination is easy because everyone's in the same room.
Microservices = each menu item has its own kitchen. Pasta kitchen, steak kitchen, dessert kitchen. Each kitchen is independent - own staff, own stock, own stove. If pasta kitchen is overwhelmed, steak kitchen isn't affected. But if a customer orders a complete package (appetizer + main + dessert), you need 3 kitchens to coordinate. The waiter runs back and forth. Billing is complex. If one kitchen fails to deliver, the whole customer experience breaks.
That's the microservices problem: cross-service coordination is often more expensive than the complexity you're trying to split.
---
Why Many Rush to Migrate
1. "Netflix did this" hype.
Netflix split into hundreds of microservices. Then every startup thought "this is the right way." But Netflix has 8000+ engineers. Your team has 6. The scale is 1000x different. What works for Netflix doesn't necessarily work for you.
2. "To scale independently."
Classic argument: "if auth service traffic spikes 10x, only auth scales, not the entire app." Sounds reasonable. But in practice: 90% of startups never reach a scale where this is a bottleneck. You scale up one monolith EC2 instance, done. You don't need microservices yet.
3. Conway's law, unrecognized.
Melvin Conway, 1967: "Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations." Meaning: your architecture will follow your team structure. Team of 5? Monolith is natural. Team of 50 across 5 cross-functional teams? Microservices makes sense. Many migrate the technology first, when the real issue is team structure.
---
When Monolith Wins
1. Small team (< 10 engineers).
Microservices require overhead: API gateway, service mesh, distributed tracing, CI/CD per service. 1 DevOps can handle 1 monolith. 1 DevOps drowns with 8 microservices.
2. Early-stage startup.
You don't know your product-market fit yet. Requirements change fast. Monolith is easy to refactor. Microservices mean every cross-service change = deploy coordination + backward compat.
3. Domain boundaries aren't clear yet.
Microservices need bounded context (DDD concept). You need to know: "feature A is about this, feature B is about that, where's the boundary." If you don't know yet, splitting first = wrong boundary, and re-migrating is 2x more painful.
4. Operational complexity isn't felt yet.
A 50,000-line monolith is actually small. Shopify runs a Rails monolith with 1M+ lines. Basecamp too. "Monolith doesn't scale" is a myth.
---
When Microservices Are Truly Needed
1. Team is big (40+ engineers) and cross-functional.
Payments team of 8, inventory team of 10, search team of 6. They shouldn't have to block each other. Service boundary = team boundary. Deploy independently. Release cycle fast.
2. Load scales very differently.
Auth service 10,000 RPS, billing service 100 RPS. 100x difference. Scaling up a monolith is wasteful - you pay RAM/CPU for services that don't need it. Microservices = scale each service as needed.
3. Domain is mature.
If your domain has been running 5 years, boundaries are stable, changes rarely cross services. You can split with confidence.
4. Failure isolation is needed.
Payment service down? Users can still browse catalog. Search down? Checkout still works. Monolith can't do this - one bug can crash everything.
---
What I Learned from a Failed Migration
1. Distributed monolith is hell.
You split into 8 services, but they still call each other, tightly coupled, deploy together. That's not microservices - that's a "distributed monolith." You get microservices complexity without the benefits. Worse than a regular monolith.
2. Data consistency becomes a new problem.
Monolith: User.where(active: true).count - 1 query. Microservices: user service + order service + billing service each with own DB. Want to know "active users who paid this month"? Need 3 service API calls, or data duplication, or event sourcing. Latency goes up 5x.
3. Observability must level up.
Monolith: 1 log file. Microservices: 8 log files across 8 servers. Without distributed tracing (Jaeger, Zipkin), debugging production incidents = guessing. You need correlation IDs, structured logging, alerting per service. Big investment.
4. Network is not free.
API call between services: 5-20ms latency. Function call in monolith: <1ms. 10 chained service calls = 100ms additional latency. You only notice when users complain "the app is slow."
---
Quick Comparison
| | Monolith | Microservices |
|---|---|---|
| Setup complexity | Low | High (API gateway, service mesh, observability) |
| Deploy speed | Slow (full app) | Fast per service |
| Scalability | Vertical + limited horizontal | Horizontal per service |
| Debugging | Easy (1 process, 1 log) | Hard (distributed tracing needed) |
| Data consistency | Easy (1 DB, transactions) | Hard (eventual consistency, saga) |
| Ideal team size | < 10-15 engineers | 40+ engineers across multiple teams |
| Failure isolation | Weak (1 bug crashes all) | Strong (service failure isolated) |
| Best for | Startup, MVP, new domain | Mature product, large org |
---
Common Misconceptions
"Microservices are modern, monoliths are legacy." - Wrong. Modular monolith (DDD architecture within one deploy unit) is a valid and modern choice. Github, Shopify, Basecamp - monoliths with millions of users.
"Using microservices = scalable." - Not automatic. You can scale a monolith vertically (big instance) or horizontally (multiple instances + load balancer). Microservices aren't a prerequisite for scale.
"Monoliths can't be split when they get big." - They can. Look at the "modular monolith" pattern - split into modules with clear boundaries within one codebase. You can migrate to microservices anytime once mature.
"Microservices make teams more productive." - Depends. Small teams will drown. Big teams with clear boundaries will be more productive. It depends on org structure, not technology.
---
An Honest Closing
I migrated to microservices in 2021 and went back to modular monolith in 2023. 2 years wasted on complexity that didn't need to exist. Our team was 8 people, we didn't need 8 services. What we needed: clear boundaries within one codebase, a solid deployment pipeline, and code discipline.
The real philosophy: microservices answers an organizational problem, not a technical one. If your team is small and constantly conflicts in the codebase, the answer isn't splitting into microservices. The answer: stricter code reviews, clearer module boundaries, tests that cover regressions. Split the organization first if needed - cross-functional teams, not layer-based teams.
Want microservices? Make sure: (1) team is big, (2) domain boundaries are clear, (3) you're ready to invest in observability + DevOps. If any one is missing, modular monolith is always better.
Choose your architecture based on your problem, not what's hyped on Medium.