Skip to content

VOL 07 / CH 06 / LESSON 01

6.1 Microservices Are Fault Topologies, Not Directory Splitting ​

A growing application still bundles accounts, analytics, search, and reporting into one deployment unit. Does it actually need to be split, and if so, where should deployment and data boundaries fall? Cutting directories is easy; creating boundaries that can independently contain failures is the hard part.

Once modules are moved into separate processes, local calls become network calls, local transactions evolve into cross-service workflows, and function parameters transform into long-term service contracts. The benefits of microservices (such as independent deployment, scaling, isolation, and team ownership) come at the cost of distributed failure.

Volume 6 covered service extraction, gateways, resilience, and Saga patterns. This chapter takes a distributed systems perspective: does actual decomposition truly create manageable fault domains?

Service Boundaries Must Simultaneously Meet Multiple Criteria ​

A healthy service typically satisfies all of the following:

  • Business capabilities and a shared language;
  • A public API or event contract;
  • Ownership of data writes;
  • Independent build, deployment, and rollback capabilities;
  • Ownership of capacity, SLOs, alerts, and on-call responsibilities.

A service with independent code repositories but no independent data or release authority remains merely a distributed monolith. An independent database does little for autonomy if every feature still requires five teams to release together.

Required Dependencies Jointly Determine Availability ​

If a request synchronously depends on A, B, and C, a timeout in any one can fail the request. Success probabilities multiply only under assumptions such as independent failures and matching measurement definitions. Three required dependencies each at 99.9% then give approximately 0.999³ = 99.7003% joint success. Shared databases, datacenters, or certificates create correlated failures that invalidate that calculation. Multiplying several vendors’ monthly SLAs does not establish your SLO. Serial waits also accumulate latency; assess the tail using actual call distributions.

text
Gateway → Order → Inventory → Pricing → Promotion → Payment

We must distinguish between:

  • Mandatory dependencies: failure means the operation cannot complete truthfully;
  • Optional dependencies: can return clear fallbacks;
  • Asynchronous post-processing: does not block the front-end response;
  • Pre-computation or caching: trades freshness for isolation.

Changing synchronous calls to asynchronous ones does not automatically decouple components. Message contracts, backlog handling, idempotency, and responsibility for the eventual outcome still exist.

Remote Interfaces Should Be Coarse-Grained ​

Local objects can frequently invoke getters, but remote APIs should not simulate fine-grained object graphs. Each RPC incurs costs of serialization, queuing, network transmission, authentication, and potential failure.

Design interfaces around use cases (such as QuoteOrder returning all pricing data in a single response) rather than requiring clients to make individual calls to getPrice, getDiscount, and getTax.

QuoteOrder can also return a quote version and expiry so order submission can identify the prices used. Combining dozens of getters into one call is only the start. If prices and discounts come from incompatible versions, fewer round trips will not mean less reconciliation. Contracts still need clear responsibilities, size limits, and versioning strategies.

Data Ownership Limits Coupling ​

Services should modify data through its owner’s contract. Several services writing the same tables can bypass one another’s business rules and force coordinated schema migrations. Logical ownership does not require a dedicated database machine for every service: separate schemas, accounts, permissions, and write authority can establish boundaries within one instance, while still sharing capacity and a failure domain. Independent releases likewise do not require separate Git repositories.

Cross-service queries can be achieved via API composition, CQRS projections, data products, or analytics warehouses. Choose according to freshness, latency, and consistency. An online query that directly joins every production database creates dependencies across those ownership boundaries.

Fault Isolation Requires Resource Boundaries ​

An independent process does not guarantee fault isolation. Multiple services may still share:

  • The same downstream connection or concurrency quota, even with independent process-local thread pools;
  • The same database or message partition;
  • The same node, zone, or account quota;
  • The same gateway and identity service;
  • The same deployment pipeline or certificate.

Suppose 50 services each configure a database pool limit of 100. Their theoretical demand reaches 5000 connections, while the shared database allows only 300. Every local pool is bounded, yet the aggregate can still exhaust the dependency. A faulty shared configuration template creates correlated failure too, but that differs from sharing a runtime resource. Architecture diagrams, capacity checks, and failure exercises must cover these actual effects.

Autonomy Does Not Mean Arbitrary Heterogeneity ​

A team can choose the most suitable technology, but every language, database, or framework adds costs in the form of patches, monitoring, on-call responsibilities, and talent acquisition. Organizations should provide a limited number of well-supported, paved paths. Any special choices must deliver quantifiable benefits and have long-term ownership assigned to them.

Is It Worth Splitting? ​

  • Are there real metrics to support independent scaling or fault isolation?
  • Can the team independently deliver and operate the service?
  • Will core invariants be fragmented into distributed transactions?
  • Are calls and data dependencies already clearly defined and managed within the monolith?
  • Does the platform provide capabilities for service discovery, identity management, observability, deployment, and failure recovery?
  • Does adding another network hop still meet the service level objectives (SLO)?

The next lesson establishes the minimal production baseline for a microservice platform, rather than reiterating middleware vendor names.

References ​

Built with VitePress | Software Systems Atlas