Architecture Patterns
A single deployable application containing all features and logic, sharing one codebase, one database, and one deployment unit.
A monolith is a single application: one codebase, one build, one deployment. All features live together, all code can call any other code in-process, and a single database backs everything. Most successful systems start as monoliths because the development model is simpler, transactions across features are trivial, refactoring is cheap, and there is no network between any two functions.
"Monolith" is often used pejoratively but the truth is more nuanced. A well-modularized monolith — with clear internal boundaries, separate packages per domain, and discipline about coupling — can serve a large product for years. Companies like Shopify, Basecamp, and Stack Overflow have run successful "majestic monoliths" at significant scale.
Monoliths struggle when the team grows beyond what one shared deployment can support, when different parts of the system need radically different scaling profiles, or when build/test/deploy times outgrow the organization's tolerance.
Default to a monolith for any new project. Extract services later, when the boundaries have proven themselves and the team is large enough to warrant the operational cost.
Monoliths struggle with very large teams, mixed-tech-stack needs, and parts of the system that need independent scaling. The risk is becoming a "big ball of mud" without internal modularity.
An architectural style that structures an application as a collection of small, independently deployable services, each responsible for a specific business capability.
A single entry point that routes external requests to internal services, handling concerns like authentication, rate limiting, and request transformation in one place.
An architectural style where services communicate primarily by emitting and reacting to events, rather than calling each other directly.
A pattern that separates the model used for writing data (commands) from the model used for reading data (queries), allowing each to be optimized independently.
A dedicated infrastructure layer that handles service-to-service communication in a microservices architecture — encryption, retries, observability, traffic shaping — outside application code.