Monolith vs Microservices Architecture
The design tradeoffs between a unified codebase and a decentralized system of independent services.
The Monolithic Architecture: All-in-One
A monolithic architecture organizes software so that the entire application, comprising the user interface, backend business logic, and database access layer, is compiled and deployed as a single, unified unit.
Inside a monolith, different domains (such as payments, users, and orders) communicate using fast in-memory function calls. The monolith usually connects to a single, shared relational database, allowing database queries to perform multi-table joins across distinct business domains.
Limitations of the Monolith
While monoliths are easy to develop, test, and deploy early on, they become difficult to manage at scale:
- Scaling Bottlenecks: You cannot scale specific components independently. If the orders service is CPU-intensive, you must replicate the entire monolith container, which duplicates memory allocations for the rest of the application.
- Team Deployment Collisions: As engineering teams grow, multiple developers modify the same codebase. Deployment pipelines slow down because testing the entire application takes hours, and a single bug in a minor component can crash the entire system.
- Single Point of Failure: A memory leak or resource panic in one module takes down the entire application process, affecting all features.
The Microservices Alternative: Decentralization
A microservices architecture decomposes the application into small, independent services. Each service represents a distinct business capability (such as a billing service or search service) and operates as a standalone operating system process.
Key rules of microservices include:
- Database Per Service: To ensure decoupling, a service must never read or write to another service's database directly. All access must flow through public API endpoints.
- Independent Deployability: Teams can deploy updates to their service without coordinating with or redeploying the rest of the system.
- Technology Heterogeneity: Services can use different programming languages or databases that are optimal for their specific tasks.
Network IPC: Replacing Memory Calls with Protocols
Because services are separated across network boundaries, modules can no longer communicate via standard in-memory programming calls. Instead, they use Inter-Process Communication (IPC) protocols:
- REST over HTTP/1.1 or HTTP/2: Standard JSON-based requests, which are easy to implement but introduce significant text-parsing and network header overhead.
- gRPC / Protocol Buffers: A binary protocol over HTTP/2 that enables high-performance, strongly typed RPC (Remote Procedure Call) patterns.
- Asynchronous Message Brokers: Messaging platforms (such as RabbitMQ or Kafka) that process transactions asynchronously, improving decoupling.
Conway's Law: Code Follows Communication
The decision to choose a monolith or a microservice architecture is often organizational. Conway's Law states:
"Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations."
If you have a small startup team of 4 engineers, a monolith is optimal because they share context. If you split those 4 engineers across 5 microservices, they will spend most of their time maintaining complex integration APIs. Conversely, an enterprise with 500 developers split into independent product teams is well suited for microservices.
Migration Strategy: The Strangler Fig Pattern
To transition a legacy monolith to microservices, you should avoid a complete rebuild. Instead, engineers use the Strangler Fig Pattern.
This pattern places an API gateway or reverse proxy in front of the application. You intercept traffic going to the monolith, implement a single feature as a new microservice, and redirect that specific traffic path to the new microservice. Over time, more routes are routed to new microservices until the old monolith is completely deprecated.
Further Reading
- Building Microservices — Sam Newman's definitive book on microservices architecture and decomposition.
- Microservices: A Definition of This New Architectural Term — Martin Fowler's seminal article detailing microservices patterns.
- Conway's Law — Background context on Melvin Conway's thesis on software and organizational structures.
Prerequisites
Code Examples
Core Literature References
Building Microservices: Designing Fine-Grained Systems
by Sam Newman — Chapter 1: Microservices, Chapter 4: Integration, pp. 1-22, 55-89
View sourceMicroservices: A Definition of This New Architectural Term
by Martin Fowler — Introduction to Microservices, pp. 1-15
View sourceContinue learning
ACID & Isolation Levels
Deep dive into database transaction guarantees, isolation levels, concurrency anomalies like write skew, and control mechanisms such as MVCC, 2PL, and SSI.
API Gateways
Understand the API Gateway pattern as the central ingress point for microservices, handling routing, auth, rate limiting, and protocol translation.
API Security & OAuth 2.0
Understand API authentication and authorization mechanisms, JWT security, and the OAuth 2.0 framework including Authorization Code Flow with PKCE.