SLIDE 23: Section Intro
Section 3: Service Decomposition and Boundaries
If you only master one skill from this entire course, it should be service decomposition. This is the single most important skill in microservices architecture, both in production and in interviews.
Getting boundaries right means services that are independent, cohesive, and easy to evolve. Getting boundaries wrong means a distributed monolith that is harder to change than the original monolith ever was. Section 2 taught you when to use microservices. This section teaches you how to find the right boundaries when you do.
What We Will Cover:
- Business capability decomposition and why it is the starting point
- Domain-driven design fundamentals: bounded contexts and aggregates
- Cohesion and coupling as the guiding principles for every boundary decision
- Team ownership and service granularity
- Three decomposition approaches: by capability, by workflow, by read/write pattern
- Service boundary anti-patterns and how to avoid them
- Boundary discovery techniques including event storming
- Real-world decomposition examples for e-commerce, ride-sharing, streaming, and banking
Where This Appears in Real Systems:
Every microservices architecture that works well has boundaries drawn around business capabilities. Every microservices architecture that struggles has boundaries drawn around database tables, technical layers, or arbitrary code splits. The difference between these two outcomes is the skill taught in this section.
SLIDE 24: Business Capability Decomposition
The most reliable way to find service boundaries is to decompose by business capability. A business capability is something the organization does to generate value, independent of how it is implemented in code.
Examples of business capabilities in an e-commerce platform like Amazon:
- Catalog Management - Maintaining product listings, descriptions, images, categories
- Inventory Management - Tracking stock levels, reserving inventory, restocking
- Order Management - Creating, tracking, and completing customer orders
- Payment Processing - Authorizing charges, processing refunds, managing payment methods
- Shipping and Fulfillment - Calculating shipping options, generating labels, tracking deliveries
- Customer Support - Handling returns, resolving disputes, managing tickets
Each of these capabilities can be owned by a separate team, has its own data, and changes for its own business reasons. When the marketing team wants to add video to product listings, only the Catalog Service changes. When the finance team wants to support a new payment provider, only the Payment Service changes.
The key test: If you change one capability, does it force a change in another capability? If yes, they might belong together. If no, they are good candidates for separate services.
Why this beats technical decomposition: A “Database Service” or “Validation Service” does not map to a business capability. Every feature touches the database. Every feature needs validation. Technical services become bottlenecks that every team depends on, which is the opposite of independence.
Interview Relevance: When an interviewer asks “how would you split this system into services?”, starting with business capabilities is the expected approach. Starting with technical layers is a red flag.
SLIDE 25: Domain-Driven Design Fundamentals
Domain-driven design (DDD) provides the vocabulary and methodology for finding service boundaries. You do not need to adopt all of DDD to benefit from it. Three concepts are directly relevant to microservices decomposition.
Concept 1: Ubiquitous Language
Every domain has its own vocabulary. The words used by the business should be the same words used in the code. If the business calls it an “order,” the code should have an Order class, not a “TransactionRequest.” If the business distinguishes between “shipment” and “delivery,” the code should too.
Why this matters for microservices: when two teams use different words for the same concept, or the same word for different concepts, that is a signal that they operate in different domains and may need different services.
Concept 2: Bounded Context
A bounded context is a boundary within which a particular domain model is defined and consistent. The same word can mean different things in different bounded contexts. We will explore this in depth on the next slide.
Concept 3: Aggregates
An aggregate is a cluster of related entities that are treated as a single unit for data changes. The aggregate defines the consistency boundary. We will explore this in Slide 27.
The connection to microservices: A bounded context often maps to a microservice. An aggregate often maps to the primary entity that a microservice manages. These are not rigid rules, but they are strong starting heuristics.
Interview Relevance: Mentioning bounded contexts and aggregates in an interview signals that you approach decomposition methodically, not by gut feeling.
SLIDE 26: Bounded Contexts
A bounded context is the most important concept in DDD for microservices. It defines a boundary within which a term has one specific, unambiguous meaning.
The core insight: The same word means different things in different parts of the business. “Product” in the catalog domain means a listing with a title, description, images, and categories. “Product” in the inventory domain means a SKU with a stock count, warehouse location, and reorder threshold. “Product” in the shipping domain means a physical item with weight, dimensions, and fragility classification.
If you try to build one “Product” model that satisfies all three domains, you get a bloated, tightly coupled entity that every team fights over. If you let each domain define “Product” in its own way, each service stays focused and independent.
The rule: Each bounded context has its own model, its own database representation, and its own definition of shared terms. When data needs to cross context boundaries, it is translated at the boundary through APIs or events, not shared through a common database model.
Why bounded contexts map to microservices: Each bounded context represents a self-contained domain model with clear boundaries. That is exactly what a microservice should be: a self-contained service with clear boundaries and its own data.
Interview Relevance: If you can explain bounded contexts with a concrete example of the same word meaning different things in different services, you demonstrate a level of design thinking most candidates do not show.
SLIDE 26B: Bounded Contexts, Worked Example
Scenario: An e-commerce platform like Amazon has four teams: Catalog, Orders, Shipping, and Payments. All four teams work with the concept of a “Customer.” But “Customer” means something different to each team.
If you build one Customer Service that holds all of these attributes, every team depends on it. A change to add “delivery instructions” for the Shipping team risks breaking the Payments team’s fraud scoring logic. Deployments require coordination across all four teams.
The better design: Each bounded context owns its own representation of the customer. The Catalog context stores browsing preferences. The Orders context stores order history. The Shipping context stores delivery details. The Payments context stores financial information. When the Orders context needs the customer’s delivery address, it calls the Shipping context’s API or receives it as part of an event.
The trade-off: Yes, this means some customer data is duplicated across services. The customer’s name might exist in all four databases. This duplication is the price of independence, and it is almost always worth paying. Section 5 (Data Ownership) will explore this trade-off in depth.
Interview Relevance: Walking through this specific example in an interview, showing the same entity meaning different things in different contexts, is one of the strongest demonstrations of microservices design thinking.
SLIDE 27: Aggregates and Consistency Boundaries
An aggregate is a cluster of related domain objects that must be changed together to maintain consistency. The aggregate is the unit of transaction within a service.
Why aggregates matter for microservices: The aggregate defines where your consistency boundary lives. Everything inside an aggregate is guaranteed to be consistent (ACID transaction within one database). Everything outside the aggregate is eventually consistent (across services, handled by events or sagas).
Example: The Order Aggregate
An Order is not just a single row in a database. It is a cluster of related objects:
- The Order itself (order ID, status, creation time)
- Order Line Items (product, quantity, price at time of purchase)
- Order Totals (subtotal, tax, shipping cost, total)
These objects must be consistent with each other at all times. You cannot have an Order Total that does not match the sum of the Line Items. You cannot have a Line Item that references a non-existent Order. They change together as a single transaction.
The aggregate rule: Changes to objects inside an aggregate happen in a single transaction within one service. Changes that span multiple aggregates (or multiple services) happen through events, sagas, or eventual consistency. This rule prevents distributed transactions.
Interview Relevance: Understanding aggregates helps you answer the question “where do you draw the transaction boundary?” in an interview. The answer is: at the aggregate boundary.
SLIDE 27B: Aggregates, Worked Example
Scenario: A customer adds 3 items to their cart and places an order on a platform like Amazon.
The Order Aggregate:
class Order:
def __init__(self, order_id, customer_id):
self.order_id = order_id
self.customer_id = customer_id
self.line_items = []
self.status = "CREATED"
def add_line_item(self, product_id, product_name, quantity, unit_price):
line_item = LineItem(product_id, product_name, quantity, unit_price)
self.line_items.append(line_item)
def calculate_total(self):
return sum(item.quantity * item.unit_price for item in self.line_items)
def confirm(self):
if not self.line_items:
raise EmptyOrderError(self.order_id)
self.status = "CONFIRMED"
The Order object controls all modifications to its line items and total. No external service reaches into the Order and modifies a line item directly. All changes go through the Order’s methods, which enforce business rules (like “you cannot confirm an empty order”).
What is inside vs outside the aggregate:
- Inside (one transaction): Creating the order, adding line items, calculating the total, confirming the order. All of this happens in a single database transaction within the Order Service.
- Outside (eventual consistency): Reserving inventory, authorizing payment, scheduling shipment. These involve other services and happen through events. If payment authorization fails, a compensating action cancels the order. This is a saga, which you will learn in Section 6.
Interview Tip: When designing a service in an interview, explicitly state what is inside your aggregate (consistent) and what is outside (eventually consistent). This shows the interviewer you understand where transactions end and distributed coordination begins.
Interview Relevance: The ability to define aggregate boundaries is what separates candidates who can design services from candidates who can only name them.
SLIDE 27C: Interview Practice
Question:
You are designing a microservices architecture for an online food ordering platform like DoorDash. The interviewer asks: “How would you determine the service boundaries?”
Take 60 seconds to think about your approach before reading below.
Weak Answer:
“I would create a Restaurant Service, a Menu Service, a Food Item Service, an Order Service, a Delivery Service, a Driver Service, a Payment Service, a Rating Service, and a Notification Service.”
Why this is weak: The candidate listed 9 services without explaining the reasoning behind any of them. “Menu Service” and “Food Item Service” are almost certainly too granular. They did not mention business capabilities, bounded contexts, team ownership, or any methodology. This looks like guessing, not designing.
Strong Answer:
“I would start by identifying the core business capabilities. Food ordering has at least five distinct capabilities: restaurant management (onboarding restaurants, managing menus, managing hours), order management (placing orders, tracking status, handling cancellations), dispatch (matching orders to drivers, optimizing routes), payment processing (charging customers, paying restaurants, paying drivers), and customer experience (ratings, reviews, support tickets).
Each of these capabilities has different data, changes for different business reasons, and maps to a different team. The restaurant team manages menus and hours. The order team manages the order lifecycle. The dispatch team handles real-time matching with very different scaling and latency requirements than the order team.
I would validate these boundaries by checking: does each service own its own data? Can each service deploy independently? Does a change in one service rarely force a change in another? If yes, these are good boundaries. If two capabilities frequently change together, I would merge them into one service.”
What makes this strong: The candidate explains a methodology (business capability decomposition), identifies specific capabilities with reasoning, considers team ownership, and applies a validation test to the boundaries.
SLIDE 28: Cohesion
Cohesion measures how strongly related the responsibilities within a service are. High cohesion means everything inside the service serves a single, focused purpose. Low cohesion means the service is a grab bag of unrelated functionality.
High cohesion example: A Payment Service that handles payment authorization, refund processing, payment method management, and payment history. All of these relate to the single business capability of processing payments. When the business adds a new payment provider, all changes happen within this one service.
Low cohesion example: A “Utility Service” that handles email sending, PDF generation, currency conversion, and address validation. These have nothing to do with each other. They change for completely different reasons. Email sending changes when the notification requirements change. PDF generation changes when report formats change. There is no business capability that unifies them.
The cohesion test: List every responsibility of a service. Can you describe what the service does in one sentence without using the word “and”? If you can (“The Payment Service processes payments”), cohesion is high. If you cannot (“The Utility Service sends emails and generates PDFs and converts currencies and validates addresses”), cohesion is low and the service should be split.
Why cohesion matters for microservices: A highly cohesive service changes for one reason, owned by one team, deployed independently. A low-cohesion service changes for many reasons, involves multiple teams, and becomes a deployment bottleneck, which is exactly what microservices are supposed to prevent.
Interview Relevance: When justifying your service boundaries in an interview, saying “I grouped these together because they have high cohesion, they all relate to the payment domain and change together” is a strong, principled answer.
SLIDE 29: Coupling
Coupling measures how much one service depends on another. Low coupling means services can change independently. High coupling means a change in one service forces changes in others.
Types of coupling, from worst to most acceptable:
Database coupling (worst): Two services read from and write to the same database table. Any schema change breaks both services. This is the shared database anti-pattern from Section 2 and is never acceptable between true microservices.
Implementation coupling: Service A depends on the internal implementation of Service B. For example, Service A knows that Service B stores user data in a specific JSON format and parses that format directly. When Service B changes its storage format, Service A breaks.
Temporal coupling: Service A can only work when Service B is available at the same moment. Synchronous request-response between services creates temporal coupling. If Service B is down, Service A fails. Asynchronous messaging reduces temporal coupling because Service A can publish a message and continue without waiting.
Contract coupling (most acceptable): Service A depends on the public API contract of Service B. This is the minimum necessary coupling. As long as Service B maintains backward compatibility in its API, Service A does not break. This is the coupling you should aim for.
The goal is not zero coupling. Services need to communicate. The goal is to push coupling from database and implementation coupling (tight, hidden, fragile) toward contract coupling (explicit, versioned, manageable).
Interview Relevance: Being able to name different types of coupling and explain which types are acceptable versus harmful shows depth of understanding that most candidates lack.
SLIDE 30: Cohesion and Coupling as a Decision Tool
Every service boundary decision comes down to one question: does this split increase cohesion and reduce coupling, or does it do the opposite?
When to keep things together (merge):
- Two components always change at the same time for the same business reason
- Splitting them would require constant synchronous communication between the two new services
- They share the same data and splitting would require complex data synchronization
- They are owned by the same team and there is no organizational reason to separate them
When to split things apart:
- Two components change for completely different business reasons at different frequencies
- They have different scaling requirements (one is read-heavy, the other is write-heavy)
- They are owned by different teams with different release cadences
- A failure in one should not affect the other
- They have different data storage needs (one needs a relational database, the other needs a document store)
Common Mistake: Splitting two components because they “feel” like separate things, even though they always change together. If the Pricing module and the Catalog module are always modified in the same sprint by the same team, they have high cohesion with each other and should probably be one service, even if “pricing” and “catalog” sound like different domains.
Interview Tip: When an interviewer challenges your boundary choice (“why did you put pricing inside the catalog service?”), explain it in terms of cohesion and coupling: “Pricing and catalog always change together when we update product listings, and splitting them would create synchronous coupling for every product read. Keeping them together gives us higher cohesion with no added coupling.”
Interview Relevance: The cohesion/coupling reasoning framework is the most versatile tool for defending service boundary decisions in interviews.
SLIDE 31: Ownership Boundaries
In microservices, every service must have one owning team. One team, one service. This is not just an organizational preference. It is an architectural requirement.
Why ownership matters:
If two teams co-own a service, every change requires cross-team coordination. Deployment schedules conflict. On-call responsibilities are unclear. Code review standards diverge. The service slowly becomes inconsistent because neither team feels fully responsible.
The ownership rules:
- One team owns one service - That team controls the code, the database, the deployment pipeline, the monitoring, and the on-call rotation
- One team can own multiple services - A team of 6 engineers might own 2-3 closely related services
- No service has zero owners - Every service must have a team in the service catalog. Orphaned services become unmaintained liabilities.
- The owning team owns the API contract - They decide what the public interface looks like, how it is versioned, and when breaking changes happen
Real-world example: In a platform like Uber, the Dispatch team owns the Dispatch Service. They decide how matching works, how the API is structured, and when to deploy changes. The Rider team and Driver team consume the Dispatch API but do not modify the Dispatch Service’s code. If the Rider team needs a new dispatch feature, they file a request with the Dispatch team.
The connection to Conway’s Law from Section 1: This is Conway’s Law in practice. The team structure mirrors the service structure. When you draw service boundaries, you are also drawing team boundaries. If the boundaries do not make sense organizationally (one team would own a service but has no expertise in that domain), the boundaries are probably wrong.
Interview Relevance: Mentioning team ownership when explaining your service boundaries shows the interviewer you think about microservices as an organizational architecture, not just a technical one.
SLIDE 32: Service Granularity
One of the hardest decisions in microservices is how big or small each service should be. Both extremes cause problems.
Too large (the “mini-monolith”):
A single Order Service handles order creation, payment processing, inventory reservation, shipping calculation, and email notifications. It has 15 database tables and requires 8 engineers to maintain. It deploys twice a week because changes are risky and require extensive testing. This is a monolith with a microservice label. It has all the problems of a monolith (deployment coupling, team bottlenecks) plus the costs of being a distributed service (network overhead, operational complexity).
Too small (the “nano-service”):
Separate services for Order Creation, Order Status, Order History, and Order Cancellation. Each has one database table and 200 lines of code. A single “view order details” request requires calling all four services, adding network latency and failure points. Each service is too simple to justify its own deployment pipeline, monitoring, and on-call rotation. The team spends more time managing infrastructure than building features.
The right granularity:
A service should be large enough to represent a complete business capability and small enough to be owned by a single team (4-8 engineers). It should have enough internal complexity to justify its operational overhead. A good heuristic: if a service has fewer than 3 database tables, it is probably too small. If it has more than 15, it is probably too large.
Interview Relevance: If an interviewer says “that service seems too big” or “that seems like a lot of services,” being able to articulate the granularity trade-off shows you have thought about this beyond the textbook.
SLIDE 32B: Interview Practice
Question:
You are designing a social media platform like Instagram. A candidate in a mock interview proposes these services: User Profile Service, User Settings Service, User Avatar Service, User Follow Service, User Block Service, User Notification Preferences Service. The interviewer asks you to evaluate this design. What would you say?
Take 60 seconds to evaluate before reading below.
Weak Answer:
“This looks good. Each service is small and focused, which is what microservices should be.”
Why this is weak: The candidate accepted the design at face value without analyzing cohesion, coupling, or granularity. Six services for user-related functionality is almost certainly too granular.
Strong Answer:
“This design is too granular. All six of these services relate to a single business capability: user profile management. They are all owned by the same team, change for similar business reasons, and a single user action like ‘update my profile’ would need to call multiple services.
I would consolidate them into two services. First, a User Service that owns profiles, settings, avatar, and notification preferences. These all change when the user updates their account and they share the same consistency requirements. Second, a Social Graph Service that owns follows and blocks. This is a genuinely different domain with different data structures (a graph rather than a row), different scaling characteristics (fan-out queries for feeds), and potentially a different database technology (a graph database or wide-column store rather than relational).
The User Service has high cohesion because everything inside it relates to a single user’s account. The Social Graph Service has high cohesion because everything inside it relates to relationships between users. Coupling between them is minimal, limited to the User Service providing basic profile data when the Social Graph Service needs to display follower names.”
What makes this strong: The candidate identifies the granularity problem, consolidates with clear reasoning (cohesion, shared ownership, shared data), and draws a principled boundary where a genuine domain difference exists (user account vs social graph).
SLIDE 33: Decomposition by Business Capability vs Technical Layer
There are two fundamentally different approaches to splitting a system into services. One works. The other creates a distributed monolith.
Technical layer decomposition (wrong):

