---
type: "article"
title: "Stream-aligned teams providing an API isn't a XaaS"
summary: "Combining Team Topologies and Domain-Driven Design Context Maps"
newsletter: "Engineering Strategy"
newsletter_handle: "engineeringstrategy"
newsletter_url: "https://usecommune.com/n/engineeringstrategy"
author: "Aleix Morgadas (@aleixmorgadas)"
published: "2024-12-01T11:23:43.000Z"
canonical_url: "https://usecommune.com/n/engineeringstrategy/a/stream-aligned-teams-providing-an-api-isn-t-a-xaas-2"
markdown_url: "https://usecommune.com/n/engineeringstrategy/a/stream-aligned-teams-providing-an-api-isn-t-a-xaas-2.md"
chat_url: "https://usecommune.com/n/engineeringstrategy/a/stream-aligned-teams-providing-an-api-isn-t-a-xaas-2/chat"
source_url: "https://learnings.aleixmorgadas.dev/p/stream-aligned-teams-providing-an"
body_source: "imported"
likes: 0
replies: 0
body_words: 1547
---

# Stream-aligned teams providing an API isn't a XaaS

I had a great conversation at [Global Domain-Driven Day 2024](https://virtualddd.com/open-space/global-domain-driven-days-2024/) at VirtualDDD with a topic proposed by [Kenny Baas-Schwegler](https://bsky.app/profile/kenny.weave-it.org) during the Open Space.

The topic was in the lines of:

> *Can a Stream-Aligned Team provide a XaaS for other teams?*

Using Team Topologies nomenclature, it refers to:

[![](https://substackcdn.com/image/fetch/$s_!_QR8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bc6f9e7-3f59-40dd-8d69-3139e12b8c92_706x418.png)](https://substackcdn.com/image/fetch/$s_!_QR8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bc6f9e7-3f59-40dd-8d69-3139e12b8c92_706x418.png)

Even though in the book it is discouraged, sometime ago I wrote about when it made sense based on my experience. I leave here the post on how a stream aligned team allowed the evolution for a platform team.

The good thing about the open space is that everyone was encouraged to speak and great arguments occurred, in favor and against of. Yet, as we all shared, it all depends.

# Introducing the context

[![Two stream aligned teams. Team 1 with capability A serving user Alice. Team 2 with capability B serving user Bob](https://substackcdn.com/image/fetch/$s_!r-Tl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1454812-70f0-4286-97b3-92bd970e64a4_2546x1400.png "Two stream aligned teams. Team 1 with capability A serving user Alice. Team 2 with capability B serving user Bob")](https://substackcdn.com/image/fetch/$s_!r-Tl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1454812-70f0-4286-97b3-92bd970e64a4_2546x1400.png)

We have two stream-aligned teams:

- `Team 1` with `Capability A` serving user `Alice`.
- `Team 2` with `Capability B` serving user `Bob`.

Then, as business as usual, a ` Team 1  `detects a new user need for `Alice` that involves `Capability B`.

Let’s explore several scenarios with their consequences.

1. Reusing the capability
2. Stream-Aligned Team providing a XaaS
3. Moving the capability to a platform team.

# 1. Reusing the capability

[![Two stream aligned teams. Team 1 with capability A serving user Alice. Team 2 with capability B serving user Bob. Capability A is connected to Capability B](https://substackcdn.com/image/fetch/$s_!0_KF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb8af773-51f6-4330-a0d7-6992f7368cdb_2543x1400.png "Two stream aligned teams. Team 1 with capability A serving user Alice. Team 2 with capability B serving user Bob. Capability A is connected to Capability B")](https://substackcdn.com/image/fetch/$s_!0_KF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb8af773-51f6-4330-a0d7-6992f7368cdb_2543x1400.png)

We have Team 2 that exposes the `Capability B` though an API already. Team 1 checked the API, and it suits the Alice’s needs.

So, they integrate `Capability A` with `Capability B`, they do all the tech best practices such as use case integration tests, and adding monitoring to be the integration works. They even add an [Anti-Corruption Layer](https://github.com/ddd-crew/context-mapping?tab=readme-ov-file#anticorruption-layer) just in case.

[![Two stream aligned teams. Team 1 with capability A serving user Alice. Team 2 with capability B serving user Bob. Capability A is connected to Capability B. Capability A has an anti-corruption layer and it is downstream to capability B, as upstream.](https://substackcdn.com/image/fetch/$s_!Ci5-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9933192b-15ed-483d-8a0b-481329aa68e5_2544x1400.png "Two stream aligned teams. Team 1 with capability A serving user Alice. Team 2 with capability B serving user Bob. Capability A is connected to Capability B. Capability A has an anti-corruption layer and it is downstream to capability B, as upstream.")](https://substackcdn.com/image/fetch/$s_!Ci5-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9933192b-15ed-483d-8a0b-481329aa68e5_2544x1400.png)

All of a sudden, `Team 2` is upstream to `Team 1` **without**`Team 2`**knowing**. Any change on `Capability B` will influence `Team 1` even though they added an `ACL`.

So now, `Capability B` serves `Alice’`s and `Bob’`s needs. It has two potential points of change, and multiple problems can occur down the road.

A common scenario could be that Alice is an enterprise customer requiring specific features. Those become prioritized, and now `Team 1` has influence over ` Team 2  `roadmap to include certain features they require from `Capability B`.

[![](https://substackcdn.com/image/fetch/$s_!ThXS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a621241-5461-4b1d-a946-66894e8f6db9_2541x1400.png)](https://substackcdn.com/image/fetch/$s_!ThXS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a621241-5461-4b1d-a946-66894e8f6db9_2541x1400.png)

Team 2 finds itself in a situation that:

- Serves`  Bob’s  `and `Alice’s` needs, directly and indirectly.
- Cannot evolve `Capability B` to serve `Bob`’s needs without being sure it doesn’t break `Capability A` integration.
- Needs to adapt to changes required by `Team 1`.
- Or, Team 1 needs to constantly adapt to the changes of Team 2, slowing down their development to serve Alice’s needs.

## A better approach

[![Two stream aligned teams. Team 1 with capability A serving user Alice. Team 2 with capability B serving user Bob. A collaboration between the two teams is explicit to investigate the reusage of the capability B.](https://substackcdn.com/image/fetch/$s_!r99q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9840c3fa-91c2-4ab2-bbbf-bf1bad0c4a0c_2544x1400.png "Two stream aligned teams. Team 1 with capability A serving user Alice. Team 2 with capability B serving user Bob. A collaboration between the two teams is explicit to investigate the reusage of the capability B.")](https://substackcdn.com/image/fetch/$s_!r99q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9840c3fa-91c2-4ab2-bbbf-bf1bad0c4a0c_2544x1400.png)

Instead of integrating directly, a collaboration between both teams is a better approach to determine is better.

1. Integrating both capabilities, and defining the collaboration expectations when both capabilities need to evolve. Such as SLAs, and alike.
2. Team 1 creating its own capability, adopting a [separate ways](https://github.com/ddd-crew/context-mapping?tab=readme-ov-file#separate-ways) approach. A small duplication can save us hours of coordination.

[![Previous text as an image.](https://substackcdn.com/image/fetch/$s_!QrN7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ffd4c84-22c1-466c-9c25-a7a2235a4906_5709x3381.png "Previous text as an image.")](https://substackcdn.com/image/fetch/$s_!QrN7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ffd4c84-22c1-466c-9c25-a7a2235a4906_5709x3381.png)

# 2. Stream-Aligned Team providing a XaaS

[![](https://substackcdn.com/image/fetch/$s_!eIfU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5f7604b-428f-469e-8b6b-b41c9f98a641_5567x1540.png)](https://substackcdn.com/image/fetch/$s_!eIfU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5f7604b-428f-469e-8b6b-b41c9f98a641_5567x1540.png)

If we find that Team 2 is in constant collaboration with Team 1, making Capability B suitable for more users than Bob, why not providing Capability as XaaS?

I think we need to be very careful on these scenarios because we will lose focus and purpose for what’s Team 2 mission. Team 2 will need to serve at least two users, Bob and Internal Teams like Team 1. Both with different needs, timings, and SLAs.

Stream-aligned teams are meant for fast flow with reasonable cognitive load. Aiming to serve their Capabilities as a Service will incur into higher cognitive load, and you need to be sure they have the right skills to make it happen.

Another risk is aiming to make Capability B too generic and too big, instead of adopting a thin platform approach. Becoming a bottleneck for innovation for customers like Bob, and slowing down other teams as well.

I would only recommend this approach when the use cases are limited, and the team skills and maturity are high enough that it will not heavily increase the team cognitive load.

Serving internal customers have something that external customers don’t provide. **Sense of control**.

You can have a faster feedback loop internally, and look like you are doing progress. Be careful because it is a **false** sense of control, and you are forgetting the most critical point, external customers.

So, you might find yourself finding more joy creating an internal platform rather than focusing on what’s crucial for the business. So, if you adopt this approach, continue with caution.

# 3. Moving the capability to a platform team

[![](https://substackcdn.com/image/fetch/$s_!Tsww!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45b5eb7d-45a4-4c90-9ea9-607917b42779_2546x2227.png)](https://substackcdn.com/image/fetch/$s_!Tsww!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45b5eb7d-45a4-4c90-9ea9-607917b42779_2546x2227.png)

The previous approach of a Steam-aligned team having its own external customers plus internal customers, like Team 1, moved the conversation into Platform Teams.

Even though it might look like a good approach from a Team Topologies perspective, it raised several concerns into the audience.

1. It seems like we moved a systems’ problem into a team problem.
2. Moving a *shared capability B* into a Platform Team and expose it as a service will not fix the issue by itself, because previous problems noted still applies into this scenario.

I think here we missed a key expectation of how Platform Teams need to behave from a Team Topologies perspective:

- Adopting the Platform is **optional** by teams. Allowing [separate ways](https://www.teamperature.com/product/drivers) in case the platform doesn’t have a good UX or doesn’t serve the initial team needs.
- [Thinnest Viable Platform](https://github.com/TeamTopologies/Thinnest-Viable-Platform-examples) over big platforms that solves everything.
- Platform teams need to reduce [team cognitive load](https://www.teamperature.com/product/drivers) of their consumers, not increase it, either by XaaS complexity or coordination complexity.

Therefore, I think some concerns of this approach comes from the misunderstanding of Platform Team mission and expected behavior. Which, based on current industry trend, it makes sense to be concerned about *platform everything* as a means to solve our problems.

[![](https://substackcdn.com/image/fetch/$s_!VEAQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4cb504e-1c70-49a4-b7f3-697184f3bf74_2543x2069.png)](https://substackcdn.com/image/fetch/$s_!VEAQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4cb504e-1c70-49a4-b7f3-697184f3bf74_2543x2069.png)

Therefore, we can find some capability duplication here and there, but a platform team can provide a good experience for certain use cases that have higher complexity, cause team cognitive load, and prevent fast flow of value.

# Recap

- Do not integrate with other team’s capabilities without a conversation.
- Integrating reduces some initial apparent cost of development, but it can create an increased cost down the road.
- Providing a good capability experience to be consumed isn’t free, and it takes time.
- XaaS can a collaboration approach between Stream-Aligned Teams in certain situations, but always being sure that:

  - It doesn’t exceed teams’ cognitive load.
  - It doesn’t reduce fast flow of value for the external customers in favor of internal customers.
- Investing in a Platform Team doesn’t mean the platform in mandatory use, nor it will solve all the problems. You still need to collaborate with teams to understand their needs.
- A platform doesn’t need to cover all teams needs, only a thin part of the main use cases to make a good thin platform instead of a sh\*ty big platform that does everything but nothing good enough.

***

Thank you a lot for reading this post 😄.

I love to read your feedback and opinions to help me improve. You can DM at my [LinkedIn](https://www.linkedin.com/in/aleixmorgadas/), [Bluesky](https://bsky.app/profile/aleixmorgadas.dev), or just leave a comment using the following links:

- [😍 Awesome](https://tally.so/r/w4krVo?rating=Awesome&url=sat-xaas)
- [😐 Okey](https://tally.so/r/w4krVo?rating=Okey&url=sat-xaas)
- [😨 Bad](https://tally.so/r/w4krVo?rating=Bad&url=sat-xaas)

# Update

[![](https://substackcdn.com/image/fetch/$s_!0giP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe61084bb-9e5b-45bb-82eb-2975d9fa5671_1087x1590.png)](https://bsky.app/profile/aleixmorgadas.dev/post/3lcclhkeztk2phttps://bsky.app/profile/aleixmorgadas.dev/post/3lcclhkeztk2p)

A nice thread happened on Bluesky about different approaches, and there was a great question on how that would look like in a Data Mesh.

I tried to expose how it could look like in terms of Flow of Change, but Data Mesh isn’t my area of experience. I haven’t been exposed to enough scenarios to make an informed call.

How do you see Data Mesh, and how can you describe flow of value using Team Topologies?

***

## Discussion

No replies yet.
