Architecture style

Monolith

The whole application lives in one codebase and ships as one deployable artifact. The simplest and cheapest starting point for most products.

Monolith: identical copies behind a load balancer and one databaseHTTPSUsersLoad balancerMonolith copy 1Monolith copy 2PostgreSQL
Monolith: identical copies behind a load balancer and one database

What it is

A monolith means all business logic (users, courses, payments, notifications) is built into one process. It is built and deployed together: one Docker image, one git push, one version in production.

It does not mean «one server». A monolith usually runs as several identical copies behind a load balancer, all talking to one database. Scaling is horizontal, each copy just knows how to do everything.

ShortLesson started exactly like this: a Next.js app that serves pages, the mobile API and the admin panel, plus one PostgreSQL. For thousands of users that is more than enough.

Why a monolith is fast

A call between modules inside one process costs nanoseconds, while a network call between services in the same data center is usually 0.5 to 2 ms plus serialization. If a request touches five modules, in a monolith you will not notice, in microservices it is real milliseconds and five points of failure.

Transactions are simple too: placing an order, charging the balance and recording an event can happen in one PostgreSQL transaction. No sagas, no compensations, no eventual consistency.

Where a monolith starts to hurt

The pain rarely comes from load, it comes from people. When 30 to 50 engineers work in one repository, the build takes 20 minutes, tests fail because of someone else's change, and one team's release blocks everyone.

The second problem is blurred boundaries. Without discipline any module reads any table, and the monolith becomes a «big ball of mud». The cure is a modular monolith, not necessarily a move to microservices.

How to scale a monolith

First add copies of the app behind a load balancer and move sessions out of process memory (into a cookie, a JWT or Redis). Next come a cache for hot reads and read replicas of the database.

Heavy jobs (video transcoding, mailings, reports) move to background workers with a queue, but the worker code can stay in the same codebase. In 2016 Stack Overflow served millions of requests a day with a monolithic .NET application on nine web servers.

Pros

  • One deploy, one repository, one process to debug.
  • Calls between modules without a network, ACID transactions across all logic.
  • The least infrastructure: no service mesh, broker or distributed tracing required.
  • Easy to refactor: the IDE sees all the code, renames work everywhere.

Cons

  • Large teams get in each other's way: a shared build, a shared release.
  • Without discipline, module boundaries blur.
  • It only scales as a whole: you cannot give more resources to one hot feature.
  • A bug in one module (a memory leak) can take down the whole application.

When to choose it

  • A new product whose requirements still change every week.
  • A team of up to 10 or 15 engineers.
  • You need strong transactional guarantees across parts of the domain.
  • The budget for infrastructure and DevOps is tight.

Where it is used

  • Stack Overflow: a monolithic .NET application on a handful of web servers (2016 architecture write-up).
  • Shopify: one of the largest Ruby on Rails monoliths, which the company modularized instead of splitting.

Tools

Sources

Logos belong to their owners and are used for identification only. Icons: Simple Icons (CC0), Devicon (MIT).