Framework Thinking - System Design - Taro Product Spec

Here is template for answering System Design Interview.

1. Businsess Value

At a high-level, here’s how full playlist support can add value to the lives of Taro users and Taro overall:

  • Watch Later - Users will often find content in Taro and not have enough time to fully consume it. This is due to our live sessions being very long (>30 minutes), content on Taro being connected to many other pieces of content (user doesn’t have enough time to fully “traverse the graph”), and catching up on content recommendations in notifications that they’re interested in. With playlists, users can create a “Watch Later” playlist for themselves and tailor it as they please.

  • Grouping By Topic - The content in Taro is organized very basically via tags, which is high-level and not granular enough to be useful for many cases. Playlists allow users to organize content by topic at whatever granularity level they want - For example, if a user is an E4 at Meta, they can create a playlist like “Satisfying E5 People Axis Advice”.

  • More Editorial Curation - Right now, we only create playlists at Taro when we absolutely have to, shipping a course or the highlights from a Tech Career Growth session. It’s just too huge a pain for us to ship playlists that are more catered to user sub-groups like “Top 10 Advice For Senior To Staff”.

  • SEO - Playlists will give Google additional structured data to index and point to Taro. Since we can name playlists whatever we want, we can create playlists specifically dedicated to compete for important search terms.

2. Functional requirements

2.1. Use cases

  1. User is able to create and manage playlists
  • Custom name

  • Custom description

  • Add content to a playlist

  • Rearrange content within a playlist

  • Remove content from a playlist

  1. User is able to add a piece of Taro content into a playlist from its detail view
  • Video page

  • From Q&A thread

  1. User is able to see all their playlists
  • Have a section somewhere on their profile
  • At the top level for a playlist, they’re able to see its name, description, and the number of content it has within it

2.2. Edge cases

  1. User is able to create and manage playlists
  • Name is blank - Block it

  • Name is too long or very short (e.g. 1 character) - This feature is mainly single-player, so there’s not much harm allowing it.

  • Description is blank - While not as necessary as the name, let’s block it to simplify UI (don’t need to adjust paddings and view visibility if it’s empty)

  • Description is too long or very short - Allow it for the same reason as for the name.

  • No content within an existing playlist - Show an empty state with a call to action to add content to it.

  • Playlist has a ton of content (100+) - Android has view recycling built in, so this isn’t a problem, but iOS doesn’t. To be safe, we could add pagination on iOS, but it’s not likely for the user to create a

  • Playlist so long that it causes scroll perf issues for them.

  1. User is able to add a piece of Taro content into a playlist from its detail view
  • No existing playlists when “Add to playlist” button is clicked - Show a modal letting the user know about this and include a call to action to make a playlist.

  • The content is already in a playlist - For simplicity’s sake, just allow duplicates in v1. The user will eventually tap into the playlist and correct it if they want to.

  1. User is able to see all their playlists
  • User has no playlists - Show an empty state with a call to action to create the playlist.

3. Non-functional requirements

4. High level Design

4.1. Diagram

4.2. Data Model

Playlist

  • We have a read-only version of playlists right now, so we already have a model.

  • The collection is called “playlists”.

  1. Fields: All fields are required.
id (String) - Unique ID and primary key of the playlist in Firebases semi-UUID style
creatorUserId (String) - ID of the user who created the playlist
name (String) - The name of the playlist, shown in a title style
description (String) - Gives more information about the playlist as a subtitle alongside the name
createdAt (Long) - UNIX time (in seconds) when the playlist was created
lessonIds (Array<String>) - A list of the content IDs this playlist contains. Order must be respected
  1. Example
  {
    "id": "firebaseIdHere",
    “creatorUserId”: “firebaseUserIdHere”,
    "name": "Alex’s Guide To Effective Communication”,
    "description": "If you haven’t watched this series, what are you doing?”,
    “createdAt”: 1669851822,
    "lessonIds": [
        video_124_id,
        video_22_id,
        question_22_id,
        video_8_id,
        question_33_id
    ]
  }
  1. Overall Approach
  • The goal is to keep things as simple as possible due to there being no back-end to abstract away complex logic.

  • The playlist model will act as a single source of truth, so there’s no data duplication.

  • Unfortunately, this means that we need query connections on the client as the model is shallow.

