You can find the full system design doc here - Feel free to use it as a template for when you're designing systems at your job!
The tactics are covered in the doc linked above, so this summary will focus on the "meta" context behind this part and additional commentary:
- When it comes to determining your overall approach, it's important to understand the priorities and values of your team/company. You can't have it all when building software; when you invest more in a certain attribute, it will generally take away from others. Here are some example attributes:
- Execution speed
- Feature robustness
- Code readability
- System scalability
- Design and aesthetic
- Taro and very early-stage startups in general will make warped decisions as the prioritization leans extremely heavily towards execution speed. The goal is to 80/20 as much as possible when it comes to all the other attributes surrounding quality.
- Since this case study is a pretty basic CRUD play building on top of an existing model, there isn't too much complexity around the approach. However, you generally want to propose 2+ concrete approaches and the tradeoffs behind them, especially at a Big Tech company where you often have many, many options.
- Here are the technical design principles covered in the video:
- Single source of truth: This is a very easy way to systems to break and have inconsistent experiences. Let's say your content object has 2 fields, a boolean of "hasLikes" and then an array of users who have liked this particular piece of content. You can either check the emptiness of the array to see if the object has likes or consult the boolean. It's extra work maintaining these 2 different representations of this information, and if they fall out of sync and 2 services/surfaces each read from a different one, things will get weird.
- Smart server, dumb client: You cannot scale the user's device unless you ship them a new computer or phone. However, you can theoretically infinitely scale your server-side. This is why clients (i.e. usually front-ends) should be as dumb as possible with the back-end abstracting away as much complex logic as possible. This is especially true when your product is a mobile app as there will always be users lagging on older versions of the app - You don't want to have to make a mobile update every time you have a basic product logic change. Make your back-end protocol generic, flexible, and powerful.
- Be additive with data model: This is primarily relevant with mobile apps as you will have users on older builds. If you change or remove a field, older builds will break. You can't count on your users to all update to the latest version of your app immediately.