Netflix, Amazon, Uber, Twitter, every single one of them started as a . One codebase. One deployment. One database. And for a good while, it worked perfectly.
There's a weird cultural thing in tech right now where "monolith" is almost a dirty word. Developers talk about like they're the only serious architecture, and monoliths are something you should be embarrassed about. That's nonsense.
Shopify handles billions of dollars in transactions every year. It's a monolith. A massive Ruby on Rails monolith. Stack Overflow serves millions of developers daily with a small team and a monolithic .NET application. They're not behind the times, they made a deliberate architectural choice.
Here's the thing nobody tells you in system design tutorials: the monolith is the default for a reason. It's simpler to build, simpler to deploy, simpler to debug, and simpler to reason about. The question isn't "should I use microservices?", it's "has my monolith hit the wall where microservices actually solve a real problem?"
Understanding monolithic architecture deeply is the foundation for everything else in this category. You can't understand why microservices exist if you don't understand what monoliths do well and where they break down.
A monolithic application is a single deployable unit that contains all of your application's functionality. The user interface, the business logic, the data access layer, background jobs, everything lives in one codebase and gets deployed as one artifact.
Think of it like a house. A is a single-family home. The kitchen, bedrooms, bathroom, living room, they're all under one roof, connected by hallways. If you want to renovate the kitchen, you're working inside the same building where everyone sleeps. If the plumbing breaks, it affects the whole house.
Compare that to an apartment complex (), where each unit is independent. But we'll get there later.
In concrete terms, a monolithic app typically looks like this:
| Layer | What It Does | Example |
|---|---|---|
| Presentation | Handles requests, renders UI | Controllers, templates, API routes |
| Business Logic | Core rules and workflows | Order processing, payment validation |
| Data Access | Talks to the database | ORM queries, , repositories |
| Infrastructure | Cross-cutting concerns | Logging, auth, email sending |
All of these layers live in the same process. When you hit the "Place Order" button, the request enters the presentation layer, flows through business logic, hits the database, and returns, all within a single application process. No network calls between services. No message queues. No . Just function calls.
Every monolith follows this stack. Clients hit the presentation layer over the network. From there, everything is in-process function calls. No serialization, no retries, no . The entire execution path from HTTP request to database query lives in a single debugger session.
Before we talk about problems, let's be honest about why monoliths dominate the early stages of every successful company.
Simplicity of development. One codebase. One IDE project. One set of dependencies. A new developer joins, clones one repo, runs one command, and they're up. With , that same developer might need to set up 15 different services, each with their own database, just to run the app locally.
Straightforward debugging. When something breaks in a , you set a breakpoint and step through the code. The entire execution path is right there in your debugger. In a distributed system, a single user request might touch 8 services, and the bug could be in any of them, or in the network between them.
Zero network overhead between components. When your order service calls your inventory service, it's a function call. A function call takes nanoseconds. A network call between microservices takes milliseconds at best. That's a million-fold difference.
Atomic transactions. You can wrap "deduct inventory AND charge payment AND create order" in a single database transaction. If any step fails, everything rolls back. Try doing that across three separate microservices with three separate databases. You'll need sagas, compensating transactions, eventual consistency, the complexity explodes.
Simple deployment. One build artifact. One deployment pipeline. One thing to monitor. You deploy it, and either the whole thing works or it doesn't.
| Aspect | Monolith | Microservices |
|---|---|---|
| Time to first deploy | Hours | Days to weeks |
So if monoliths are so great, why did Netflix, Amazon, and Uber move away from them? Because monoliths have a scaling ceiling, and when you hit it, you hit it hard.
Team scaling. When you have 5 developers, a is paradise. When you have 50, it's a traffic jam. Everyone is working in the same codebase. Merge conflicts become a daily ritual. A change in the payment module accidentally breaks the notification system because they share a utility function. Deployments require coordination between 8 teams.
Deployment coupling. You fixed a typo in the "About" page? Great. But to deploy that fix, you have to deploy the entire application, including the risky database migration that another team just merged. Every deployment becomes a high-stakes event because everything ships together.
Technology lock-in. Your monolith is in Java. The ML team wants to use Python. The real-time team wants to use Go. Too bad, everyone uses Java, because it's one application. You can't pick the best tool for each job.
Selective scaling is impossible. Your search feature gets 100x more traffic than your admin panel. With , you'd scale search independently, spin up 50 search instances while keeping 2 admin instances. With a monolith, you scale the entire application. Those 50 instances each include the admin code that nobody is using.
The "big ball of mud" problem. Over time, without extreme discipline, module boundaries erode. The order module starts importing from the user module which imports from the notification module which imports from the order module. Everything depends on everything. Changing one thing means understanding and testing everything.
When Search needs 100x more capacity, you clone the entire . Orders, Users, Admin, everything. Every instance carries dead weight. The single shared database becomes the bottleneck as all instances hammer it with connections.
The decision tree is simpler than most people think. If the monolith is not causing pain, do not touch it. If the pain is team scaling (merge conflicts, deploy coordination), try modular monolith first. If the pain is performance (one module needs 100x scale), extract just that module. Full decomposition is the last resort, not the first impulse.
Shopify processes over $200 billion in commerce annually. Their core application is a massive Rails monolith, one of the largest in the world. They didn't decompose into . Instead, they invested heavily in modularizing the . Clear module boundaries, enforced dependency rules, and a concept they call "components" that behave like services but run in-process.
Their reasoning? The operational complexity of microservices wasn't worth it for their team and their problem domain. A well-structured monolith with a great deployment pipeline beat microservices for them.
Stack Overflow serves 100+ million developers per month with a team of about 50 engineers. Their architecture? A .NET monolith running on roughly 9 web servers. They've been extremely vocal about this: the simplicity of their architecture lets them move fast, debug easily, and keep infrastructure costs low.
In the early 2000s, Amazon's monolith became the bottleneck. The codebase was so tangled that deploying a single change required a "merge Friday" where teams would spend an entire day resolving conflicts. Jeff Bezos issued the famous mandate: every team must expose their functionality through APIs, and no team can access another team's data directly. That mandate birthed AWS and Amazon's microservices architecture.
The lesson? Amazon didn't switch to microservices because monoliths are bad. They switched because at their scale and team size, the monolith had become the bottleneck for organizational velocity.
3 questions - Score 80% to pass
What is the primary advantage of a monolithic architecture for small teams?
Why did Amazon transition from monolith to microservices?
Shopify handles $200B+ in annual commerce. What architecture do they use?
The key insight from this diagram: everything talks to everything through in-process function calls. That's both the greatest strength and the eventual weakness of a .
| Local development setup |
| 1 repo, 1 command |
| 5-20 repos, compose |
| Debugging a request | Breakpoint, step through | Distributed tracing across services |
| Database transactions | , trivial | Sagas, eventual consistency |
| New developer onboarding | Days | Weeks |
Most teams jump straight from monolith to and skip the middle option. Shopify handles $200B+ annually on a modular monolith. Stack Overflow serves 100M+ developers on a plain monolith. The modular monolith gives you team scaling and code ownership without the distributed systems tax. Start there before reaching for microservices.
Amazon's famous mandate came after years of team scaling pain with 1,000+ engineers. Your 15-person startup is not Amazon.