CLOSE
Updated on 27 Nov, 202530 mins read 42 views

Monolithic Architecture (Monolith)

A monolith is a single, unified application where all modules (auth, product, payments, notifications..) are packaged and deployed together.

HLD Structure

┌──────────────────────────────────────────┐
│               Monolithic App             │
│ ┌────────────┬─────────────┬───────────┐ │
│ │  Auth      │  Orders     │ Payments  │ │
│ ├────────────┼─────────────┼───────────┤ │
│ │ Inventory  │Notifications│ Analytics │ │
│ └────────────┴─────────────┴───────────┘ │
└──────────────────────────────────────────┘
               ▲
               │ Single DB
               ▼
          ┌─────────┐
          │Database │
          └─────────┘

monolith_architecture
 

Characteristics

Pros:

  1. Simple HLD and Development
    Single codebase, easier onboarding
  2. Simple Deployment
    One build -> one deployment
  3. Shared Memory & DB
    No network calls; faster function calls.
  4. Easy Local Dev
    Everything runs in one place

Cons:

  1. Scaling Limitation
    Must scale entire application, even if only one module needs capacity.
  2. Tight Coupling
    A change in one module affects the whole system.
  3. Slower deployments with size
    As the app grows, deployment becomes heavy.
  4. Reduced Fault Isolation
    One bug can crush everything.
  5. Hard to implement polyglot tech stack
    Must use same language/framework.

When to Use Monolith

  • Early-stage startup / MVP.
  • Small engineering team.
  • When domain is not yet clearly defined.
  • When performance is more important than modularity.
  • When features are highly interdependent.

Microservices Architecture

A microservices architecture splits the system into independent, loosely-coupled services, each owning a specific business capability.

HLD Structure

                 ┌───────────────┐
                 │ API Gateway   │
                 └───────┬───────┘
                         │ Route
─────────────────────────┼──────────────────────────────
                         ▼
      ┌──────────┐   ┌───────────┐   ┌───────────────┐
      │ Auth Svc │   │ Order Svc │   │ Payment Svc   │
      └─────┬────┘   └─────┬─────┘   └──────┬────────┘
            │              │                │
      ┌─────▼───┐    ┌─────▼───┐      ┌─────▼──────┐
      │ Auth DB │    │ Order DB│      │ Payment DB │
      └─────────┘    └─────────┘      └────────────┘

microservices_architecture

Other HLD components:

  • Service Discovery (Eureka/Consul)
  • API Gateway (Kong, Nginx, Zuul)
  • Load Balancers
  • Message Broker (Kafka, RabbitMQ)
  • Centralized Logging (ELK, Loki)
  • Tracing (Jaeger, Zipkin)

Characteristics

Pros:

  1. Independent deployability
    Deploy only the service you modify.
  2. Independent scaling
    Scale only high-load services (ex: search or checkout)
  3. Fault Isolation
    Failure in one service does not kill the entire system.
  4. Polyglot flexibility
    Different services can use different languages/DB.
  5. Clear Domain Separation
    Each service is complete bounded context.

Cons:

  1. Complex HLD
    Requires DevOps maturity (gateway, CI/CD, logs, tracing).
  2. Distributed System Challenges
    Network issues, retries, timeouts, async communication.
  3. Eventual Consistency
    Synchronous consistency becomes harder
  4. Operational Overhead
    Many repositories, many deployments.
  5. Cross-cutting Concerns
    Need centralized logging, monitoring, metrics.

When to Use Microservices

  • Application is large and rapidly growing.
  • Teams are big and work on independent modules
  • Need independent deployments.
  • Different modules need different scaling modules.
  • Need high availability
  • Domain boundaries are clear

Different Phases of a Microservice

Microservices are not just “small services” – they requires a full lifecycle of phases to design, build, operate, and evolve.

Below are the essential phases:

1 Decomposition Phase

This is the first and most critical phase.

This tells us if you have a monolith application, then how will you break it down to the microservice architecture.

decomposition_phase

The decomposition phase decides how the system is split into services:

There are two major categories:

  1. Decomposition by business logic
  2. Decomposition by sub domain

