Put the user interface, the business logic and the data access code in one codebase, deploy it as a single unit, and you have a monolith. Components call each other in-process, so no network request separates them.
Most web applications start this way because early development is easier than with microservices (Microsoft Learn, 2022). David Heinemeier Hansson has written Basecamp as a monolith since 2003, according to his 2016 Signal v. Noise post.
The label describes the deployment unit, not the quality of the code. A monolith can still be built from separate libraries, components and layers, as Microsoft’s .NET guide notes.
What Is Monolithic Architecture?

The whole program gets built, deployed and run as one. Every component sits in the same process, so one part of the application reaches another with a plain function call, not a network request.
It all lives in one shared codebase and ships as a single artifact, whether that’s a JAR, a WAR, an executable or a container image.
History explains why it became the default. Early development is easier than with microservices, and a lot of teams built this way because tooling made service-based designs too hard at the time (Microsoft Learn, 2022).
Within software architecture, it sits opposite microservices, which split the same functions across separately deployed services.
The term gets misread in a couple of ways. It doesn’t mean a flawed design, since a monolith can be cleanly layered and a distributed system can be a mess. It also says nothing about size or language. Shopify’s main codebase is a monolith with millions of lines of Ruby, and the style shows up in Spring Boot and .NET projects too.
How a Monolithic Application Is Structured

Inside the one codebase, code usually splits into presentation, business logic and data access. All of it shares one process and one database.
Layers inside one codebase
The presentation layer renders pages or API responses. Business rules such as pricing or order validation sit in the logic layer, and the data access layer reads and writes the database.
This is classic layered architecture, and it sorts code by technical role. Microsoft’s .NET guide notes that an application can be layered this way internally (application, domain and data-access layers) and still ship as one container (Microsoft Learn, 2022).
Layers sort code by role, not by owner, so nothing in them says which team is responsible for billing logic.
How MVC frameworks arrange the code
Rails is the clearest case. Its guides describe code organized around the MVC pattern, where the model manages data (typically database tables), the view renders responses in formats such as HTML or JSON, and the controller handles each request (Ruby on Rails Guides, 2025).
The controller reaches the model, the model reaches the database, and all of it runs in one process.
In-process calls instead of network calls
A call between modules is just a function call.
There’s no serialization step and no timeout to handle, and a request can’t half-fail the way it can over a network. That removes the network latency and partial failures that distributed designs have to deal with.
One shared database
All modules read and write the same relational database, usually PostgreSQL or MySQL, so a single transaction can span every table a request touches.
The catch is access control. Nothing stops one module from querying another module’s tables, and Shopify’s engineers rank the assumption that any Active Record model can be used anywhere among the most problematic in their codebase (Shopify Engineering, 2020).
How Is a Monolithic Application Deployed and Scaled?
A monolith gets built into one artifact (a JAR, WAR, executable or container image) and runs as one process. To scale it, you move to a bigger machine or run identical copies of the whole application.
One artifact, one process
Spring Boot’s Maven and Gradle plugins generate the executable JAR automatically, with dependencies nested inside it (Spring Boot reference documentation). That single file is the whole application.
Microsoft’s .NET guide describes the container version: one container or VM represents the app, and a change to any component means retesting everything and redeploying every instance (Microsoft Learn, 2022).
Containers keep that redeploy cheap. Docker images typically start in seconds and stop in under a second, per the same guide.
On Kubernetes, a ReplicaSet (usually managed through a Deployment) keeps the requested number of identical Pods running, and .spec.replicas defaults to 1, per the Kubernetes documentation.
Vertical and horizontal scaling
How far a monolith grows before costs climb depends on vertical and horizontal scaling.
Going vertical means moving to a bigger machine. You change no code, but the ceiling is the largest server available.
The horizontal route runs identical copies behind a load balancer, which Microsoft’s guide describes as adding more copies with the balancer in front.
The cost sits in the word identical. Every copy carries the whole codebase, so the browsing code in a store scales at the same grade as the checkout code, even though far more customers browse than pay (Microsoft Learn, 2022).
Release cycle and build time
One codebase means one build and one release train. Every change waits for the same test run.
That is why Shopify’s modularity effort aims to run tests only on the components a change touches, instead of the whole application (Shopify Engineering, 2020).
Monolithic Architecture vs Modular Monolith vs Microservices
The plain monolith ships as one unit with open internal access, and a modular monolith keeps that single deployable while enforcing boundaries between modules. Microservices deploy each module as its own service.
| Dimension | Monolith | Modular monolith | Microservices |
|---|---|---|---|
| Deployment | One unit | One unit | One per service |
| Data access | Shared database, open to all code | Shared database, module rules | Typically one datastore per service |
| Communication | In-process calls | In-process calls across modules | Network calls |
| Scaling unit | Whole application | Whole application | Individual service |
| Main cost | Coupling grows with size | Discipline to hold boundaries | Operating many services |
Modular monolith
A modular monolith divides one deployable into components with defined boundaries and a named owner for each.
Shopify’s core application has more than 2.8 million lines of Ruby and 500,000 commits, organized into 37 components (Shopify Engineering, 2020).
The split followed domain-driven design (Eric Evans’s approach to drawing boundaries around business subdomains). Components map to subdomains of commerce, not to technical layers.
Rails Engines make it work. Several can run in one process, and an engine can become a standalone application if a team later extracts it, per the same post.
Boundaries don’t enforce themselves, though. Shopify’s dependency analysis found a graph so dense that every component depended on more than half of the others, with circular dependencies on top.
Microservices

