Distribution Boundaries
8 lessons. Every one names the guarantee it claims, what a node can know, and how it fails.
Splitting a system into services does not make it faster or more scalable. It converts function calls into network calls, and in doing so hands you network failure, independent failure, distributed state, versioning, observability cost and deployment coordination — every subject in this domain, per boundary.
Q · What do I actually get, and what do I actually pay, when I split a system into services?
Many services, tightly coupled synchronously, sharing deployment assumptions and often a database schema. You pay every distributed-systems cost — network failure, ambiguous outcomes, versioning, tracing, operational overhead — and receive none of the independence those costs were supposed to buy.
Q · We have twelve services. Why does everything still have to ship together?
Does this boundary reduce coupling? Does it align with ownership and data? Can the two sides fail independently? Does it require constant synchronous chatter? Four questions, asked before the cut, that separate a boundary which buys independence from one that only buys network calls.
Q · I am about to draw a line between two parts of my system. How do I know it is in the right place?
Two services reading and writing the same schema keep joins and transactions — which are genuinely valuable and expensive to replace. They also make the schema a public interface, blur ownership, and turn independent deployment into a coordinated one. Both halves are true, and which dominates depends on facts you can check.
Q · Two services need the same data. Is sharing a database a shortcut or a mistake?
For every piece of state in the system, exactly one component decides what it is. Everything else — caches, search indexes, read models, replicas, downstream copies — is derived. Most incidents filed as "data inconsistency" are really an unanswered question about which component was authoritative.
Q · Two services disagree about a customer’s address. Which one is right?
The source of truth is the store whose value is correct by definition, and from which every other copy can be reconstructed. Naming it converts an argument into a repair procedure — and the reason so many incidents drag on is that nobody can name it.
Q · If everything except one store were deleted, which one would let me rebuild the rest?
Events flow into a projection, which produces a read model shaped for one query. The read model is fast, purpose-built and derived — and it is always behind the source by an amount you should be measuring, because everything downstream of that lag is a design decision you either made or inherited.
Q · I need a query the write model cannot serve efficiently. What does building a read model actually cost?
Derived state drifts. Not might — will. Compare the source of truth against each derivation, find the delta, repair it, and alert on the size of the delta. This is a designed part of the system with an owner and a schedule, and building it after the first incident is building it a year late.
Q · My search index and my database disagree. What repairs that, and who runs it?