Software architecture
Monolithic architecture
Monolithic architecture builds an application as one deployable unit that holds the user interface, business logic and data access in a single codebase.
Most applications start as a monolith, and plenty of large ones stay that way. One codebase, one build and one deployment are simple to reason about, which is exactly what a small team shipping a new product needs.
Why does monolithic architecture matter?
- Simplicity. One repository, one pipeline and one thing to deploy. A new engineer can run the entire system on a laptop.
- Speed of development. Calling another module is a function call, not an API with a schema, a client and a retry policy.
- Transactions. One database means one transaction can span orders, payments and inventory.
- Easy debugging. A single stack trace covers the whole request.
- Lower operating cost. No gateway, broker or service registry to run, and no network latency between modules.
What are the parts of a monolithic architecture?
- Presentation layer. The web UI, REST API endpoints and admin pages. It accepts requests, validates input and calls into the business logic.
- Business logic layer. The modules that implement the domain: catalog, orders, payments and accounts in the example above.
- Data access layer. Repositories, an ORM and connection pooling. It turns objects into SQL and back.
- Database. One relational database shared by every module, with foreign keys between their tables.
- Deployment unit. The whole thing compiles to one artifact, such as a container image or a binary, and runs as one process that is copied behind a load balancer or API gateway to scale.
The layers are the same shape as a three-tier architecture, except that they run in one process rather than on separate servers. From the browser’s side it is an ordinary client-server system.
What are the types of monolithic architecture?
Classic monolith
Modules can call anything anywhere. This is the way most codebases grow by default, but dependencies accumulate until catalog code reads order tables and a change in payments breaks accounts.
Modular monolith
One deployable and one database, but every module has a defined public interface and private internals, enforced by the build system or by code review. Catalog can call the orders module’s API; it cannot touch its tables or classes. Modules often talk through in-process events, which is an event-driven architecture without the broker. This is the recommended shape for a monolith that is expected to grow, and it makes extracting a module later a mechanical change.
Distributed monolith
Several deployables that must be released together because they share a database or call each other synchronously for everything. This is the failure mode of a microservices migration: the coordination cost of a monolith plus the cost of distribution.
How does monolithic architecture compare with modular monoliths and microservices?
| Monolith | Modular monolith | Microservices | |
|---|---|---|---|
| Deployables | One | One | One per service |
| Databases | One, shared | One, with a schema per module | One per service |
| Module boundaries | Convention | Enforced in code | Enforced by the network |
| Calls between modules | In process | In process, through interfaces | Over the network |
| Independent scaling | No | No | Yes |
| Operational overhead | Low | Low | High |
The middle column is the one most teams underrate. A modular monolith delivers clean boundaries with the operational profile of a single application. Move to microservices only when a specific module needs to deploy or scale on its own schedule.
How do you read a monolithic architecture diagram?
Follow a request from the user down through the layers. In the online store example at the top of this page, a browser calls the presentation layer over HTTPS. A controller there calls the orders module in the business logic layer, which may call catalog to check prices and payments to charge the card, all in the same process. The orders module then calls a repository in the data access layer, which writes to the single database over SQL.
Everything inside the tinted group is one deployable. Scaling it means running more copies of the whole thing, including the admin pages nobody is using, which is the cost that eventually pushes large systems toward splitting.
How do you design a monolith well?
- Pick the modules by domain. Name them after business capabilities, such as orders and payments, not technical layers.
- Give each module a public interface. Everything else is private. Enforce it with package visibility, separate build targets or a linter rule.
- Keep the layers one way. Presentation calls business logic calls data access. Nothing calls upward.
- Assign tables to modules. Even in one database, decide which module owns each table and route other modules through its interface.
- Keep it stateless. Store sessions and caches outside the process so you can run several copies behind a load balancer.
- Draw it. An architecture diagram of the modules and their allowed dependencies, plus a system architecture view of what sits around the monolith, makes violations visible in review.
What are common monolithic architecture mistakes?
- No module boundaries. Code that can call anything will. Within a few years every change is risky.
- Business logic in the UI or the database. Rules spread across controllers and stored procedures cannot be tested or reused.
- Sessions in memory. A stateless monolith scales horizontally well. One that keeps sessions in the process does not.
- Breaking it up too early. Splitting a system you do not yet understand produces the wrong services, whether they are containers or serverless functions. Make the modules clean first.
What tools help with monolithic architecture?
- Build tools with module support. Multi-module builds in Gradle, Maven, Bazel and most language toolchains let you enforce which modules may depend on which.
- Architecture test libraries. ArchUnit, NetArchTest and similar tools fail the build when a module reaches into another’s internals.
- AI diagramming tools. Tools like Eraser turn a description of your modules and layers into an architecture diagram you can keep editing, which is the quickest way to agree on boundaries before enforcing them.
For more on this kind of diagram, see architecture diagrams.
Frequently asked questions
-
Is monolithic architecture bad?
No. A monolith is the simplest architecture that works, and it is the right choice for most new products and small teams. It becomes a problem when the codebase grows past what one team can understand, when modules become so tangled that any change risks everything, or when parts of the system need to scale or release on different schedules.
-
What is a modular monolith?
A modular monolith is one deployable unit whose code is split into modules with strict boundaries. Each module exposes a small public interface and keeps its internals and often its database tables private. It gives most of the design benefits of microservices without the network calls, separate deployments and operational overhead.
-
What is the difference between a monolith and microservices?
A monolith is one process that holds every feature and talks to one database. A microservices architecture splits those features into separately deployed services that communicate over the network and each own their data. The monolith is easier to build and run; microservices let teams deploy and scale parts independently.
-
When should you break up a monolith?
When the cost of coordination is higher than the cost of distribution: releases wait on unrelated teams, one hot module forces the whole application to scale, or a failure in a minor feature takes down a critical one. Extract one capability at a time, starting with the one that would benefit most from independence.