4.3. Feature: Pros and Cons

Since we have the “creatorUserId” field on each playlist, we can query against that to get all of a user’s playlists. There is no need to alter the “user” model.

  1. Trade-offs
  • The primary alternative is to have a “deep” data model where the playlist contains everything needed to render itself. Here’s what that would look like:
{
	// All other playlist fields
"lessons": [
	{
		id: “video_id_1,
		videoUrl: coolurl.com
		numViews: 5
	},
	{
		id: “video_id_1,
		videoUrl: coolurl.com
		numViews: 10
	}.
	 // More lessons here
]
}
  1. Pros
  • Don’t need to worry about backporting as we’re simply using the existing model

  • No back-end needed as playlist model is single source of truth that doesn’t require model duplication and syncing

  • Minimal data model and mutations - If we were to include the lesson model on the playlist, we would need to update them whenever the lesson gets updated. This is actually quite often due to liking and views.

  1. Cons
  • The client is “smarter” as it needs to do subsequent queries to fully render a playlist, breaking the design principle of “dumb client, smart server”.

  • Performance concerns loading the playlist detail view (unless we do some sort of pre-fetch beforehand). This can be a problem with playlists with tons of content in them.

4.4. Choose technology

4.5. Sequence Diagram (Edge cases)

5. Bottlenecks and Break

For the most part, this feature is pretty safe as it’s primarily single-player. We have already covered smaller edge cases like overly long playlist names in their appropriate section, this section is for how things can really break (equivalent of a SEV at Meta and other Big Tech companies). Think of events that would really hurt the user experience for a huge swath of users and damage Taro’s reputation.

  1. User edits or deletes another user’s playlist
  • Since playlists are sharable, this is something we need to look out for. Users can already look at another user’s playlists as we have public playlists on behalf of the Taro team.
  • We need to make extra sure that the owner ID of a playlist matches the ID of the current user before exposing the edit button.
  • If we wanted to go really deep, we could add a Firestore rule protecting write permissions or create an endpoint that abstracts away the editing, so that even if the UI messes up, the endpoint would fail.
  1. Offensive and vulgar material in a playlist
  • The blast radius here is pretty small as we are not making playlists publicly indexed, at least not in v1. Shared playlists will either be by official playlists from Taro or friends sharing with one another.
  • The potential for harm is further reduced as the freeform customizable components are the playlist name and description, which are just text. Users cannot add their own audio, images, or video.
  1. Playlist mutations affect the underlying content in Taro
  • Imagine someone removing a Taro video from their custom playlist, and there’s some side effect where that video is deleted from the platform altogether.
  • This is incredibly unlikely due to the shallow data model - Playlists don’t contain the Taro content data model directly, just the ID.
  • A proper broad protection against this is having Firestore rules around deletion for the core Taro content model or moving all deletion to an endpoint that checks to see if the acting user is an employee.
  1. Old Mobile Builds Are Incompatible
  • Since the older builds already have read-only support, it’s hard to imagine a scenario where this breaks. If this were all new (i.e. the playlist unit is created as a part of this project), we would have risk through older builds getting shared links to playlists or getting push notifications for them, but it’s not so we should be safe.

6. Potential Future Improvements

These will be ordered in terms of likelihood/priority descending (i.e. iterations we are most likely to do come first).

  1. Allow users to clone playlists of others
  • The use case is that someone goes through someone else’s playlist, isn’t able to finish it, and wants to save it to go through later. This is a common potential use-case with official Taro playlists.
  1. Automatically “seed” a “Watch Later” playlist for every user
  • This is what YouTube does and would be a nice quality of life improvement. The data cost is relatively cheap as it’s only one per user.
  1. Make playlists publicly show up within the Taro ecosystem
  • The idea is to turn them into another type of Taro content, complete with views and likes. They would surface in places like search and maybe even have their own tab. However, unlike the above, this feature has a lot of complexity as it’s a multiplayer feature, not single player - We would need to think about features like a user “opting in” their playlist to be part of this ecosystem. The data model would almost certainly have to change as well.
November 11, 2025