1 Decomposition by business logic

Each service is designed around a business capability – a function the business performs.

Examples:

  • Payment Service
  • Order Service
  • Inventory Service
  • User Service

decomposition_by_business_logic
 Disadvantages:

  • Developer should be aware of entire business.

2 Decomposition by Subdomain

Split system based on bounded contexts in Domain Driven Design.

decomposition_by_subdomain
 3 Decompose by Strangler Pattern (Incremental Migration)

When migrating monolith -> microservices, you extract one part at a time.

Steps:

  1. Identify a module
  2. Built it as a microservice
  3. Route traffic to it through an API gateway
  4. Shut down old monolith module

2 Database Phase

Once we have decomposed the system into services, the next step is to decide how each service handles its data.

This phase focuses on:

  • Data ownership
  • Database per service
  • Schema design
  • Consistency model
  • Data communication between services
  • Transaction patterns
  • Query patterns

Each microservice can have:

Shared DB:
shared_db

Advantages:

  • Simple to carry operations
  • Join (SQL)
  • Transaction manage (ACID)

Disadvantages:

  • Can not be scaled properly.
  • Has the limitation of either being SQL or NoSQL.

Unique DB

Every service has their own database.

unique_db
 Disadvantages:

  • JOIN
  • Transaction Management (How to know commit, rollback across different services)

3 Communication

How two microservices communicate with each other.

4 Deployment

How your microservices will be deployed.

5 Observability

How will we monitor the application

SAGA Pattern (Solves Transaction Management)

Saga Pattern is a distributed transaction management pattern used in microservices to maintain eventual consistency across multiple services without using distributed locks or 2-phase commit.

Why Saga Is Needed

In microservices:

  • Each service has its own DB
  • Distributed transactions are slow and risky
  • Network failures are common

Saga solves this by splitting a transaction into steps, with compensating actions to undo a step if later steps fail.

Definition:

A Saga is a sequence of local transactions where each local transaction:

  • updates data within  its own service
  • publishes an even or sends a command to trigger the next step

If a step fails:

  • A compensating transaction is executed to undo the previous steps.

Two Types of SAGA

Saga has two major architecture patterns:

1 Choreography Saga (Event-Driven)

Microservices communicate via events. No central controller.

Flow:

Order Service  →  Inventory Service  →  Payment Service  →  Shipping Service

Each Service:

  • listens for an event
  • performs its local transaction
  • emits the next event

Example Flow (E-commerce):

  1. Order Service
    1. Local transaction: create order
    2. Emit event: OrderCreated
  2. Inventory Service
    1. On OrderCreated: reserve stock
    2. Emit: InventoryReserved
  3. Payment Service
    1. On InventoryReserved: ship item
    2. Emit: OrderShipped

Failure Example:

If payment fails:

  • Emit PaymentFailed
  • Inventory Service listens -> rollback reservation
  • Order Service listens -> cancel order

2 Orchestration Saga (Centralized Coordinator)

A Saga Orchestrator or “workflow engine” controls the flow.

Flow:

Saga Orchestrator → Auth Service
                   → Payment Service
                   → Inventory Service
                   → Shipping Service

Example (E-commerce):

  1. Orchestrator sends: CreateOrder
  2. Order Service returns: OrderCreated
  3. Orchestrator sends: ReserveInventory
  4. Inventory -> InventoryReserved
  5. Orchestrator -> ProcessPayment
  6. Payment -> PaymentCompleted
  7. Orchestrator -> ShipOrder

If payment fails:

  • Orchestrator sends: ReleaseInventory
  • Orchestrator sends: CancelOrder

CQRS (Command Query Request Separation) (Solves the JOIN problem)

CQRS is an architectural pattern that separates write operations (commands) from read operations (queries) instead of using the same data model for both.

Command = Write operations (update, delete, insert)

Query = Read operations (select)

Query Side (Read Model)

Handles:

  • Read-only operations
  • UI queries
  •  
Buy Me A Coffee

Leave a comment

Your email address will not be published. Required fields are marked *

Your experience on this site will be improved by allowing cookies Cookie Policy