rgoussu@goussu: ~/library/system-design
~/library/system-design cat microservice-architecture.md

Microservice architecture

# Decomposing a system into independently deployable services — when it pays, what it costs, and the patterns that make it survivable.

Conceptsaved 2026-08-08updated 2026-08-20 #microservices#architecture#distributed-systems#system-design#modulith

Overview

Microservice architecture splits a system into small, independently deployable services, each owning its data and aligned with a business capability. The prize is independent deployment and team autonomy; the price is turning in-process calls into a distributed system with all its failure modes. The honest framing (Fowler, Newman): you must be this tall — mature CI/CD, observability, and ops — before the trade is worth it, and a well-modularized monolith is the right starting point more often than not.

Key points

  • Boundaries are the whole game: services should map to bounded contexts (DDD); get boundaries wrong and you build a distributed monolith — the worst of both worlds.
  • Database per service: no shared database; data crosses boundaries via APIs and events, consistency becomes eventual (async patterns, sagas, outbox).
  • Communication: sync (REST/gRPC, simple but couples availability) vs. async (events, decoupled but harder to reason about); API gateway and service discovery at the edges; contract testing to keep independence real.
  • Deployment & ops: one service = one pipeline; containers + orchestration; observability (distributed tracing, correlation IDs) is non-optional because no single log tells the story.
  • Organizational mirror: Conway's law works both ways — team ownership per service is the point ("you build it, you run it").
  • Alternatives on the spectrum: modular monolith, and the middle grounds (moduliths, self-contained systems); migration via strangler fig, not big bang. The house position is to start as a modulith and keep extraction mechanical — see modulith & microservices.
  • To explore: service mesh, serverless as the extreme of the same axis, micro-frontends as the front-end analogue.

Details

The boundary tax

A boundary in a distributed system is not free. Every boundary buys you independent deployment and independent scaling, and charges you for it in serialisation, network transfer, orchestration state, request volume and failure handling [1]. Prime Video's own team found this the hard way: a serverless, heavily-decomposed pipeline was redesigned into a monolith and cut cost by ~90%, because the fan-out of boundaries was charging orchestration and data-transfer costs the workload didn't need. The lesson isn't "monoliths win" — it's that each boundary should be bought deliberately (per an operational trigger, not aesthetics — see modulith & microservices), not inherited from a reference architecture.

Practice

  • Saga, twice (source) — implement an order/payment saga as choreography, then as orchestration, with a compensating action for every failure point; the trade-off writes itself.
  • FTGO application (source) — Richardson's reference implementation: trace one service's boundaries, then add a small feature end to end — API, events, saga.
  • Strangler fig migration (source) — carve one bounded context out of a monolithic side project behind a routing facade, without breaking the rest.
  • Build the edge (source) — the gateway tier every service system needs — load balancing, health checks, per-key limits — built from scratch.

Related

Citations

[1] Prime Video cut costs 90% by deleting its serverless architecture, then the post vanished