High-Level Design Tutorial 0/42 lessons ~6 min read Lesson 5

    Monolithic Architecture

    A monolith is a single deployable application containing all business modules — user management, catalog, checkout, notifications — sharing one process space and typically one p…

    Course progress0%
    Focus
    10 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Introduction

    A monolith is a single deployable application containing all business modules — user management, catalog, checkout, notifications — sharing one process space and typically one primary database. For startups and many enterprise systems, monoliths remain the fastest path to market and the easiest architecture to debug.

    HLD interviews are not anti-monolith by default. Strong candidates explain when a monolith is correct (small team, unclear domain, low scale) and when cracks appear (independent scaling needs, conflicting release cycles, compile times measured in minutes).

    This lesson covers monolith topology, modular monolith patterns, scaling tactics, and the migration triggers that lead to microservices in later lessons.

    Understanding the topic

    Key concepts

    • Single codebase, single deployment unit, shared runtime and often one relational database.
    • Modular monolith: enforce package boundaries inside one JVM to delay network split.
    • Scaling: vertical first, then horizontal replicas behind load balancer (stateless web tier).
    • Database is usually the first bottleneck — connection pools, read replicas, caching.
    • Deployment risk: any change redeploys everything — feature flags and CI/CD mitigate.
    • Operational simplicity: one log stream, one trace, no distributed transaction saga yet.
    text
    flowchart TB
    Client --> App[Monolithic App]
    App --> DB[(Single DB)]

    Internal architecture

    Architecture overview

    text
    flowchart TB
    Client --> App[Monolithic App]
    App --> DB[(Single DB)]

    Step-by-step explanation

    1. Clients hit load balancer → N identical app instances (stateless session in Redis if needed).
    2. Monolith layers: controllers → services → repositories → single PostgreSQL cluster.
    3. Background jobs run in same process or sidecar worker consuming same DB/queue.
    4. Static assets offloaded to CDN; API remains on origin.
    5. Read scaling: cache-aside Redis + PostgreSQL read replicas for reporting.
    6. Extract service only when a module needs independent scale, tech stack, or team ownership.

    Informative example

    Spring Boot modular monolith — separate packages with clear boundaries before any network split:

    java
    @SpringBootApplication
    public class ShopApplication {
    public static void main(String[] args) {
    SpringApplication.run(ShopApplication.class, args);
    }
    }
    // module: catalog — no imports from checkout internals
    @RestController
    @RequestMapping("/api/v1/products")
    class ProductController {
    private final ProductService products;
    ProductController(ProductService products) { this.products = products; }
    @GetMapping("/{id}")
    ProductDto get(@PathVariable String id) {
    return products.findById(id);
    }
    }
    // module: checkout — calls catalog via interface, not concrete DB tables
    @Service
    class CheckoutService {
    private final ProductCatalog catalog;
    private final OrderRepository orders;
    CheckoutService(ProductCatalog catalog, OrderRepository orders) {
    this.catalog = catalog;
    this.orders = orders;
    }
    OrderDto placeOrder(PlaceOrderCommand cmd) {
    var items = catalog.verifyAvailability(cmd.lines());
    return orders.save(Order.from(cmd, items));
    }
    }

    Interview tip: propose modular monolith first for MVPs. Show you know microservices without premature splitting.

    Real-world use

    Real-world use cases

    • Early-stage fintech MVP with one team and compliance scope still stabilizing.
    • Internal admin tools with moderate traffic and tight iteration cycles.
    • Regional e-commerce before international expansion forces multi-region split.
    • Healthcare clinic scheduling where integration complexity favors one deployable unit.

    Best practices

    • Enforce module boundaries with package-private types and interface contracts.
    • Keep web tier stateless; externalize sessions and uploads.
    • Invest in automated tests before splitting — they become service contract tests later.
    • Monitor DB connection saturation and slow queries early.
    • Use feature flags for risky modules without microservice overhead.
    • Document domain boundaries even inside monolith — eases future extraction.

    Common mistakes

    • Creating a 'distributed monolith' prematurely with shared DB anti-pattern across services.
    • Ignoring modular structure — everything imports everything (big ball of mud).
    • Scaling only app servers while DB remains single tiny instance.
    • Assuming monolith cannot handle millions of users — many do with caching and replicas.
    • Splitting on technical layers (JSON service, SQL service) instead of business domains.

    Advanced interview questions

    Q1BeginnerWhat is a monolithic architecture?
    All application functionality deployed as a single unit sharing process and usually one primary database.
    Q2BeginnerAdvantages of monolith?
    Simple deploy, debug, and transaction boundaries; lower operational overhead for small teams.
    Q3IntermediateWhen migrate away from monolith?
    Independent scaling, team autonomy, diverging SLAs, or deployment coupling blocking velocity.
    Q4IntermediateWhat is a modular monolith?
    Single deployable with enforced internal module boundaries preparing for eventual service extraction.
    Q5AdvancedDesign monolith for 1M DAU e-commerce.
    Stateless Spring tier behind LB, Redis sessions/cache, PostgreSQL primary + replicas, async email via internal queue module, CDN for static — state sharding triggers.

    Summary

    Monoliths are valid HLD choices for MVPs and cohesive domains. Modular monoliths delay microservice complexity without sacrificing clarity. Scale horizontally at app tier; solve DB and cache bottlenecks early. Extract services on business drivers, not hype. Interviewers reward knowing when NOT to microservice. Next lesson contrasts microservices trade-offs explicitly.

    Ready to mark this lesson complete?Track your journey across the entire course.