Microservices trade the shared process for independence.
In a microservices architecture, each module becomes a small service with its own deployment.
Each service runs in its own process and talks to the others over HTTP/HTTPS, WebSockets or AMQP, per Microsoft’s .NET microservices guide (2022). Each one also scales out on its own. The price lands on the team, because managing a suite of services slows it down. Martin Fowler calls this the microservice premium, and it favors a monolith for simpler applications (Fowler, 2015).
Where the sources disagree
The monolith-first camp leans on Fowler, who noted that in the stories he had heard, almost all successful microservice systems began as a monolith that grew too big. Almost all systems built as microservices from scratch ended up in serious trouble.
The services-first argument runs the other way. Building a monolith modular enough to split later takes a lot of discipline, perhaps too much, and small teams separated by service boundaries from day one make it easier to scale development.
Fowler’s own 2015 post calls the evidence sparse and his advice tentative.
The second argument follows Conway’s law, Melvin Conway’s 1968 observation that systems end up mirroring the communication structure of the organization that builds them.
Fowler’s condition for starting with services is a team that has already built a microservices system. Without that experience, the monolith is the safer first build while domain boundaries are still unclear.
Advantages of Monolithic Architecture

A monolith wins on simplicity. There’s one codebase to debug, one artifact to ship, and one team that can understand the whole system.
- The first release is cheaper, since there’s no service boundary to design, secure or operate.
- Debugging happens in one place. A failing request leaves one stack trace, not a trail across services.
- Turning a call between objects into a call between systems brings service outages and coordinated migrations, argues David Heinemeier Hansson (DHH) of Basecamp (Signal v. Noise, 2016).
- Knowledge isn’t siloed in small systems, so the people working on the app also understand it.
Testing follows the same logic. Integration testing runs against one deployed process, so a failure points at one codebase.
The cost gap is measurable. In a study of 21 practitioners who had migrated to microservices, all reported higher initial costs, and 76% reported 20% to 30% more development effort than a monolith would have taken (Taibi, Lenarduzzi and Pahl, IEEE Cloud Computing, 2017).
The sample is small and the survey dates from 2017, so read it as a direction, not a benchmark.
Where Monolithic Architecture Breaks Down
One fault can stop every feature, coupling slows each change, the stack resists variety, and releases queue behind each other as teams grow.
Single point of failure
One bug can take every feature down. Twilio Segment named this the first cost of its consolidation, saying that if one destination’s code crashes the service, the service crashes for all destinations (Twilio, 2018).
Running several copies behind a balancer buys high availability against hardware faults, not against a defect shipped in every copy.
Coupling, lock-in and release friction
Upgrading a shared library can break several features at once, which Segment listed as its third trade-off. A monolith also takes one stack, and interviewees in Taibi’s study said a new language fits a service far more easily than a monolith (Taibi, Lenarduzzi and Pahl, 2017).
Then there are the people. At a certain scale, DHH writes, everyone steps on each other and merge conflicts pile up, and he points to organizations with thousands of developers such as Amazon and Google (Signal v. Noise, 2016).
The queue is the part teams feel first. Every team ships through one software release cycle, so a finished feature waits for the slowest change in the build.
Distributed monolith: the failed split
Every interviewee outside the migration consultancies in Taibi’s study had connected new services to a legacy database or database cluster, because they could not split the existing data.
That is a distributed monolith: services deployed separately that still change and release together because they share data. Sam Newman’s Monolith to Microservices (O’Reilly, 2019) lists it as a monolith type next to the single-process one.
The network cost arrives and the coupling stays.
Where these limits stay mild
Team scale matters here. The examples DHH gives of coordination breaking down are organizations with thousands of developers, not dozens.
Fault containment is another case. Segment’s stated plan was to build isolation inside the monolith instead of splitting it again.
When Does a Monolith Make Sense?

