Microservices Done Right: Splitting, Communicating, and Governing Without Creating a Distributed Monolith
The article gives Western engineering teams a concrete checklist for avoiding the two most expensive microservices failures: splitting by technology instead of business capability, and ending up with a distributed monolith. It also spells out the operational requirements for eventual consistency that many teams discover only after data goes wrong.
This guide walks through a full microservices design path, starting with the decision to split. It argues that decomposition should follow business capabilities, not technical layers, and that a service only counts as independent if it has its own data, build pipeline, runtime resources, and backward-compatible contracts. The article stresses starting coarse (3–8 core domains) and refining later, and watching for the distributed monolith: services that still must be released together, which are worse than a single monolith.
On communication, it recommends synchronous HTTP/gRPC for queries and core paths with timeouts, and asynchronous messaging for side paths and commands that allow eventual consistency. It covers the role of an API gateway and BFF (Backend for Frontend) for aggregation and endpoint adaptation, while noting BFFs add overhead for small teams. Governance topics include service registration and discovery with graceful shutdown, config centers with gray push and defaults, circuit breaker state machines with fallback strategies, and the three pillars of observability.
The final section addresses distributed transactions, comparing 2PC, TCC, Saga, local message tables, and transactional messages. It lands on the local message table plus scheduled compensation as the lowest-cost approach, with the key points that the message table and business table must share a local transaction, consumers must be idempotent, and dead-letter queues with alerts are mandatory. It closes with three consistency rules: don't sacrifice availability for strong consistency, make every retried write idempotent, and reconcile core money flows.
The article's strongest claim is that a split is only real when independent deployment is possible; teams often celebrate service boundaries while still coupling releases, and that is exactly what turns a microservice architecture into a worse monolith.
The guidance to prefer eventual consistency almost everywhere, with idempotency and reconciliation as non-negotiable, is a sensible default for most web businesses, but it assumes teams can actually enforce idempotency at the design level, which requires discipline across every service.
The advice to start coarse and refine only when needed directly contradicts the common instinct to over-engineer microservices from day one; this positions the article as a practical counterweight to the "microservices everywhere" hype.
The author acknowledges that BFF adds a layer only justified when there are multiple client types with divergent needs, which is a pragmatic check against the tendency to adopt every pattern in the book.