0
0
Microservicessystem_design~7 mins

Single responsibility per service in Microservices - System Design Guide

Choose your learning style9 modes available
Problem Statement
When a microservice handles multiple unrelated responsibilities, it becomes hard to maintain and scale. Changes in one function can unintentionally affect others, causing bugs and deployment delays. This tight coupling also slows down teams and increases the risk of system-wide failures.
Solution
Each microservice is designed to focus on one specific business capability or responsibility. This separation allows teams to develop, deploy, and scale services independently. It reduces complexity, improves fault isolation, and makes the system easier to understand and evolve.
Architecture
┌───────────────┐     ┌───────────────┐     ┌───────────────┐
│ User Service  │ →→→ │ Order Service │ →→→ │ Payment Service│
└───────────────┘     └───────────────┘     └───────────────┘

Each box is a microservice with a single responsibility. Arrows show communication flow.

This diagram shows three microservices, each handling a distinct responsibility: user management, order processing, and payment handling. They communicate through defined interfaces.

Trade-offs
✓ Pros
Improves maintainability by isolating changes to one service.
Enables independent deployment and scaling of services.
Enhances fault tolerance by limiting failure impact to one service.
Simplifies understanding of each service's purpose.
✗ Cons
Increases the number of services to manage, adding operational overhead.
Requires well-defined APIs and communication patterns between services.
Can introduce latency due to inter-service calls.
When the system has multiple distinct business capabilities and teams can own separate services. Typically beneficial at scale beyond 10,000 daily active users or when deployment agility is critical.
For very small or simple applications with limited functionality where the overhead of multiple services outweighs benefits, such as prototypes or MVPs with fewer than 1,000 users.
Real World Examples
Amazon
Amazon decomposed its monolithic e-commerce platform into microservices each responsible for a single domain like product catalog, order management, and payment processing to enable independent scaling and faster deployments.
Netflix
Netflix uses single responsibility microservices to isolate streaming, user profiles, and recommendations, allowing teams to innovate and deploy features independently without affecting the entire system.
Uber
Uber splits services by responsibility such as ride matching, payments, and notifications, enabling rapid development and fault isolation in their complex, high-scale platform.
Code Example
The before code shows one class handling user creation, order placement, and payment processing, mixing responsibilities. The after code splits these into three classes, each focused on a single responsibility, making the code easier to maintain and scale.
Microservices
### Before: Single service handling multiple responsibilities
class ECommerceService:
    def create_user(self, user_data):
        # code to create user
        pass

    def place_order(self, order_data):
        # code to place order
        pass

    def process_payment(self, payment_data):
        # code to process payment
        pass


### After: Separate services each with single responsibility

# User Service
class UserService:
    def create_user(self, user_data):
        # code to create user
        pass

# Order Service
class OrderService:
    def place_order(self, order_data):
        # code to place order
        pass

# Payment Service
class PaymentService:
    def process_payment(self, payment_data):
        # code to process payment
        pass
OutputSuccess
Alternatives
Monolithic architecture
All responsibilities are combined into a single deployable unit without service boundaries.
Use when: When the application is small, simple, or early in development and team size is small.
Modular monolith
Keeps a single deployable unit but enforces clear module boundaries internally without separate services.
Use when: When you want clear separation of concerns but want to avoid distributed system complexity.
Summary
Single responsibility per service means each microservice handles one business capability.
This separation improves maintainability, scalability, and fault isolation.
It is best used in systems with multiple distinct domains and larger teams.