Stop Overengineering Everything
You know what scales really well? A monolith.#
I need to say this because the internet won't: most apps don't need microservices.
Your startup with 500 users doesn't need Kubernetes. Your side project doesn't need an event-driven architecture. Your blog doesn't need a distributed cache.
But every junior dev I interview talks about their "microservices architecture" for a to-do app. We need to stop.
The overengineering checklist#
Before you add complexity, ask yourself:
- Do I have more than 10 engineers? No? Monolith.
- Do different parts of my app scale independently? No? Monolith.
- Am I deploying different features on different schedules? No? Monolith.
- Is my database struggling? Add an index before you add a service.
Shopify runs on a monolith. So did GitHub for years. Basecamp still does. These aren't small companies.
The real cost of microservices#
Nobody talks about this part:
- Network calls instead of function calls. Every service boundary is a latency penalty and a failure point.
- Distributed transactions. Have fun with saga patterns when all you needed was a database transaction.
- Deployment complexity. Instead of deploying one thing, you're deploying twelve things and praying they're compatible.
- Debugging across services. A bug that would take 5 minutes to find in a monolith takes 2 hours across 6 services and 4 log aggregators.
When to ACTUALLY use microservices#
- You have 50+ engineers and they're stepping on each other
- One part of your system needs to scale 100x while the rest stays small
- You're integrating systems built in different languages
- You have a compliance requirement to isolate certain data
That's basically it.
The right amount of architecture#
Here's my rule: start with the simplest thing that could work, and add complexity only when you feel the pain.
Don't add caching until your queries are slow. Don't add a queue until your API is timing out. Don't split into services until your team can't deploy without conflicts.
Three lines of duplicated code is better than a premature abstraction. A slow monolith is better than a broken microservice mesh.
See the difference#
Want to see what an appropriately simple architecture looks like vs. an overengineered one? Try comparing them:
Go to Codelit, turn on Compare Mode, and type "monolith vs microservices for a simple SaaS app." You'll see exactly how much unnecessary complexity microservices add for a small team.
Compare architectures yourself
Stop reading about architecture. Start building it. Describe any system and watch it come alive.
Launch CodelitTry these templates
Small SaaS Launch Architecture
A single application with private file storage, tenant-scoped records, and idempotent billing events. Start small; scale from measured demand.
5 componentsFeedback to Roadmap Architecture
Preserve original evidence separately from model suggestions and require review before publishing roadmap changes.
5 componentsWebsite Monitoring Architecture
Isolate browsing, store dated evidence, and separate scheduled checks from approved report delivery.
5 componentsContinue learning
Go deeper on system design
As an Amazon Associate I earn from qualifying purchases. Codelit may receive a commission at no extra cost to you.
The Plant Was Never the Problem
How Engineering Managers Help People Speak Up, Grow, and Ship
A practical guide to the management systems that help engineering teams surface problems and keep shipping.
View on AmazonThis book is written by Codelit founder Mo Sharif. Its Amazon link is a paid affiliate link.
Building Microservices
Sam Newman · 2021
600 pages on splitting a monolith: service boundaries, data decomposition, migration order.
Enterprise Integration Patterns
Gregor Hohpe, Bobby Woolf · 2003
A catalog of 65 messaging patterns with diagrams - the vocabulary queue designs still use today.
4.6 (581)Learning Domain-Driven Design
Vlad Khononov · 2021
Turns bounded contexts and aggregates into decision rules for where service boundaries actually go.
4.6 (400)