Jul 08, 2026 · 11 min read
Your Domain Model Is a Political Document, Not an Engineering One
Why bounded contexts rot into distributed monoliths: the boundary that matters is data ownership and change cadence, not the org chart you quietly drew it around.
Your Domain Model Is a Political Document, Not an Engineering One
Here is the uncomfortable truth that most domain-driven design writing tiptoes around: the boundaries in your system are not decided by your domain. They are decided by who reports to whom, whose roadmap wins the quarterly planning fight, and which team can defend its database from the others. The domain model is downstream of the politics, not the other way around. You can run a flawless event storming session, cover a wall in orange and blue stickies, and produce a context map that would make Eric Evans proud — and it will still rot, because none of it settled the only question that matters: who actually owns the concept when two teams both need to change it.
I want to push directly against the dominant framing that domain-driven design in practice is a modeling problem you can solve with enough workshops. It isn’t. Modeling is the easy part. Any competent group of engineers can identify that Order, Customer, and Invoice mean different things in different parts of a business. The hard part — the part that determines whether your bounded contexts survive contact with production — is negotiating authority over shared concepts before anyone draws a single box. Skip that negotiation and you don’t get a set of clean bounded contexts. You get a distributed monolith wearing a microservices costume, and you get it faster than you think.
Event Storming Answers the Wrong Question
Event storming is a genuinely useful technique. It surfaces domain events, aggregates, and the seams where language shifts. What it does not do — what no facilitation technique can do — is tell you where authority should sit. It tells you where language changes today, which is a description of the current org’s compromises, not a prescription for a durable architecture.
Consider what happens in the room. The people placing stickies are the people who showed up. Their mental model of the domain is shaped by the team they’re on and the incidents they’ve been paged for. When a “Payment Authorized” event lands on the wall, whether it belongs to the Checkout context or the Payments context is not resolved by the sticky note. It’s resolved later, quietly, by whichever team has budget to build the service and whichever manager is more willing to take on the on-call burden. The workshop produces a map. The politics produce the boundary.
This is why so many bounded context design efforts feel successful and then quietly fail. The artifact looks correct. Everyone agreed. But agreement in a workshop is cheap because nobody committed to giving anything up. Real boundary decisions are about ceding control — one team accepting that it can no longer write to a table it used to own, or that it must now ask another team for a change it used to make itself. That’s not a modeling decision. That’s a treaty negotiation, and treaties don’t get signed with sticky notes.
The Two Signals That Actually Define a Boundary
If org politics is the corrupting force, what’s the honest alternative? Two signals, and they’re both boringly concrete: data ownership and change cadence.
Data ownership means exactly one context can write a given piece of state. Not “is the source of truth in principle” — literally holds the write path, enforces the invariants, and can reject a mutation that violates them. If two contexts both write to the same logical entity through different code paths, they are not two contexts. They are one context with a network partition running through its middle, and every consistency bug you’ll spend the next year chasing lives in that partition.
Change cadence is the second signal and the one teams routinely ignore. Two concepts might look coupled in the data model but change on completely different rhythms. Pricing rules change weekly under marketing pressure. The tax calculation engine changes twice a year when regulations shift. A catalog’s product taxonomy might be stable for months while inventory levels churn by the second. When change cadences diverge sharply, you want a boundary there even if the data looks tightly related, because a fast-moving concept trapped in the same deployment unit as a slow, high-risk one means every pricing tweak now carries the deployment risk of the tax engine. That’s a coupling tax you pay on every release.
Draw your microservices ownership boundaries along these two lines and you get contexts that can genuinely evolve independently. Draw them along team names and you get contexts that share writes and deploy in lockstep — the exact properties that make a distributed monolith worse than the monolith it replaced, because now the coupling is invisible and travels over the network with retries, timeouts, and partial failures attached.
Conway’s Law Is Not Advice, It’s Gravity
The standard response here is to invoke Conway’s law: organizations design systems that mirror their communication structures. True, and well-supported. But people cite Conway’s law as if it were a strategy — “align teams to services and let the architecture follow.” The Team Topologies crowd has built a whole vocabulary around this, and much of it is sound. Stream-aligned teams, platform teams, the inverse Conway maneuver — these are real, useful ideas.
The failure mode is treating Conway’s law software architecture reasoning as sufficient. It isn’t. Conway’s law describes gravity. It tells you the direction things will fall if you do nothing. It does not tell you where the floor should be. If your org chart has a Checkout team and a Fulfillment team purely because that’s how headcount was allocated three reorgs ago, then aligning contexts to those teams just launders an accident of hiring into an architectural principle.
The inverse Conway maneuver — reshaping teams to get the architecture you want — is the honest move here, but it’s expensive and slow, and it requires executive authority most architects don’t have. So what actually happens in enterprise architecture and team topologies discussions is that the existing org chart wins by default, and the domain model is quietly bent to fit it. The boundary sits where the reporting line sits. Then everyone acts surprised when the two services that were supposed to be independent turn out to need synchronized releases, shared database migrations, and a standing cross-team sync meeting to coordinate any change of consequence.
Gravity pulled the boundary to the org chart. Nobody chose it. That’s the problem.
The Shared Concept Nobody Wants to Own
The clearest place to watch this dynamic play out is around concepts that genuinely span the business — the ones that don’t belong cleanly to any single team, so everyone touches them and no one owns them.
Localization content is a perfect example, and it’s one I think about constantly because it’s the space my product LingoHub operates in. In a product of any size, translatable strings, locale rules, and content variants show up everywhere: the marketing site, the transactional emails, the in-app UI, the error messages coming out of three different backend services. Every team needs to read and often write this content. Almost no team wants to own the system of record for it, because ownership means being on the hook for the workflow — who approves a translation, how a new locale gets rolled out, what happens when a string changes and forty downstream surfaces need to re-render.
What you see when nobody negotiates ownership up front is predictable. Each team stashes its own strings in its own repo, in its own format, with its own half-built process for getting them translated. The “localization boundary” exists on the context map as a neat little box, but in reality it’s smeared across every service in the company. There is no single write path, no single change cadence, no authority. When a CTO finally asks “how long to add Japanese,” the answer is a multi-quarter project touching every team, because the concept was never actually bounded — it was just drawn.
The reason a dedicated translation management system helps here is not primarily the translation features. It’s that it forces the ownership decision: content lives in one place with one write path and one workflow, and services consume it through a defined contract rather than each holding a private copy. That’s what a real bounded context looks like — a place where authority over the shared concept is settled. Building LingoHub, the recurring pattern I see is that the tooling only sticks once someone in the org has been made accountable for the localization boundary. Without that political decision, no tool saves you; you just get a nicer database for the same distributed mess.
How the Distributed Monolith Forms in Two Quarters
Let me trace the failure explicitly, because the speed of it is the part people underestimate.
Quarter one: the context map is agreed. Two services get carved out — say, an Orders service and a Billing service — with the boundary drawn between the Orders team and the Billing team. There’s a shared notion of a “line item” that both need. Nobody wants to block on the other, so both services keep their own copy of line-item data, synced by events. Everyone is happy. The demo works.
Mid quarter two: a business change requires line items to carry a new field — a discount attribution, say. Because both services materialize their own copy, the change requires coordinated deploys. Billing can’t compute correctly until Orders emits the new field; Orders can’t stop emitting the old shape until Billing has migrated. So the two “independent” services now ship together, in a specific order, with a rollback plan that spans both. The event contract has become a shared schema that neither team can change alone.
End of quarter two: there are now three or four of these shared shapes. Every meaningful change requires a cross-team coordination call. The teams have added retries and dead-letter queues to paper over the sync lag, which means they’ve also inherited a class of eventual-consistency bugs — a customer sees a discount in Orders that hasn’t propagated to Billing, support gets a ticket, and someone spends a day reconciling two databases that should never have both held the same truth.
This is the distributed monolith anti-pattern in its natural habitat. It didn’t come from bad modeling. The model was fine. It came from a boundary drawn between two teams rather than around a single owner of the line-item concept. Had someone decided up front that line items are owned by Orders and Billing consumes an explicit, versioned view it never writes to, the discount field is a one-team change with a contract addition. Same domain, same teams, radically different failure surface — the difference is entirely in who was granted authority over the shared concept.
Negotiate Authority Before You Draw Boxes
So what do I actually do differently, given that the politics are real and the org chart has gravity?
Start the design with an ownership map, not a context map. For every concept that more than one team touches, name a single owning context and write down what that ownership grants and forbids: who holds the write path, what invariants that context enforces, and what the read contract is for everyone else. Do this in a room with the people who have the authority to give things up — engineering leadership, not just the engineers. If the person who can reassign a database can’t be in the room, you’re not designing a boundary; you’re drafting a proposal someone else will overrule.
Treat every shared concept as a negotiation with an explicit outcome. Either one context owns it and others consume a defined view, or you consciously accept shared ownership and pay for it with strong contracts, versioning, and consumer-driven contract tests — never implicit dual writes. The middle ground, where two teams “sort of” share something and hope events keep it aligned, is the ground the distributed monolith grows in.
Then use change cadence as a tiebreaker. When it’s genuinely unclear where a boundary belongs, put it where the deployment rhythms differ most sharply, because that’s where independent deployability buys you the most and where lockstep coupling hurts most.
And be honest that this is political work. The valuable skill in domain-driven design in practice is not fluency with aggregates and value objects — that’s table stakes. It’s the willingness to walk into a planning meeting and say “Billing does not get to write line items anymore, and here’s why the whole system gets more reliable if that team gives up something it currently controls.” That sentence wins or loses your architecture. Everything on the whiteboard is downstream of whether you can get it agreed.
Your domain model is a political document. The sooner you treat it like one — negotiating authority instead of pretending you’re just drawing the true shape of the business — the sooner your bounded contexts will hold up under the load they were supposed to survive in the first place.
References
- Eric Evans, Domain-Driven Design: Tackling Complexity in the Heart of Software (Addison-Wesley, 2003) — the origin of bounded contexts and context mapping.
- Melvin Conway, “How Do Committees Invent?” (Datamation, 1968) — the original statement of what became Conway’s law.
- Matthew Skelton and Manuel Pais, Team Topologies (IT Revolution, 2019) — team-first architecture and the inverse Conway maneuver.
- Sam Newman, Building Microservices, 2nd ed. (O’Reilly, 2021) — ownership boundaries, data decomposition, and the distributed monolith failure mode.
- Martin Fowler, “BoundedContext” and related notes at martinfowler.com — concise treatment of context boundaries and shared kernels.