Every feature requires changes to all three services. Adding a “discount code” feature means updating the API Service (new endpoint), the Business Logic Service (discount calculation), and the Data Access Service (new query). These services cannot be developed, deployed, or scaled independently. You have rebuilt the monolith’s layers as separate services with network calls in between.
Business capability decomposition (correct):

Each service contains its own API layer, business logic, and data access for one business capability. Adding a “discount code” feature only changes the Order Service. The Catalog and Payment services do not need to change or redeploy.
The definitive test: When a product manager requests a new feature, how many services need to change? If the answer is consistently “only one,” you have decomposed by business capability. If the answer is consistently “three or more,” you have decomposed by technical layer.
Interview Relevance: If an interviewer sees you drawing a “frontend service, backend service, database service” architecture, they will immediately recognize it as a technical layer split and push back.
SLIDE 34: Decomposition by Workflow
Some service boundaries become clear only when you trace the workflow that a user action triggers from start to finish.
Example: E-commerce checkout workflow
When a customer clicks “Place Order,” this workflow executes:

Each step in this workflow is a distinct responsibility with different data, different failure modes, and different teams. Order creation is a write-heavy transactional step. Inventory reservation needs real-time stock data. Payment authorization involves external payment providers with their own latency and failure characteristics. Shipment creation integrates with logistics partners. Notification sending is fire-and-forget and should never block the order.
How to use workflows to find boundaries:
- Map out the major user workflows in your system (checkout, signup, content upload, search)
- For each workflow, identify the distinct steps
- Group steps that share data and change for the same business reason
- Steps that have different scaling needs, different failure tolerance, or different team ownership become separate services
When two workflow steps should stay together: If step A and step B always happen in the same transaction and a failure in either means both must roll back, they probably belong in the same service. Splitting them would require a distributed transaction, which adds complexity for no benefit.
Interview Relevance: Tracing a workflow on the whiteboard and then deriving service boundaries from it is one of the strongest interview techniques for demonstrating decomposition skill.
SLIDE 35: Decomposition by Read and Write Patterns
Some service boundaries emerge from the observation that reads and writes have fundamentally different characteristics in many domains.
The pattern: In many systems, the write path and the read path differ in volume, latency requirements, data shape, and scaling needs. When this difference is large enough, separating them into different services (or at least different models) is justified.
Example: Product catalog in an e-commerce platform
- Writes are low volume. Product managers update listings a few hundred times per day. Each update involves complex validation, image processing, and category assignment. The write model is normalized and relational.
- Reads are extremely high volume. Millions of customers browse the catalog every hour. They need fast, denormalized responses with product name, price, main image, and average rating in a single query. The read model is denormalized and optimized for fast retrieval.
Trying to serve both patterns from the same service and the same database means compromising on both. The write model becomes denormalized to speed up reads, making writes more complex. The read model becomes normalized to simplify writes, making reads slower.
The CQRS approach (preview):
Command Query Responsibility Segregation separates the write model (commands) from the read model (queries). The write service processes updates and publishes events. The read service consumes those events and maintains an optimized read model. Section 5 (Data Ownership) will cover CQRS in full detail.
When this decomposition applies: When read volume is 10x-1000x higher than write volume, when read and write latency requirements differ significantly, or when the ideal data shape for reading differs from the ideal shape for writing.
Interview Relevance: Mentioning read/write separation as a decomposition strategy shows the interviewer you think about data access patterns, not just business domains.
SLIDE 36: Why One Service Per Database Table Fails
This is one of the most common mistakes in microservices design and it comes up frequently in interviews. It deserves its own slide because the reasoning behind why it fails illustrates the core principles of good decomposition.
The mistake: A team looks at their database schema, sees 12 tables, and creates 12 services. The User Service owns the users table. The Address Service owns the addresses table. The Phone Number Service owns the phone_numbers table.
Why it fails:
Problem 1: No cohesion. An Address Service with one table has no meaningful business logic. It is a CRUD wrapper around a database table. It adds network overhead, a deployment pipeline, and monitoring for something that could be a function call inside the User Service.
Problem 2: Chatty communication. Displaying a user profile requires calling the User Service, then the Address Service, then the Phone Number Service, then the Email Service. Four network calls for what was a single database join. Latency increases. Failure probability increases. Debugging becomes harder.
Problem 3: Wrong consistency boundary. A user updates their profile with a new name and new address. In a monolith, this is one transaction. With separate services, you now need to coordinate a distributed update across User Service and Address Service. If one succeeds and the other fails, the user has an inconsistent profile.
The fix: Group related tables into services based on business capability. Users, addresses, phone numbers, and emails all belong to the User Profile capability. They form one aggregate, owned by one service, changed in one transaction.
Interview Relevance: If an interviewer asks “how many services would this system need?” and you count database tables, they will immediately know you have the wrong decomposition instinct.
SLIDE 37: Service Boundary Anti-Patterns
Beyond the decomposition anti-patterns from Section 2, there are specific boundary-level mistakes that emerge during the design phase.
Anti-pattern 1: Circular dependencies
The Order Service calls the Payment Service to process payment. The Payment Service calls back to the Order Service to update order status. This creates a cycle where neither service can function without the other. The fix: the Payment Service publishes a “payment completed” event, and the Order Service consumes it. Data flows in one direction.
Anti-pattern 2: The “just one more call” chain
Service A calls B, which calls C, which calls D, which calls E. A single user request triggers a chain of 5 synchronous calls. Total latency is the sum of all 5 calls. If any one service is slow or down, the entire chain fails. The fix: evaluate whether A truly needs all that data, or if some calls can be replaced with cached data or asynchronous events.
Anti-pattern 3: Anemic services
A service that has no business logic and only forwards requests to another service. The “API Routing Service” that receives requests and passes them to the real services is not a useful boundary. It is an unnecessary network hop. The API Gateway handles this responsibility.
Anti-pattern 4: Shared kernel coupling
Two services import the same shared library that contains business logic. When the shared library is updated, both services must redeploy. Shared libraries for infrastructure concerns (logging, metrics, HTTP client) are fine. Shared libraries for business logic defeat the purpose of independent deployment.
Interview Relevance: Being able to spot these anti-patterns in a whiteboard design, whether your own or one the interviewer presents, is a key skill for senior-level interviews.
SLIDE 37B: Note It Down
Service boundary anti-patterns to memorize:
- Circular dependencies - If A calls B and B calls A, break the cycle with events
- Call chains - If a request triggers 5+ synchronous hops, replace some with caching or events
- Anemic services - If a service has no business logic and only proxies to another, remove it
- Shared business logic libraries - If two services share a library with business rules, they are coupled at deployment time
- Database table = service - If each table is a service, you have decomposed by schema, not capability
- God service - If one service handles multiple unrelated business capabilities, split it
The universal test for every boundary:
Can this service be developed, deployed, and operated by one team without coordinating with other teams for most changes? If yes, the boundary is good. If no, the boundary needs to move.
Interview Relevance: Memorizing these anti-patterns prepares you for the common interview question: “What could go wrong with this microservices design?”
SLIDE 38: Boundary Discovery Techniques
How do you actually find the right boundaries in practice? These are the techniques used by real engineering teams.
Technique 1: Event Storming
Get domain experts, engineers, and product managers in a room. Use sticky notes on a wall. Write down every event that happens in the system (“Order Placed,” “Payment Authorized,” “Inventory Reserved,” “Shipment Created”). Group related events. The groups that form naturally often correspond to service boundaries. Events that cross between groups become the inter-service communication.
Technique 2: Start with the transaction boundaries
Identify every operation that must be atomic (all-or-nothing). Everything that must succeed or fail together belongs in one service. If “create order” and “add line items” must be one transaction, they belong in the same service. If “create order” and “reserve inventory” can be eventually consistent, they can be separate services.
Technique 3: Ask “what changes together?”
Look at your version control history. Which files always change in the same commit? Which modules always appear in the same pull request? Code that changes together has high cohesion and should stay together.
Technique 4: Follow the team structure
If your organization already has a Payments team and an Orders team, those are your starting boundaries. Conway’s Law will push the architecture in this direction regardless, so you might as well align proactively.
Interview Tip: If an interviewer asks “how would you discover service boundaries for a system you are not familiar with?”, mentioning event storming and transaction boundary analysis shows practical methodology, not guesswork.
Interview Relevance: Interviewers do not just want to see your final service boundaries. They want to see the process you used to arrive at them.
SLIDE 39: Real Example, E-Commerce Service Boundaries
System: An e-commerce platform like Amazon

