Litdev

Distributed Software Architecture Fundamentals for Product Owners

Disclaimer: The following explanations are heavily salted with the opinions of the author.

Target audience: Product Owners (or anyone else working closely with development teams) in a company with a large technical landscape where multiple development teams operate independently of each other.

Why Should Product Owners Care About Software Architecture?

It all usually starts with a meeting that goes something like this:

  1. You propose a shiny new feature or epic, maybe something as simple as showing a user's birthday on the settings page.
  2. The developers immediately start raising concerns about potential technical pitfalls.
  3. Terms like microservices, monolith and event-driven architecture surface before you even finish your sentence.
  4. Suddenly you’re knee-deep in technical jargon.

How on earth does a "Distributed Monolith" make adding a birthday to a simple screen so complicated?1 Understanding the fundamentals of distributed software architecture will help you ask the right questions, and actually follow the answers.

Why does this matter to you, as a Product Owner?

  1. Impact on Delivery: Software architecture can dramatically affect how quickly and reliably your team can deliver new features.
  2. Scalability and Maintenance: A complex system with lots of interdependencies can slow down development and lead to constant firefighting.
  3. Ownership and Coupling: Knowing who owns what, and how those parts interact, helps maintain clear accountability and reduces the risk of “finger-pointing” when problems arise.

Ownership: Who Controls What?

In an ideal world, each service in your architecture maps to a distinct business domain or Bounded Context2 and is owned by a single team. Ownership isn’t just about who “wrote the code”, it’s about ongoing maintenance, support, and strategic improvements.

Assuming development teams work closely with the business, by architecting around business capabilities we are conforming to Conway's Law.

Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations.

~  Melvin E. Conway, How Do Committees Invent?

Shared ownership sounds nice in theory, but too often it results in no one truly owning anything. This leads to slow decision-making and a high risk of knowledge gaps.

If everyone is responsible, no one is.

The “Too Many Services” Anti-Pattern

A common trap is splitting a single team’s work across too many services. In microservices architecture, people often assume each “feature” deserves its own service, which can balloon into dozens of services for one team. This fragmentation can lead to:

So while dividing your system into separate services can help, more is not always better. A balanced approach is to have as few services as needed to maintain clear boundaries and ownership without creating unnecessary complexity.

Coupling: The Hidden Cost of Dependencies

Tight Coupling

Tight coupling means changes in one part of the system often force changes in another.

For example, that simple request to show a user’s birthday requires you to:1

  1. Call Bingo to get the User Id.
  2. Call Papaya and MBS to turn the User Id into a User Session Token.
  3. Validate the User Session Token with LMNOP.
  4. Ask Wingman if the user is ready to take it to the next level.
  5. Wingman gets a time range between now and the end of the universe from EKS.
  6. Wingman asks Galactus what all the user info provider services are for that time range.
  7. Wingman reaches out the the user info providers like RGS, BRB-DLL, Ringo 2 and BLS to get the birthday of the user.
  8. Wingman returns the user's birthday.

When everything is chained together, a single issue can cascade and cause major outages. If a system needs to change, e.g. moving from EKS to Omega Star, it could block multiple teams from continuing with their work!

Loose Coupling

In loosely coupled systems, each service can stand on its own. Modifications to a single service don’t automatically break others, and teams can deploy updates independently.

This structure enhances:

Communication between services

A major driver of coupling is communication patterns:

sync-vs-async-communication

sync-vs-async-communication-failure

The Evolution of Software Architecture

Most applications begin as a Monolith, a single, self-contained system where all business logic resides in one codebase. Over time, as systems grow and new features are developed, someone will go:

bender-own-service-bj-and-hookers

At this point developers start splitting the monolith into smaller services. Congratulations, you know have a Distributed Architecture!. The first step is often a Distributed Monolith, different services that appear independent but remain tightly bound together. Eventually, in an ideal scenario, you reach a more Microservices-oriented approach, where services are truly independent and loosely coupled.

Why This Evolution Happens

But as we’ll see, where you draw those boundaries and how your services communicate decide the differences between seamless scaling and a distributed mess.

Monoliths: The Starting Point

A Monolith bundles everything, login, shipping, billing, product listings, etc. into one giant codebase and typically one deployment.

Pros:

Cons:

Most companies start here because it’s straightforward. Problems arise as the application, and the organization, grow.

Microservices: Freedom or a Maintenance Nightmare?

Microservices are small, independently deployable services that revolve around business capabilities and are loosely coupled. Each service owns its domain logic, data, and external interfaces.

Pros:

Cons:

loosely-coupled-microservices-failure-prevention

The Iceberg Principle

Your microservice’s API should be the tip of the iceberg, a simple interface that hides all the depth underneath. For example, a Create Shipment API call might do all the following internally:

All that logic remains inside the “Shipment” service. You keep the external interface lean, and the user doesn’t need to call five different microservices to get one action done.

If at any point you want to pull out one of these sub-systems into it's own service (e.g. creating an email sending service) you can do so without changing the external API.

Microservice-iceberg

The Distributed Monolith: A System That Pretends to Be Microservices

After outgrowing the monolith, the next logical step is splitting off parts of the application into separate services. But if those new services remain tightly coupled, you don’t really gain the benefits of microservices.

Symptoms of a Distributed Monolith

  1. Multiple Deployments, Single Point of Failure: Even though you deploy 10 different services, if one of them crashes, everything stops working.
  2. Cascading Failures: A seemingly small issue in the “Order Service” might trigger a meltdown in “User Profile,” “Notification,” and “Invoice” services.
  3. Excessive Cross-Service Calls: Retrieving basic data (like a user’s birthday) requires multiple network hops.

In many cases, a Distributed Monolith is actually worse than a single monolith. You have all the overhead of multiple services, but with none of the independence.

distributed-monolith-failure-cascade

Conclusion

Hopefully, this overview helps you navigate those technical discussions with more confidence. By recognizing how monoliths, distributed monoliths, and microservices differ, and why those differences matter, you’ll be better positioned to lead your team to scalable, maintainable success.

Further Reading & Listening

Footnotes

  1. If you don't get the reference, this video is a mandatory watch for anyone dealing with a distributed system landscape.

  2. See Martin Fowler’s description of Bounded Contexts for a deeper dive into how to define logical boundaries in complex systems.