Skip to content

Distributed Systems Are an Ownership Problem

I've been trying to understand why distributed systems felt so much harder than monoliths when I first started building them.

Not technically. I expected them to be technically harder. What surprised me was how much harder they were to reason about. I'd read about eventual consistency, retries, idempotency, message ordering, and distributed transactions, and none of those ideas were beyond me individually — if someone explained a pattern or a technology, I could usually follow along without much trouble. But when I sat down to design a distributed system myself, something felt different. Two experienced developers could look at exactly the same problem and arrive at completely different architectures. Both could sound reasonable. Both could work. Yet somehow one solution would almost always prove easier to evolve a year later, and for a long time I couldn't explain why.

I thought I just needed to learn more technology. Now I think I was trying to solve the wrong problem.

Carrying a monolith into a distributed world

Like many developers, I learned software development on monolithic applications, and you don't think much about ownership in a monolith. There's one application, one deployment, usually one database. If one part of the system needs information from another, it calls a method. If it needs data, it queries the same database. The boundaries are flexible enough that many architectural decisions can simply be postponed, and the application quietly becomes responsible for everything.

Without realizing it, I carried that mental model with me when I started building distributed systems. The technologies changed — method calls became HTTP requests, background jobs became message queues, one database became several — but my way of thinking hadn't changed at all.

I was still trying to partition software.

I hadn't yet learned to partition the business.

The question that unlocked the discussions

Over the years, I began noticing something about architecture discussions: whenever they became difficult, they almost always followed the same pattern. The conversation would start with services. Should this service own the API? Should that service expose an event? Where should this table live? Should this call be synchronous or asynchronous? Should we duplicate the data? All perfectly reasonable questions — and they rarely moved the conversation forward.

Eventually, someone would ask a completely different kind of question: who actually owns this business responsibility? Almost every time, the discussion became dramatically simpler. That one question seemed to unlock everything else, and it took me years to understand why.

I had been treating services as the starting point. They aren't. Services are an implementation. Business capabilities exist whether software does or not: a company knows who hires employees long before someone writes an Employee Service, and it knows who manages customer accounts before someone creates a Customer API. Software doesn't invent those responsibilities. It merely implements them.

Once I started thinking this way, architecture stopped feeling like an exercise in drawing boxes and arrows. It became an exercise in understanding the business well enough to discover where responsibilities naturally belong. The technology came afterwards.

Ownership isn't about storage

One realization changed my thinking more than any other: a business fact isn't defined by where it's stored. It's defined by who gets to decide whether it's true.

That distinction took me embarrassingly long to appreciate. I'd spent years worrying about duplicate data. Like many developers, I instinctively wanted a single copy of everything, and eventually I realized I had been protecting the wrong thing.

One pattern I've noticed is that discussions about identity often begin with the wrong question.

A team introduces a User Service alongside an external identity provider, and the conversation immediately becomes about duplication. If both systems contain user information, haven't we created two sources of truth? The discussion turns to schemas, APIs, and synchronization strategies, yet somehow never gets closer to a decision.

The discussion usually changes when someone asks a different question: who actually owns each business fact?

The identity provider owns authentication. It decides identities, credentials, and everything required to prove who a user is. The User Service isn't trying to replace that. It exists because the business has responsibilities that the identity provider never will: organizational membership, enterprise identity relationships, application-specific roles, and the business rules that connect those identities to the platform.

Once ownership becomes clear, the duplication largely stops mattering. Some information exists in both systems, but only one system is authoritative for each business fact.

Copies are cheap. Ownership is expensive.

A customer's information might be copied into ten different databases. An employee might appear in half a dozen applications. The real problem begins when two different capabilities both believe they have the authority to decide the same business fact. That's when systems slowly drift apart. That's when reconciliation jobs appear. That's when developers stop trusting the data they're looking at.

The issue was never duplication. It was ownership.

Entities aren't capabilities

Even after I understood authoritative ownership, one nuance took much longer to internalize: business entities aren't the same thing as business capabilities. That sounds obvious now. It certainly wasn't obvious to me.

Take something as simple as an employee. At first, it seems natural to think that one system should own employees. But an employee isn't a business responsibility — it's a business concept. Employment status is one responsibility. Organizational hierarchy is another. Communication preferences are another. Physical access might belong somewhere else entirely. They're all facts about the same person, but they aren't the same kind of fact, and different capabilities can legitimately own different truths about the same employee.

Once that clicked, I stopped trying to partition systems around nouns. I started partitioning them around decisions.

Owning the truth isn't the same as serving it

One consequence surprised me. For years, I assumed that if another service needed information, it should ask the authoritative source directly — after all, that's where the truth lived. The problem is that truth and convenience aren't the same thing. If every request depends on several other services being available, you've built a system whose reliability is limited by its longest chain of dependencies.

Eventually I realized that authoritative ownership doesn't imply authoritative reading. A capability can own the business facts while other capabilities maintain their own projections of them, shaped specifically for the work they need to do. The ownership stays centralized. The reading becomes local. That single idea removed an enormous amount of unnecessary coupling from how I thought about systems, and it finally made projected read models feel like a natural consequence of ownership rather than a clever trick layered on top of it.

Where the model runs out

I should be honest about the limits of this. Asking who owns a business responsibility assumes that somebody can answer, and sometimes nobody can. Two departments may each believe they decide the same fact. A responsibility may be genuinely shared, or in the middle of moving from one part of the organization to another. When that happens, the mental model doesn't produce an architecture — it surfaces an organizational question that was never settled, and no amount of system design will settle it from below. Ownership also moves: businesses reorganize, responsibilities merge and split, and a boundary that was right two years ago may not be right today.

I've come to see that as a feature rather than a flaw. The service-first questions let an unresolved ownership dispute hide inside a diagram for months. The ownership question drags it into the open in the first meeting. But I don't want to oversell it: dragging the question into the open is not the same as answering it.

The hardest part wasn't the technology

When I think about the hardest part of learning distributed systems, it isn't the technology that stands out. Retries can be learned. Idempotency can be implemented. Resiliency patterns can be practiced. Those are engineering problems.

The harder challenge was learning to stop seeing architecture as a collection of services and start seeing it as a collection of business responsibilities. Everything else followed from there. Only after the ownership questions have answers does it make sense to talk about APIs, events, databases, or deployment boundaries.

I've come to think that distributed systems are really an ownership problem disguised as a technical one.

Once I changed that mental model, the technology didn't become easier.

It became obvious where the technology belonged.