Microservices
debt(d9/e9/b9/t7)
Closest to 'silent in production until users hit it' (d9). The detection_hints explicitly state automated=no, and the only code pattern cited (distributed monolith) only becomes visible at runtime through cascading failures, latency spikes, or deployment coupling — not through any static or linting tool. Misapplication is invisible until the system is in production under real load and team coordination pressure.
Closest to 'architectural rework' (e9). The quick_fix itself acknowledges the remedy is 'begin as a modular monolith and extract services only when necessary' — meaning the fix for having wrongly adopted microservices is not a patch or refactor but a fundamental architectural reversal. The common_mistakes (wrong domain cuts, distributed monolith, shared databases, underestimated operational overhead) all require rewriting service boundaries, consolidating data layers, and restructuring deployment pipelines — classic e9 territory.
Closest to 'defines the system's shape' (b9). Applies to web and API contexts broadly, and the tags (architecture, scalability, devops, distributed) signal this is load-bearing across the entire system. Every future decision — deployment pipelines, team structure, data ownership, observability, inter-service communication — is shaped by this architectural choice. There is no local escape; the choice permeates the entire organisation and codebase.
Closest to 'serious trap — contradicts how a similar concept works elsewhere' (t7). The misconception field is explicit: developers believe microservices 'always improve scalability and deployment speed' when in reality they introduce distributed system complexity that only pays off at sufficient scale and team size. This is a well-documented but widely ignored gotcha — not quite t9 (the obvious way isn't always wrong, it is right at scale) but clearly t7 since the expectation of automatic improvement is strongly contradicted by operational reality for most teams.
Also Known As
TL;DR
Explanation
Microservices decompose a monolith into small services that own their data, are independently deployable, and communicate via HTTP APIs or message queues. Benefits include independent scaling, technology flexibility, and team autonomy. Costs include: distributed systems complexity (network latency, partial failures, distributed transactions), service discovery overhead, and operational burden (logging, tracing, many deployment units). Microservices suit large organisations with multiple teams — for smaller teams, a well-structured monolith (modular monolith) is often the right starting point.
Diagram
flowchart TD
GW[API Gateway] --> OS[Order Service]
GW --> US[User Service]
GW --> PS[Payment Service]
OS <-->|events| BUS[[Message Bus]]
PS <-->|events| BUS
OS --> ODB[(Orders DB)]
US --> UDB[(Users DB)]
PS --> PDB[(Payments DB)]
style GW fill:#d29922,color:#fff
style BUS fill:#6e40c9,color:#fff
Common Misconception
Why It Matters
Common Mistakes
- Migrating to microservices before understanding your domain boundaries — wrong cuts create distributed monolith.
- Making services so fine-grained they require synchronous calls to ten other services to fulfil one request.
- Sharing a database between services — that is a monolith with extra network hops.
- Underestimating operational overhead — microservices require service discovery, distributed tracing, and independent deployment pipelines.
Avoid When
- The team is small — microservices require significant operational maturity that small teams cannot sustain.
- The domain is not well understood — premature decomposition creates the wrong service boundaries that are expensive to fix.
- Latency budget is tight — network hops between services add milliseconds that in-process calls do not.
- The monolith is not causing problems — do not solve scaling or team problems you do not yet have.
When To Use
- Large teams where independent deployability removes coordination overhead between squads.
- Services with genuinely different scaling requirements — the payments service scales differently from the search service.
- Polyglot environments where different parts of the system benefit from different languages or runtimes.
- Well-understood domains where service boundaries align cleanly with business capabilities.
Code Examples
// Distributed monolith — services call each other synchronously in a chain:
// OrderService → InventoryService → PricingService → UserService
// One slow/failed service fails the entire chain
// Better: async events, or ensure each service has its own data and rarely calls others
# Each service: its own repo, own database, deployed independently
# They communicate over HTTP or message queue
# Order service calls Inventory service via HTTP
$response = $this->httpClient->post('http://inventory-service/reserve', [
'json' => ['sku' => $sku, 'qty' => $qty],
]);
if ($response->getStatusCode() !== 200) {
throw new ReservationFailedException();
}
# Or via message queue (decoupled, async)
$this->bus->publish(new OrderPlaced(orderId: $id, items: $items));
# Inventory service consumes the message independently