The subtle art of writing a high level design doc!

 


     In my small career, I have been very fortunate to have received a lot of opportunities to write an HLD (High-level design) and many other forms of documents (LLD, one-pagers, deployment docs etc). At first, most of the engineers (particularly entry-level) either do not like doing this (it looks like documentation!) or do it just for the sake of it. It turns out to be a big blunder and teams end up wasting a lot of time doing back and forth with the stakeholders or the code reviewers. In this article, I will try to cover whatever (little) I have learned and follow when I write an HLD for our team. Trust me, it is a skill which can be best learnt by doing and getting it reviewed and grilled by senior leaders and engineers. Still, I will try to give a nice crisp overview of the whole thing. 

     Let's begin with the reason why you need an HLD in the first place? Of course, I am an engineer and I know what we want to build I have built similar things in the past. It will take a lot of time as well. I do not need it! Turns out, you still probably need it for the following reasons : 

  1. It will help you figure out various components you would need in the project and will help you break down your larger problem into smaller subproblems.
  2. It will help you get an "alignment" between various stakeholders like the product team, internal customers, management, higher engineering leads and your own team. Also, this document will serve as a written record of how the project started and will contain everyone's approvals to avoid problems later.
  3. It will help you understand the trade-offs (let's accept it, all solutions you propose have to come with trade-offs be it in terms of capabilities, scale or cost) and make the best and the most informed choice.
  4. It will help you come up with high-level timelines and when a leader asks when it will be completed, you can give better estimates with valid and written backing of what is complete and what is left. You may also agree on the release plan better.
  5. It helps you streamline your thoughts and your team's thought in a particular direction and the chances of misunderstandings and single points of failure (let's say you fall sick, your document will continue to guide the team) is reduced drastically. 
  6. It helps you call out what is "in the scope" and what is not. It sets the right "expectations" with the stakeholders. This is important as you do not want people coming out later saying they were "expecting" something in this release that they do not see and because of this business is going to suffer.
     There are a lot of other reasons why one should write an HLD. But can we avoid writing an HLD in some cases? The answer is yes! If your project is low impact or internal to your team or not involve stakeholders/cross teams/customers or is just a simple script or bug fix you may skip the HLD but still, if you have some time, at least do come up with a one-pager in these cases as well. Documentation of the process is great to have!
     Now, let us see a typical format of an HLD. I have always been a supporter of developer creativity (as long as the relevant and mandatory things are not compromised!) and each HLD is a masterpiece that the artist (the SDE!) creates for a particular set of audience. Hence each HLD is different but here I will try to show a small highlight of what a typical software HLD looks like usually.
  1. Title: It should summarize the whole project in one line. It is generally the same as the project name. Does not need much explanation but it should be one line and conveying the idea of the project.
  2. Stakeholders List:  The list of stakeholders and their PoCs (Point of contact) along with their designations. This section should also include a column for approval. For example : 
  3. References: This should include all the jargon, abbreviations, references, links etc needed for a complete understanding of the doc and the context.
  4. Background: The background of the project including what is the current scenario and what is the desired scenario. It should also include what is the business necessity and impact of the project in the short, medium and long term.
  5. Functional Requirements: The list of "direct" requirements which need to be verified before calling the project a success. The requirements should be quantifiable wherever possible and monitorable via some metrics. All the stakeholders should be aligned with these.
  6. Non-Functional Requirements: The list of "indirect" requirements like latency, availability, consistency etc. These requirements should also be quantifiable via metrics whenever possible like P95, P99 metrics etc.
  7. Scope: What is not a part of the project should be clearly called out so that we know what we are not aiming for. 
  8. Approaches: Propose various approaches. Each approach should be backed by a proper pros and cons analysis with the tradeoffs clearly mentioned for the approach. Each approach should have an HLD diagram to explain the plan at the component level. Optionally, it can also contain a flow diagram. An example of the component diagram and data flow diagram may be as follows :


  9. Finalized approach: The approach that was finalized by all the stakeholders after meetings and discussions. This should be a detailed segment and we should add tradeoffs, a detailed HLD diagram, data models, a deployment plan at a high level etc. It should indicate what is the reusability, modularity, security etc of the system. It should also contain database designs and ER models if needed.
  10. Risk/Dependencies/Assumptions: Note down which all down stream services, teams your work and timelines depend on. Also, list down the assumptions that you have made while designing the document so that people are aware of what all cases need to be resolved before the document can be fully executed.
  11. T-shirt sizing: Once the approach is finalized, we can come up with a T-shirt size estimate for the various component's delivery. The T-shirt size is usually taken as S (small - Around half a sprint effort), M (Medium - Around a sprint worth of task), L (Large - Around two sprints of task), XL (Extra large - Around 2-3 sprints with many engineers working). An example could be something like this :

  12. Appendix: This should contain future reads and other things that we were unable to fit anywhere else. This might also include historical data that were considered when the design was created.
     This is what a typical HLD document should usually mandatorily have. A lot can be added based on the complexity of the project and its impact. It can be made far more complex and detailed or simplified a bit based on the team, company, requirement, audience, impact etc. Also, the template depends from company to company based on their practices. But more or less this is what is almost always looked for in a HLD. Making the stakeholders agree on the HLD is a separate issue which usually spans multiple cross-team meetings (depending on your communication and presentation skills and how well the 1st draft of the HLD is created). You can read more and find more templates for HLD here:
  1. https://cmps-people.ok.ubc.ca/rlawrenc/research/Students/CJ_05_Design.pdf
  2. https://www.slideshare.net/anoshajamshed/high-level-design-document-template
     I am still learning things and exploring the best practices. Any comments or feedback would be really welcome! Happy reading!

-Amrit Raj

Comments