Grokking Microservices for System Design Interviews

0% completed

Drawing Service Boundaries

  1. From Concept to Method
  1. Four Heuristics That Produce Boundaries
  1. Capabilities, Not Entities
  1. Three Tests That Catch Bad Boundaries
  1. In the Interview
  1. TL;DR

1. From Concept to Method

Bounded contexts told you what a good boundary is. This lesson gives you the working method. You get four heuristics that produce boundaries, and three tests that catch bad ones before they ship. A heuristic is a rule of thumb, a shortcut that is fast to apply and usually right.

Together, the heuristics and the tests are the content of a strong answer to "how would you split this system?" That question is among the most frequently asked microservices questions at every level.

2. Four Heuristics That Produce Boundaries

Heuristic 1: One writer per piece of data. For every important entity, ask one question. Who is the single source of truth for this data? The source of truth is the one place where the real, authoritative value lives.

Exactly one service should write inventory counts. Exactly one should write payment records. If a proposed split leaves two services writing the same data, the boundary is wrong.

Data ownership is the most reliable boundary-finding tool because it is binary. Either one service writes the data or more than one does. Shared writes fail loudly and immediately. Shared concepts fail slowly.

Every piece of data needs exactly one writer. Two services writing the same data means the boundary is drawn in the wrong place.
Every piece of data needs exactly one writer. Two services writing the same data means the boundary is drawn in the wrong place.

Heuristic 2: Things that change together stay together. Look at the last twenty feature requests. If most changes to cart logic also touched checkout logic, cart and checkout want to be one service. A boundary between them would turn every feature into a two-service, two-deploy coordination exercise.

The inverse also holds. If the catalog changed fifteen times while fulfillment changed twice, a boundary between them costs nothing.

Heuristic 3: Follow the team structure. A service should have exactly one owning team, and a team should own a small number of services. This is Conway's law used deliberately. Conway's law says your architecture ends up copying your org chart.

A boundary that cuts across a team creates coordination inside the team's own codebase. A service owned by three teams has no owner at all. When a technical boundary and the org chart disagree, one of them will move. Decide which one on purpose.

Heuristic 4: Split where the profiles diverge. A profile is the set of demands a component makes: how it scales, how reliable it must be, what rules it must follow, how often it ships. Look for differences like these:

  • Different scaling needs: GPU image processing vs. CRUD traffic. A GPU is a graphics processor, a chip built for heavy parallel math. CRUD means plain create, read, update, delete operations.
  • Different reliability requirements: payments vs. recommendations.
  • Different compliance regimes: PCI card data vs. everything else. PCI is the security standard that governs how card data must be stored and handled.
  • Different release cadences: ML models retrained daily vs. a stable ledger. ML means machine learning, software that learns patterns from data. Release cadence is how often each part ships.

Divergent profiles are the strongest justification for a boundary. This is because they are the benefits from the first module made concrete.

3. Capabilities, Not Entities

The single most common boundary mistake in interviews is splitting by noun: a User service, an Order service, a Product service, a Payment service. It feels systematic, and it produces the wrong system.

Here is the problem. Real operations are verbs, and verbs cut across nouns. "Place an order" touches user, product, inventory, payment, and order data. If each noun is a service, placing one order means a synchronous chain of five network calls.

A synchronous call is one where the caller stops and waits for the answer. Each call is a new failure point, and no single service can do its job alone. You have built maximum coupling with maximum overhead.

Entity splitting is also how god objects return. A god object is one class or service that keeps absorbing loosely related features until everything depends on it. The User service picks up every user-adjacent feature in the company, and every other team files tickets against it.

Split by business capability instead: Checkout, Fulfillment, Catalog, Billing. A capability is a whole verb the business performs. A capability service owns that verb end to end, including all the data the verb needs to complete on its own.

Checkout owns carts, the ordering flow, and its own snapshot of the prices it charged. A snapshot is a saved copy of a value at a moment in time.

