Composition for teams

Written on //3-minute read

A tension in software engineering which has always fascinated me is knowing when to break one into many. One of the approaches for solving such situations is composition.

Software engineering organisations also benefit from composition by transforming one big and complex team into smaller and simpler teams. A common way to apply composition to software orgs is applying the platform/application pattern: a "platform team" responsible for generalising shared behaviours across a product's use-cases, and "application teams", focusing on the specifics of use-cases.

Defining clear responsibilities for application teams helps defining what a platform could be, if you even need one. Some of the following principles have helped me in the past.

Application teams should own the nuances of use-cases. Given that a platform's role is serving multiple use-cases, they are usually excellent at solving objective problems. For example, in a payments processing platform, when to authorise a card and charge a customer, when to retry a payment, when and how often to settle funds, the best day of the month to recur a payment, are all application team responsibilities.

Application teams should have influence over optimisation. Platforms are great at solving the bulk of shared problems, although some of the most challenging optimisation work, especially for platforms with dozens of use-cases, is at the context-level. Think for example of a platform responsible for cross-selling recommendations. The context whereby a recommendation is made is hugely relevant for it to be effective, e.g. a recommendation in a product listing page, with low purchase intent vs a pre-payment or upsell recommendation.

Whilst platforms can provide table-stakes for optimisation, all the tuning, calibration and meaning of success needs to be considerate of the context. In general, application teams are in a better position to provide signal for optimisation.

Infrastructure is the product of a platform team. When a platform team can't control all downstream consequences of different failure modes, they need to have much stricter SLAs, incident management processes, and business continuity practices. For example, a 99% availability requirement might be acceptable for a payments platform with an average ticket of $10 @ 500k transactions per day – meaning a loss of ~$3.5k per hour. Nevertheless, if the average ticket is on the thousands, that could mean different availability requirements.

Being in a platform team demands a shift into thinking that infrastructure is the product.

Make the platform assumptions explicit. Application teams should be aware of where the platform draws its boundary and platform teams should be explicit about those boundaries.

Generally speaking, I recommend my teams to be conservative of where to draw the platform's domain boundary and start with the smallest value possible. For instance, a product recommendations platform can start with an API that returns probability scores for multiple recommendation types – buy again, also bought, etc – rather than dealing with product ranking, which is a much more complex and nuanced problem.

Think of the platform a a collection of capabilities rather than a one-stop-shop. A way platforms commonly fail is by trying to package all capabilities together rather than providing application teams with a set of interoperable capabilities which they can use as needed. Even though it can be quite convenient to abstract all complexity behind a single API, when application teams don't have access to independent capabilities, they are incentivised to "go around the platform".

Instead, breaking logical domains into building blocks can give tenants the ability to extend functionality. Kislay Verma's post about preventing "go-around" with platform thinking explains the problem and solution very well.

Do not lose sight of the end-user. This is particularly easy in platform teams, where you are at least two degrees away of the user, as an application team is always in between you and them.

Working very closely with user experience researchers are a way to go about it. If you don't have user researchers, another way to close the gap is by treating the application team as your customer rather than just a stakeholder. By understanding their motivations you will understand the user's motivations.