Monolith
A single, unified application where all features share the same codebase and deployment. Simpler to start with but harder to scale individual parts.
What is Monolith?
In short
A monolith is an application built and deployed as a single unit, where the user interface, business logic, and data access all live in one codebase and run in one process. You ship the whole thing together, scale it by running more copies of the same binary, and a change anywhere means redeploying everything.
What a monolith actually is
A monolith is one program that does everything your product needs. The signup flow, the payment logic, the email sender, the reporting screens, and the database queries all live in the same repository and compile or package into a single deployable artifact, like one JAR file, one container image, or one Rails app.
When you run it in production, every feature shares the same process and the same memory. A function calling another function is a normal in-process call, not a network request. That is the defining trait: components talk to each other directly inside the application instead of over HTTP or a message queue.
Monolith is not an insult. The first version of almost every successful product is a monolith because it is the fastest way to ship. Shopify, GitHub, and Stack Overflow have run enormous monoliths for years. The word only describes the deployment shape, not the code quality.
How it works under the hood
The whole application is built into one artifact. A typical Java monolith compiles into a single WAR or fat JAR; a Python one is a single app served by Gunicorn; a .NET one is one published service. You deploy that artifact to a server or container, and it boots as one operating system process.
Scaling is done horizontally by running more identical copies behind a load balancer. If checkout traffic spikes, you cannot scale just the checkout code, because checkout is not a separate thing you can run alone. You add more full copies of the entire app, even though only one module is busy. This is the main cost of the model.
State usually lives in one shared relational database that every part of the app reads and writes. Because all calls are in-process, a request can touch the user table, the order table, and the inventory table inside a single database transaction, which makes data consistency simple to reason about.
When to use it and the trade-offs
Reach for a monolith when the team is small, the product is still finding its shape, and you want one place to build, test, and debug. With everything in one process there is no network latency between modules, no distributed tracing to set up, and one deploy pipeline. Local development is starting one app, not orchestrating fifteen.
The pain shows up at scale. A monolith forces one language and one runtime on everyone. A single bad deploy can take down every feature at once. Build times grow until a one line change takes ten minutes to ship. And you cannot give the CPU-heavy image processor more cores without also paying to run more copies of the lightweight login page.
The honest answer for most teams is to start with a well organized monolith, keep clear internal module boundaries, and only split a piece into its own service when a real problem demands it, such as one component needing independent scaling, a separate team owning it, or a different runtime. Splitting too early buys you distributed systems complexity before you have the scale to need it.
A concrete example
Picture an online store as a monolith. A customer clicks Place Order. The web layer receives the request, the order module validates the cart, the inventory module decrements stock, the payment module charges the card, and the email module queues a receipt, all as ordinary method calls inside one running process, wrapped in one database transaction. If the payment fails, the transaction rolls back the stock change automatically.
Now the store goes viral. Order traffic is ten times normal but everything else is calm. To handle it you spin up twenty more copies of the entire store app behind the load balancer, each carrying the full code for browsing, search, admin, and reporting that nobody is hammering. It works, but you are paying to scale code that does not need scaling.
That tension is exactly where teams start carving the busy parts out into separate services. Until that point, the monolith was the right call, and trying to be clever earlier would have slowed the product down.
Where it is used in production
Shopify
Runs one of the largest Ruby on Rails monoliths in the world, serving millions of merchants from a single codebase organized into internal modules.
GitHub
The core product is a large Rails monolith that the company has kept and modernized rather than rewritten into microservices.
Stack Overflow
Famously serves enormous traffic from a small monolithic .NET application running on a handful of servers, proving monoliths scale further than people assume.
Basecamp
Built and runs as a single Rails monolith on purpose, and its creators publicly advocate the majestic monolith approach for small teams.
Frequently asked questions
- Is a monolith bad?
- No. It is the simplest way to build and ship, and it is the right choice for most early-stage products and small teams. It becomes a problem only at large scale, when independent scaling, multiple teams, or different runtimes start to matter.
- What is the difference between a monolith and microservices?
- A monolith is one deployable unit where modules call each other in-process. Microservices split those modules into separately deployed services that talk over the network. Monoliths trade independent scaling and team autonomy for simplicity and speed.
- Can a monolith scale to millions of users?
- Yes. You scale it horizontally by running more copies behind a load balancer, and the database usually becomes the bottleneck long before the app code does. Stack Overflow and Shopify both serve massive traffic from monoliths.
- What is a modular monolith?
- A modular monolith is a single deployable application with strong internal boundaries between modules, so each module has a clear interface and limited access to the others. It gives you most of the organizational benefits of microservices without the network and operational overhead.
- When should I break a monolith into services?
- Split a piece out when there is a concrete reason: one component needs to scale independently, a separate team needs to own and deploy it on its own schedule, or it needs a different language or runtime. Splitting just because microservices sound modern usually adds cost without benefit.
Learn Monolith hands-on
This page explains the idea. The full lesson lets you step through the ring as servers join and leave, read the implementation, and check yourself with a quiz. It is one of 760+ lessons in the System Design Masterclass, from your first API call to distributed consensus. Eleven Foundation lessons are free, no signup. Lifetime access is ₹499 in India or $7.99 worldwide, one payment, no subscription.
Related lessons
Lessons that touch on Monolith as part of a larger topic.
Monolithic Architecture
The single-unit application architecture that every system starts with, and why it works until it doesn't
intermediate · microservices architecture
Strangler Fig Pattern
Migrate from monolith to microservices incrementally, replacing pieces one at a time while the old system stays alive
intermediate · microservices architecture
Database Federation
Splitting your monolithic database into multiple specialized databases by domain, reducing load and enabling independent scaling
intermediate · database types storage
Service-Oriented Architecture (SOA)
The predecessor to microservices, how enterprise systems first broke apart monoliths using shared services and an ESB
intermediate · microservices architecture
See also
Related glossary terms you might want to look up next.
Microservices
An architecture where an application is split into small, independent services that communicate over the network. Each service owns its own data and can be deployed separately.
Vertical Scaling
Making a single machine more powerful (more CPU, RAM, storage). Simpler but has physical limits. Also called 'scaling up.'
Service Discovery
The mechanism by which microservices find and communicate with each other. Services register themselves and others can look them up by name.
Circuit Breaker
A pattern that stops calling a failing service after repeated failures, preventing cascade failures. Like an electrical circuit breaker that cuts power to prevent fires.
Bulkhead
A pattern that isolates different parts of a system so a failure in one part doesn't sink the whole ship. Named after the compartments in a ship's hull.
Retry
Automatically re-attempting a failed operation, usually with exponential backoff. Essential for handling transient failures in distributed systems.