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 │
└─────────┘
Characteristics
Pros:
- Simple HLD and Development
Single codebase, easier onboarding - Simple Deployment
One build -> one deployment - Shared Memory & DB
No network calls; faster function calls. - Easy Local Dev
Everything runs in one place
Cons:
- Scaling Limitation
Must scale entire application, even if only one module needs capacity. - Tight Coupling
A change in one module affects the whole system. - Slower deployments with size
As the app grows, deployment becomes heavy. - Reduced Fault Isolation
One bug can crush everything. - 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 │
└─────────┘ └─────────┘ └────────────┘
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:
- Independent deployability
Deploy only the service you modify. - Independent scaling
Scale only high-load services (ex: search or checkout) - Fault Isolation
Failure in one service does not kill the entire system. - Polyglot flexibility
Different services can use different languages/DB. - Clear Domain Separation
Each service is complete bounded context.
Cons:
- Complex HLD
Requires DevOps maturity (gateway, CI/CD, logs, tracing). - Distributed System Challenges
Network issues, retries, timeouts, async communication. - Eventual Consistency
Synchronous consistency becomes harder - Operational Overhead
Many repositories, many deployments. - 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.

The decomposition phase decides how the system is split into services:
There are two major categories:
- Decomposition by business logic
- 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

Disadvantages:
- Developer should be aware of entire business.
2 Decomposition by Subdomain
Split system based on bounded contexts in Domain Driven Design.

3 Decompose by Strangler Pattern (Incremental Migration)
When migrating monolith -> microservices, you extract one part at a time.
Steps:
- Identify a module
- Built it as a microservice
- Route traffic to it through an API gateway
- 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:

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.

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):
- Order Service
- Local transaction: create order
- Emit event:
OrderCreated
- Inventory Service
- On
OrderCreated: reserve stock - Emit:
InventoryReserved
- On
- Payment Service
- On
InventoryReserved: ship item - Emit:
OrderShipped
- On
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):
- Orchestrator sends:
CreateOrder - Order Service returns:
OrderCreated - Orchestrator sends:
ReserveInventory - Inventory ->
InventoryReserved - Orchestrator ->
ProcessPayment - Payment ->
PaymentCompleted - 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
Leave a comment
Your email address will not be published. Required fields are marked *