A monolith makes sense for small teams, one product and an early stage where boundaries are still unclear. It stops making sense when independent scaling, independent releases or a very large organization force the split.
- Services pay off when coordination, not code, is the bottleneck, which DHH illustrates with organizations of thousands of developers.
- Split a workload only when it needs a different scale or release rhythm than the rest.
- Every interviewee in Taibi’s study needed a DevOps infrastructure for microservices, on top of the development effort.
- For quick prototypes and short-lived projects, the same paper notes microservices can cost more than a monolith.
Published cases
- Amazon Prime Video cut infrastructure cost by over 90% in 2023 after its video quality monitoring service moved into a single process (Prime Video engineering, March 2023).
- Twilio Segment consolidated over 140 services into one in 2018. 3 full-time engineers had been spending most of their time keeping the microservices alive (Twilio, 2018).
- About 12 programmers maintain Basecamp (2016) across web, mobile, desktop and email as a majestic monolith.
Prime Video’s gain came from removing coordination overhead. The original design paid for several state transitions for every second of the analyzed stream, plus storage reads and writes for intermediate frames, and a single process moved that data transfer into memory (InfoQ, 2023).
TechTarget points out the result is a monolith only at the service level, one monitoring service inside a larger platform. Reading the case as “microservices failed” overstates it.
Segment’s team said microservices worked in some parts of its infrastructure but hurt productivity and performance for its server-side destinations.
DHH offers a test. Keep integrating the system until one person can no longer hold it all in their head. In a 2019 comment on his own post, he said Basecamp had not reached that point and that tooling had not changed his view.
The counter-case and where the evidence splits
Netflix went the other way. A major database corruption in August 2008 stopped DVD shipping, and the company moved away from vertically scaled single points of failure, rebuilding virtually all its technology for the cloud (Netflix, 2016).
Sources disagree on whether the extra effort of services pays back. Taibi’s interviewees reported that it did, within two to three years, through lower maintenance effort.
Prime Video and Segment show the opposite for specific workloads. The survey covered teams that had already migrated, so it cannot count the teams that turned back.
Several practitioners in that study also said they adopted microservices because other companies had. The simpler option is the better default until a named pressure (scale, release independence or team size) argues otherwise.
How to Move Off a Monolith Without a Rewrite