Why these boundaries work:
- Catalog Service - Manages product listings, descriptions, images, categories, search indexing. Changes when the merchandising team updates product content. Read-heavy, needs caching and search optimization.
- Cart Service - Manages shopping carts, saved items, cart persistence. Changes when the conversion team experiments with cart features. Needs session-level storage with fast reads and writes.
- Order Service - Manages order lifecycle from creation to completion. Changes when order workflow rules change. The core aggregate is the Order with its line items.
- Payment Service - Handles authorization, capture, refunds, payment methods. Changes when new payment providers are added. Integrates with external payment gateways.
- Inventory Service - Tracks stock levels, warehouse locations, reservations, restocking. Changes when warehousing logistics change. Needs real-time accuracy for stock counts.
- Shipping Service - Manages shipment creation, carrier integration, tracking, delivery estimates. Changes when logistics partnerships change.
Each service maps to a distinct business capability, is owned by a separate team, and has its own database.
Interview Relevance: Having a well-reasoned e-commerce decomposition ready to present saves time in interviews and demonstrates experience with the most common system design problem domain.
SLIDE 40: Real Example, Ride-Sharing Service Boundaries
System: A ride-sharing platform like Uber
Key insight: The Dispatch Service and the Pricing Service both need real-time location data, but they are separate services because they change for different reasons. Pricing changes when the economics team adjusts surge algorithms. Dispatch changes when the engineering team optimizes matching algorithms. They have different release cadences and different teams.
Interview Relevance: Ride-sharing is one of the most frequently asked system design problems. Having a clear service decomposition with reasoning for each boundary prepared in advance is a significant advantage.
SLIDE 41: Real Example, Streaming Platform and Banking
System 1: A streaming platform like Netflix
- User Service - Profiles, preferences, parental controls, account settings
- Catalog Service - Movie and show metadata, genres, cast, availability by region
- Recommendation Service - Personalized suggestions based on viewing history and similar users. Compute-intensive, uses ML models, changes independently from catalog content.
- Playback Service - Stream initiation, quality adaptation, DRM, resume position. Latency-critical, closest to the CDN infrastructure, very different scaling profile from recommendations.
- Billing Service - Subscriptions, payment processing, plan management, invoicing. Changes when pricing tiers change. Strict financial compliance requirements.
Key insight: Recommendation and Playback are both part of “watching a movie,” but they have completely different scaling profiles, technology stacks, and team expertise. Recommendations are batch-computed and ML-heavy. Playback is real-time and infrastructure-heavy. This is a textbook case where different scaling and technology needs drive separate services.
System 2: A banking platform
- Account Service - Account creation, balance inquiries, account status. The core entity that everything references.
- Ledger Service - Transaction recording, double-entry bookkeeping, balance updates. Every financial movement is a ledger entry. This service must be append-only and auditable.
- Transfer Service - Initiating and executing transfers between accounts. Orchestrates the saga: debit source account, credit destination account, record in ledger.
- Risk Service - Fraud detection, transaction limits, suspicious activity monitoring. Evaluates every transfer in real-time. Changes when compliance regulations change.
- Notification Service - Alerts for transactions, low balance, suspicious activity. Fire-and-forget. Should never block a financial transaction.
Key insight: In banking, the Ledger Service is the most critical service because it is the system of record. Every other service eventually writes to or reads from the ledger. This is different from e-commerce where the Order Service is central.
Interview Relevance: Having decomposition examples across multiple domains (e-commerce, ride-sharing, streaming, banking) shows the interviewer you can apply decomposition principles to any system, not just the one you memorized.
SLIDE 41B: Interview Practice
Question:
An interviewer asks you to decompose a messaging platform like WhatsApp into microservices. You have 2 minutes. Go.
Take 60 seconds to think about your decomposition before reading below.
Weak Answer:
“I would have a Message Service, a User Service, a Group Service, a Media Service, a Notification Service, and a Presence Service.”
Why this is weak: The candidate listed services without explaining why these boundaries exist. More importantly, they did not discuss the unique characteristics of messaging that should drive the decomposition (real-time delivery, massive fan-out for groups, presence at scale, media storage).
Strong Answer:
“I would decompose based on the distinct business capabilities and their very different scaling and technical requirements.
First, a User Service for account management, contacts, and profile information. This is standard CRUD with relatively low write volume.
Second, a Messaging Service for the core message delivery pipeline. This is the heart of the system, handling one-to-one and group message routing, delivery receipts, and end-to-end encryption. This service has extreme throughput requirements. A platform like WhatsApp handles over 100 billion messages per day. It needs a specialized storage engine optimized for write-heavy sequential message storage.
Third, a Group Service for group creation, membership management, and group metadata. I am separating this from messaging because group management (adding members, changing names, setting permissions) is a different business capability from message delivery, and group fan-out (sending one message to 256 members) has different scaling characteristics than one-to-one delivery.
Fourth, a Media Service for image, video, and document storage and delivery. Media has completely different storage requirements (blob storage, CDN delivery) and different latency tolerance (uploading a video can take seconds, but the upload should not block text message delivery).
Fifth, a Presence Service for online/offline status and last-seen timestamps. This is extremely high-frequency data (every app open/close is a presence update for 2 billion users) and needs a specialized in-memory data store rather than a relational database.”
What makes this strong: The candidate explains the reasoning behind each boundary (different scaling profiles, different storage needs, different business capabilities) and includes real-world scale numbers to justify the separation.
SLIDE 42: Decomposition Decision Framework
When you are unsure whether to split or merge two components, run through this checklist.
Split into separate services when:
- Different teams own them and have different release cadences
- They have significantly different scaling requirements (10x+ difference in load)
- They change for different business reasons at different frequencies
- A failure in one should not affect the other
- They need different data storage technologies
- They have different compliance or security requirements
Keep together in one service when:
- They always change together for the same business reason
- Splitting would require synchronous calls between them for most operations
- They share the same data and need transactional consistency
- They are owned by the same team with no foreseeable organizational split
- One cannot do anything useful without the other
The final validation:
After you draw your service boundaries, check each boundary against these three questions:
- Independence test - Can each service deploy without coordinating with other services?
- Cohesion test - Can you describe each service’s purpose in one sentence without “and”?
- Coupling test - Does a change in one service rarely require a change in another?
If all three answers are yes for every service, your boundaries are sound.
Interview Tip: Running through this checklist out loud during an interview shows the interviewer you have a repeatable process for validating service boundaries, not just intuition.
Interview Relevance: This framework is the most practical tool in this section. Memorize the split criteria, the merge criteria, and the three validation questions.
SLIDE 43: Section Summary and Interview Tips
Section 3 Summary:
Common Interview Mistakes:
Key Numbers to Remember:
How This Connects to Other Sections:
Section 4 (Communication Patterns) addresses the next question after boundaries: how do these services talk to each other? The synchronous vs asynchronous decision depends directly on the coupling level you are willing to accept between services. Section 5 (Data Ownership) tackles the hardest consequence of good boundaries: when each service owns its data, how do you handle cross-service queries and data duplication? Section 6 (Sagas and Consistency) builds directly on aggregates. Everything inside an aggregate is a local transaction. Everything across aggregates requires the saga pattern.