Thinking through our changes with Design Documents
Customer Products is made up of multiple, autonomous teams. There are lots of advantages to our structure, but one disadvantage is that teams can find they are heading in different technical directions. In our write-up of our tech strategy, we said “We want to make it possible for tech leads to make architectural decisions that are consistent with other teams’ technical decisions, without imposing too much process on the decision-making.” and this post is about how we have done that.
Autonomous teams can diverge
FT.com is built mainly by a wonderful group called Customer Products. Customer Products comprises 13 teams that are essentially multi-disciplinary independent work units. They own a product or strategy area and design their roadmap based on the priorities and opportunities of their product or strategy.
These self-sufficient teams can think strategically about their domain when they have complete ownership of it. They not only maintain it and support it. They also innovate, experiment and iterate. And they do it efficiently because, most of the time, they don’t have external dependencies.
But the flip side of independence can be isolation. Without a way to share their future work, these autonomous teams could work on identical issues without knowing it, or could even make contradictory decisions. For example, not long ago, one team was moving away from a certain API because “it’s going to be deprecated”, while another team was actively pushing improvements. We learned that without constant and structured communication, teams would eventually find themselves moving in opposite directions or missing out on the learnings and experiences of others.
Recurrent cross-team meetings and showcases can help alleviate some of these pains. But we believe a more collaborative tool is needed. And that’s the purpose we found for Design Documents.
A living document
The main goal of a Design Document is to gather feedback before implementing a feature or change. It comes with other beneficial side effects too. By putting it in written words, the team is forced to think through their understanding of the problem and proposed design. Additionally, it can act as a historical record of decisions and provide a knowledge base for other teams working on similar work in the future.
Contrary to other types of technical documentation, we can expect a design document to be highly collaborative and spur conversations. Sections are to be edited, extended and even rewritten according to the feedback gathered and experiences shared.
The design document typically starts with one engineer creating a shareable document, usually a Google Doc or a Wiki page. This document doesn’t have to follow a specific structure, but we have a template that can give us a kickstart. Although ideally, it would include these sections:
Context and scope. It gives the reader an overview of the issue or opportunity and what will be built to address it. It adds bullet points with what’s in scope and, more importantly, what’s not.
Proposed design. It describes the solution, and it shouldn’t spare any details. We should aim for a world where we can write this, then take a vacation on some desert island, and another engineer on the team can just read it and implement the solution as you described¹. An architecture diagram is highly encouraged.
The next important part of this section is the trade-offs. Why does this particular design meet the requirements better than the alternative? It helps to describe the alternative options and their weak points.
Finally, it should describe the migration strategy to bring this change live. It should flag potential risks, their impact and how to mitigate them, if possible.
Details if it is an experiment The change might be a test designed to run on a fixed timeframe. In that case, this section describes the metrics we’ll use to consider it successful and the strategy to put it live indefinitely. We also include the decommissioning strategy in case it fails.
Ready to review
The next stage of the Design Document is the review. This process will look different depending on the nature of the change. If we are changing the platform on which FT.com is built, we would focus on getting feedback from Principal Engineers and Tech Leads. If it’s an experiment, then feedback from Product Managers, Designers, and engineers maintaining its dependencies is essential. We’ll share it on our channels, publicise it in meetings and raise it with the Delivery manager. We also expect this process when other groups propose changes to our stack to support their work.
Reviewers will have 1 or 2 weeks to go through it and add their opinions, questions and concerns. And from this point, conversations will start to flourish all over the document, accomplishing one of the side goals of a Design Document, which is to keep track of these conversations.
The engineers in charge of this project will consider the feedback and adapt the design to apply these new learnings. After we’re satisfied with the result and convinced that the design has been fortified with all the valuable experience from the group, we can start development.
But the life of the Design Document doesn’t end there. We should edit it with new learnings during the development phase. It’s also useful to review a design document before a product is launched to ensure that the stated goals when the design document was written remain the stated goals at launch². And even after the project is released, we should revisit it and use it to measure success, confirming that we met these goals or, otherwise, documenting why we didn’t.
One of many examples
Our teams have been profiting from using Design Documents for a while now but let’s single out one great example that summarises their benefits. Recently, our Reliability team was working on a new Node.js library to achieve error-handling consistency across the FT.com stack. While working on the design document, they came across two thoughts originally outside their work’s scope. The first one was about uncaught exceptions. Fatal errors were being handled by another package, which lacked active maintenance and had deprecated dependencies. A new module in the library would be created to cover this issue. The other one was about error-handling on non-Node.js apps. The library couldn’t run on those apps, but it could still provide a spec for other teams to follow and keep consistency across the stack. The Design Document served two of its main purposes here: challenge our understanding of the problem and make us think about how this works and interacts with other parts of the system.
Most decisions are small decisions
Some decisions aren’t big enough to go through the overhead of a Design Document, but we still want to keep a historical record of them. For these cases, teams have been using another type of document, the Decisions Document.
It’s essentially a simplified version of the Design Document, but it captures minor decisions that are often relevant only to the scope of a single team.
The benefits we get are the same as a full Design Document. Write down a decision to make, capture the preferred option, their trade-offs, and alternatives. Then review it, make a decision and keep it as a historical record. It won’t go through the scrutiny of a Design Document, but it’ll help us build our knowledge base and cover the smaller spots of information that the more formal Design Document doesn’t.
Design Documents helps us build sustainably
Design documents are a great tool to make work more visible across a multi-team group. They’re essential to achieve consensus on new features and enrich them with other teams’ experiences. They fit perfectly in the “no next next” strategy, because they allow us to continue building decoupled components but are designed to work in the real world, where assumptions and requirements change constantly.
A big thank you to Jennifer Shepherd, Rowan Manning and Anna Shipman for helping me write, edit and proof-read this blog post