Extract one module at a time behind a routing facade, move its data only after the new service works, and keep the monolith running until the service has proven itself.
Define Module Boundaries First
Boundaries decide whether the split works. Martin Fowler warns that an arbitrary system cannot be assumed splittable, because most systems accumulate too many dependencies between modules, and he has heard of plenty of attempts that quickly ended in a mess (Fowler, 2015).
Start with code refactoring inside the monolith. Fowler’s strangler fig post says legacy systems rarely have components that can be replaced independently, so teams must find seams that allow a split (Fowler, 2024 revision).
Map the dependencies before choosing. Practitioners in Taibi’s study used tools such as Structure101 and SchemaSpy, ranked candidates by bug count, and took the one with the fewest dependencies first when priorities tied.
Extract With the Strangler Fig Pattern
Fowler first described the idea in 2004 as the Strangler Application. It replaces a legacy system piece by piece instead of in one cut-over.
Microsoft’s Azure Architecture Center, as of its June 2026 update, describes the mechanics. A facade (proxy) intercepts requests and routes each one to the legacy system or the new service, shifting more traffic as features move.
- Map dependencies and pick the seams where one module can separate from the rest
- Rank candidates: more bugs and fewer dependencies go first
- Put a facade in front of the monolith, which at first sends it nearly every request
- Build the service for one module while it still reads and writes the monolith’s database
- Give the service its own database: load it with ETL, keep it in sync with change data capture, validate before cutover
- Run old and new side by side on the same input and compare the outputs (a parallel run)
- Shift traffic to the service, then remove the module’s code and tables from the monolith
Plan the rollback before the cutover. Microsoft’s guidance says rolling back stays simple until the domain tables and sync processes are removed from the monolithic database, after which it means restoring objects and replaying changes.
The facade carries its own risk. It must not become a single point of failure or a performance bottleneck.
The pattern also doesn’t fit every system. It falls apart when requests to the back end cannot be intercepted, or when you have no access to the legacy source code or to another integration point you can change. If the system is small enough that replacing it whole is simple, or the original must be fully decommissioned quickly, skip it.
Taibi’s interviewees who built only new features as services around the monolith reported lower migration cost, with a longer road to retiring the legacy system. Newman’s book catalogs the strangler fig application beside UI composition, branch by abstraction and parallel run.
The coexistence code is temporary, and Fowler accepts the cost because the reduced risk and earlier value outweigh it.
Monolithic Architecture FAQ
Is a monolithic kernel the same thing as a monolithic application?
No. In a monolithic kernel, the operating system’s kernel directs all functionality.
Monolithic architecture is about applications, where one codebase deploys as one unit. The shared word points to the same idea, one block, applied at different levels.
Can a three-tier application count as a monolith?
Yes. Three-tier describes how an application divides into presentation, logic and data, while monolithic describes how it deploys.
A three-tier app whose code ships as one unit is a monolith. The same tiers can also be split into separately deployed services.
How does monolithic architecture differ from service-oriented architecture?

A monolith keeps every component in one process, while service-oriented designs run each function as a separately deployed service.
In service-oriented architecture, calls cross the network, which adds the latency and failure handling a monolith avoids.
Does a monolith give better security than microservices?
Not by default. A monolith has fewer network entry points between components, while microservices add service-to-service calls to secure.
But a monolith shares one process and one database, so a flaw in one module can reach every other.
Is monolithic architecture outdated?

No. The style has evolved rather than disappeared, and the modular monolith keeps one deployable while adding enforced module boundaries.
Teams still choose it when team size and product scope do not justify the operating cost of services.
Keeping a Monolith Healthy as the Team Grows
A monolith stays healthy when module boundaries are enforced by the build, not by convention. A build step that fails when one module reaches into another’s internals keeps changes independent as the team grows.
The order of work matters.
- Enforce module boundaries in the build
- Contain faults inside the process, riskiest module first
- Extract a module only when its scale or release rhythm diverges
Boundaries come first because the next two steps depend on them. Fault containment needs a defined module to wrap, and extraction needs a seam to cut along.
The price is refactoring time spent before any visible feature ships, plus a temporary facade if extraction follows. Teams ready for step one can start with modular software architecture.
As of October 2026, that order holds until one module needs its own scaling profile or release rhythm, which moves extraction ahead of fault containment.
- What Communications Teams Should Ask Before Commissioning a Mobile App - November 12, 2026
- How to Install Node JS in VS Code and Run Your First Script - November 11, 2026
- Protecting Users and Brand Standards Across Image-Driven Platforms - November 10, 2026