Entity boundaries chain five synchronous calls to place one order. A capability boundary completes the order inside Checkout and tells the rest with events.
Entity boundaries chain five synchronous calls to place one order. A capability boundary completes the order inside Checkout and tells the rest with events.

This is the same trade-off as organizing a codebase by layer (controllers, models) versus by feature. The feature folder keeps everything one change needs in one place. The capability service does the same for a running system.

The test of success has two parts. First, the most common operations complete inside one service. Second, the arrows on your diagram carry events between capabilities, not data fetches in the middle of every request.

4. Three Tests That Catch Bad Boundaries

Run every proposed boundary through these before defending it:

  1. The one-sentence test. Describe the service's responsibility in one sentence without the word "and." "Manages the product catalog" passes. "Manages users and sends notifications and tracks referrals" fails.

    That is three services, or more likely one service that should not exist. Think of a function named validateAndSaveAndEmail. The name alone tells you it does too much. The same smell applies to services.

  2. The arrow-counting test. Take the two or three most common user operations. Count the synchronous calls each one needs under the proposed split. One or two is healthy. Five is a warning.

    Watch for a count that grows with every new feature. That growth means the boundaries fight the domain, and the design is drifting toward chatty services.

  3. The lockstep test. Ask: can this service actually deploy alone? Lockstep means two services that can only ship together. If a typical change requires releasing the service together with a neighbor, the boundary exists on the diagram but not in reality. The usual signs are a shared schema, an API still in flux, or a feature split down the middle.

Run the three tests in order. Only a boundary that passes all three is worth defending in your design.
Run the three tests in order. Only a boundary that passes all three is worth defending in your design.

💡 In a design round, apply the tests out loud. "I am putting cart inside checkout because they change together and it keeps order placement to one synchronous call" earns more than any number of correctly named boxes. It shows the boundaries were derived, not recited.

5. In the Interview

This question is usually implicit in a design round. Sometimes it is explicit: "How do you decide what becomes a service?"

The 30-second answer: "I split by business capability, not by entity. That means Checkout and Fulfillment rather than User and Order, so common operations complete inside one service instead of chaining calls across five. To place boundaries I use data ownership (exactly one writer per piece of data) and change patterns (things that change together stay together). I also weigh team ownership (one owning team per service) and divergent profiles (different scaling, reliability, or compliance needs). Then I sanity-check each boundary: can I state the service's job in one sentence, and can it deploy alone?"

Likely follow-ups:

  1. "Checkout needs product prices, which Catalog owns. Doesn't your capability split break down?" No. Checkout keeps its own copy of the prices it needs, updated by events from Catalog. At purchase time, it snapshots the price into the order. The business wants that anyway, because the price charged must not change when the catalog does. Cross-context data needs are met with owned copies, not live reads. The mechanics live in a later lesson on data ownership.
  2. "How would you fix a boundary you got wrong?" Merging two over-split services is cheap. Do it without ceremony. Splitting an under-split service is the harder direction. Extract along the new line inside the codebase first, using modules and separate tables. Then move it out. That is the strangler approach in the migration lesson.

A red flag that fails candidates: drawing one box per database noun and calling it a design. Interviewers name this specific pattern in their write-ups as the most common failure in microservices design rounds.

6. TL;DR

Four heuristicsOne writer per data; change together, stay together; one owning team; split on divergent profiles.
The big ruleCapabilities (verbs), not entities (nouns).
Three testsOne sentence without "and"; count arrows per operation; can it deploy alone?
Cross-boundary dataOwned copies fed by events, not live reads and not shared tables.
Red flagOne service per noun: User, Order, Product, Payment.
Flashcards Review

What are the four heuristics that produce service boundaries?

1 / 20
General
Test Your Knowledge
Check your understanding and reinforce the key concepts covered in this section with a short, targeted assessment.
10 Questions
~15 mins
Your progress is saved automatically
Mark as Completed

On This Page

  1. From Concept to Method
  1. Four Heuristics That Produce Boundaries
  1. Capabilities, Not Entities
  1. Three Tests That Catch Bad Boundaries
  1. In the Interview
  1. TL;DR