<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Karan Pratap Singh</title>
    <description>The latest articles on Forem by Karan Pratap Singh (@karanpratapsingh).</description>
    <link>https://forem.com/karanpratapsingh</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F350819%2F371eca60-9d4d-4caa-9d8d-1c5e85dfcb92.jpg</url>
      <title>Forem: Karan Pratap Singh</title>
      <link>https://forem.com/karanpratapsingh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/karanpratapsingh"/>
    <language>en</language>
    <item>
      <title>System Design: Uber</title>
      <dc:creator>Karan Pratap Singh</dc:creator>
      <pubDate>Thu, 22 Sep 2022 02:51:38 +0000</pubDate>
      <link>https://forem.com/karanpratapsingh/system-design-uber-56b1</link>
      <guid>https://forem.com/karanpratapsingh/system-design-uber-56b1</guid>
      <description>&lt;p&gt;Let's design an &lt;a href="https://uber.com" rel="noopener noreferrer"&gt;Uber&lt;/a&gt; like ride-hailing service, similar to services like &lt;a href="https://www.lyft.com" rel="noopener noreferrer"&gt;Lyft&lt;/a&gt;, &lt;a href="https://www.olacabs.com" rel="noopener noreferrer"&gt;OLA Cabs&lt;/a&gt;, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Uber?
&lt;/h2&gt;

&lt;p&gt;Uber is a mobility service provider, allowing users to book rides and a driver to transport them in a way similar to a taxi. It is available on the web and mobile platforms such as Android and iOS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;p&gt;Our system should meet the following requirements:&lt;/p&gt;

&lt;h3&gt;
  
  
  Functional requirements
&lt;/h3&gt;

&lt;p&gt;We will design our system for two types of users: Customers and Drivers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Customers&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Customers should be able to see all the cabs in the vicinity with an ETA and pricing information.&lt;/li&gt;
&lt;li&gt;Customers should be able to book a cab to a destination.&lt;/li&gt;
&lt;li&gt;Customers should be able to see the location of the driver.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Drivers&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Drivers should be able to accept or deny the customer requested ride.&lt;/li&gt;
&lt;li&gt;Once a driver accepts the ride, they should see the pickup location of the customer.&lt;/li&gt;
&lt;li&gt;Drivers should be able to mark the trip as complete on reaching the destination.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Non-Functional requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;High reliability.&lt;/li&gt;
&lt;li&gt;High availability with minimal latency.&lt;/li&gt;
&lt;li&gt;The system should be scalable and efficient.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extended requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Customers can rate the trip after it's completed.&lt;/li&gt;
&lt;li&gt;Payment processing.&lt;/li&gt;
&lt;li&gt;Metrics and analytics.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Estimation and Constraints
&lt;/h2&gt;

&lt;p&gt;Let's start with the estimation and constraints.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Make sure to check any scale or traffic-related assumptions with your interviewer.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Traffic
&lt;/h3&gt;

&lt;p&gt;Let us assume we have 100 million daily active users (DAU) with 1 million drivers and on average our platform enables 10 million rides daily.&lt;/p&gt;

&lt;p&gt;If on average each user performs 10 actions (such as request a check available rides, fares, book rides, etc.) we will have to handle 1 billion requests daily.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;100 million×10 actions=1 billion/day
100 \space million \times 10 \space actions = 1 \space billion/day
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;mi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;10&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;c&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;bi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;strong&gt;What would be Requests Per Second (RPS) for our system?&lt;/strong&gt;

&lt;p&gt;1 billion requests per day translate into 12K requests per second.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;1 billion(24 hrs×3600 seconds)=∼12K requests/second
\frac{1 \space billion}{(24 \space hrs \times 3600 \space seconds)} = \sim 12K \space requests/second
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;24&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;h&lt;/span&gt;&lt;span class="mord mathnormal"&gt;rs&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3600&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;bi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;12&lt;/span&gt;&lt;span class="mord mathnormal"&gt;K&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;re&lt;/span&gt;&lt;span class="mord mathnormal"&gt;q&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mord mathnormal"&gt;es&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
### Storage

&lt;p&gt;If we assume each message on average is 400 bytes, we will require about 400 GB of database storage every day.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;1 billion×400 bytes=∼400 GB/day
1 \space billion \times 400 \space bytes = \sim 400 \space GB/day
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;bi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;400&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;es&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;400&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;GB&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
And for 10 years, we will require about 1.4 PB of storage.


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;400 GB×10 years×365 days=∼1.4 PB
400 \space GB \times 10 \space years \times 365 \space days = \sim 1.4 \space PB
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;400&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;GB&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;10&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;ye&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;rs&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;365&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ys&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1.4&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;PB&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
### Bandwidth

&lt;p&gt;As our system is handling 400 GB of ingress every day, we will a require minimum bandwidth of around 4 MB per second.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;400 GB(24 hrs×3600 seconds)=∼5 MB/second
\frac{400 \space GB}{(24 \space hrs \times 3600 \space seconds)} = \sim 5 \space MB/second
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;24&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;h&lt;/span&gt;&lt;span class="mord mathnormal"&gt;rs&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3600&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;400&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;GB&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;5&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;MB&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
### High-level estimate

&lt;p&gt;Here is our high-level estimate:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Estimate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Daily active users (DAU)&lt;/td&gt;
&lt;td&gt;100 million&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Requests per second (RPS)&lt;/td&gt;
&lt;td&gt;12K/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage (per day)&lt;/td&gt;
&lt;td&gt;~400 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage (10 years)&lt;/td&gt;
&lt;td&gt;~1.4 PB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bandwidth&lt;/td&gt;
&lt;td&gt;~5 MB/s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Data model design
&lt;/h2&gt;

&lt;p&gt;This is the general data model which reflects our requirements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fha52hcwh80wtowzdc4ci.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fha52hcwh80wtowzdc4ci.png" alt="uber-datamodel" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have the following tables:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;customers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This table will contain a customer's information such as &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;, and other details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;drivers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This table will contain a driver's information such as &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;, &lt;code&gt;dob&lt;/code&gt; and other details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;trips&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This table represents the trip taken by the customer and stores data such as &lt;code&gt;source&lt;/code&gt;, &lt;code&gt;destination&lt;/code&gt;, and &lt;code&gt;status&lt;/code&gt; of the trip.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;cabs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This table stores data such as the registration number, and type (like Uber Go, Uber XL, etc.) of the cab that the driver will be driving.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ratings&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As the name suggests, this table stores the &lt;code&gt;rating&lt;/code&gt; and &lt;code&gt;feedback&lt;/code&gt; for the trip.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;payments&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The payments table contains the payment-related data with the corresponding &lt;code&gt;tripID&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  What kind of database should we use?
&lt;/h3&gt;

&lt;p&gt;While our data model seems quite relational, we don't necessarily need to store everything in a single database, as this can limit our scalability and quickly become a bottleneck.&lt;/p&gt;

&lt;p&gt;We will split the data between different services each having ownership over a particular table. Then we can use a relational database such as &lt;a href="https://www.postgresql.org" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt; or a distributed NoSQL database such as &lt;a href="https://cassandra.apache.org/_/index.html" rel="noopener noreferrer"&gt;Apache Cassandra&lt;/a&gt; for our use case.&lt;/p&gt;
&lt;h2&gt;
  
  
  API design
&lt;/h2&gt;

&lt;p&gt;Let us do a basic API design for our services:&lt;/p&gt;
&lt;h3&gt;
  
  
  Request a Ride
&lt;/h3&gt;

&lt;p&gt;Through this API, customers will be able to request a ride.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;requestRide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customerID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Tuple&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;float&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Tuple&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;float&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cabType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;paymentMethod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Ride&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Customer ID (&lt;code&gt;UUID&lt;/code&gt;): ID of the customer.&lt;/p&gt;

&lt;p&gt;Source (&lt;code&gt;Tuple&amp;lt;float&amp;gt;&lt;/code&gt;): Tuple containing the latitude and longitude of the trip's starting location.&lt;/p&gt;

&lt;p&gt;Destination (&lt;code&gt;Tuple&amp;lt;float&amp;gt;&lt;/code&gt;): Tuple containing the latitude and longitude of the trip's destination.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Returns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Result (&lt;code&gt;boolean&lt;/code&gt;): Represents whether the operation was successful or not.&lt;/p&gt;
&lt;h3&gt;
  
  
  Cancel the Ride
&lt;/h3&gt;

&lt;p&gt;This API will allow customers to cancel the ride.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;cancelRide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customerID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Customer ID (&lt;code&gt;UUID&lt;/code&gt;): ID of the customer.&lt;/p&gt;

&lt;p&gt;Reason (&lt;code&gt;UUID&lt;/code&gt;): Reason for canceling the ride &lt;em&gt;(optional)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Returns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Result (&lt;code&gt;boolean&lt;/code&gt;): Represents whether the operation was successful or not.&lt;/p&gt;
&lt;h3&gt;
  
  
  Accept or Deny the Ride
&lt;/h3&gt;

&lt;p&gt;This API will allow the driver to accept or deny the trip.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;acceptRide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;driverID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rideID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;span class="nf"&gt;denyRide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;driverID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rideID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Driver ID (&lt;code&gt;UUID&lt;/code&gt;): ID of the driver.&lt;/p&gt;

&lt;p&gt;Ride ID (&lt;code&gt;UUID&lt;/code&gt;): ID of the customer requested ride.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Returns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Result (&lt;code&gt;boolean&lt;/code&gt;): Represents whether the operation was successful or not.&lt;/p&gt;
&lt;h3&gt;
  
  
  Start or End the Trip
&lt;/h3&gt;

&lt;p&gt;Using this API, a driver will be able to start and end the trip.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;startTrip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;driverID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tripID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;span class="nf"&gt;endTrip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;driverID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tripID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Driver ID (&lt;code&gt;UUID&lt;/code&gt;): ID of the driver.&lt;/p&gt;

&lt;p&gt;Trip ID (&lt;code&gt;UUID&lt;/code&gt;): ID of the requested trip.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Returns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Result (&lt;code&gt;boolean&lt;/code&gt;): Represents whether the operation was successful or not.&lt;/p&gt;
&lt;h3&gt;
  
  
  Rate the Trip
&lt;/h3&gt;

&lt;p&gt;This API will enable customers to rate the trip.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;rateTrip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customerID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tripID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;feedback&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Customer ID (&lt;code&gt;UUID&lt;/code&gt;): ID of the customer.&lt;/p&gt;

&lt;p&gt;Trip ID (&lt;code&gt;UUID&lt;/code&gt;): ID of the completed trip.&lt;/p&gt;

&lt;p&gt;Rating (&lt;code&gt;int&lt;/code&gt;): Rating of the trip.&lt;/p&gt;

&lt;p&gt;Feedback (&lt;code&gt;string&lt;/code&gt;): Feedback about the trip by the customer &lt;em&gt;(optional)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Returns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Result (&lt;code&gt;boolean&lt;/code&gt;): Represents whether the operation was successful or not.&lt;/p&gt;
&lt;h2&gt;
  
  
  High-level design
&lt;/h2&gt;

&lt;p&gt;Now let us do a high-level design of our system.&lt;/p&gt;
&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;

&lt;p&gt;We will be using &lt;a href="https://karanpratapsingh.com/courses/system-design/monoliths-microservices#microservices" rel="noopener noreferrer"&gt;microservices architecture&lt;/a&gt; since it will make it easier to horizontally scale and decouple our services. Each service will have ownership of its own data model. Let's try to divide our system into some core services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Customer Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This service handles customer-related concerns such as authentication and customer information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Driver Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This service handles driver-related concerns such as authentication and driver information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ride Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This service will be responsible for ride matching and quadtree aggregation. It will be discussed in detail separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trip Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This service handles trip-related functionality in our system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Payment Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This service will be responsible for handling payments in our system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notification Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This service will simply send push notifications to the users. It will be discussed in detail separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Analytics Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This service will be used for metrics and analytics use cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What about inter-service communication and service discovery?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Since our architecture is microservices-based, services will be communicating with each other as well. Generally, REST or HTTP performs well but we can further improve the performance using &lt;a href="https://karanpratapsingh.com/courses/system-design/rest-graphql-grpc#grpc" rel="noopener noreferrer"&gt;gRPC&lt;/a&gt; which is more lightweight and efficient.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://karanpratapsingh.com/courses/system-design/service-discovery" rel="noopener noreferrer"&gt;Service discovery&lt;/a&gt; is another thing we will have to take into account. We can also use a service mesh that enables managed, observable, and secure communication between individual services.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Learn more about &lt;a href="https://karanpratapsingh.com/courses/system-design/rest-graphql-grpc" rel="noopener noreferrer"&gt;REST, GraphQL, gRPC&lt;/a&gt; and how they compare with each other.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  How is the service expected to work?
&lt;/h3&gt;

&lt;p&gt;Here's how our service is expected to work:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2x3yjggbfjlbl4kioxq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2x3yjggbfjlbl4kioxq.png" alt="uber-working" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Customer requests a ride by specifying the source, destination, cab type, payment method, etc.&lt;/li&gt;
&lt;li&gt;Ride service register's this request, finds nearby drivers, and calculates the estimated time of arrival (ETA).&lt;/li&gt;
&lt;li&gt;The request is then broadcasted to the nearby drivers for them to accept or deny.&lt;/li&gt;
&lt;li&gt;If the driver accepts, the customer is notified about the live location of the driver with the estimated time of arrival (ETA) while they wait for pickup.&lt;/li&gt;
&lt;li&gt;The customer is picked up and the driver can start the trip.&lt;/li&gt;
&lt;li&gt;Once the destination is reached, the driver will mark the ride as complete and collect payment.&lt;/li&gt;
&lt;li&gt;After the payment is complete, the customer can leave a rating and feedback for the trip if they like.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Location Tracking
&lt;/h3&gt;

&lt;p&gt;How do we efficiently send and receive live location data from the client (customers and drivers) to our backend? We have two different options:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pull model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The client can periodically send an HTTP request to servers to report its current location and receive ETA and pricing information. This can be achieved via something like &lt;a href="https://karanpratapsingh.com/courses/system-design/long-polling-websockets-server-sent-events#long-polling" rel="noopener noreferrer"&gt;Long polling&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Push model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The client opens a long-lived connection with the server and once new data is available it will be pushed to the client. We can use &lt;a href="https://karanpratapsingh.com/courses/system-design/long-polling-websockets-server-sent-events#websockets" rel="noopener noreferrer"&gt;WebSockets&lt;/a&gt; or &lt;a href="https://karanpratapsingh.com/courses/system-design/long-polling-websockets-server-sent-events#server-sent-events-sse" rel="noopener noreferrer"&gt;Server-Sent Events (SSE)&lt;/a&gt; for this.&lt;/p&gt;

&lt;p&gt;The pull model approach is not scalable as it will create unnecessary request overhead on our servers and most of the time the response will be empty, thus wasting our resources. To minimize latency, using the push model with &lt;a href="https://karanpratapsingh.com/courses/system-design/long-polling-websockets-server-sent-events#websockets" rel="noopener noreferrer"&gt;WebSockets&lt;/a&gt; is a better choice because then we can push data to the client once it's available without any delay given the connection is open with the client. Also, WebSockets provide full-duplex communication, unlike &lt;a href="https://karanpratapsingh.com/courses/system-design/long-polling-websockets-server-sent-events#server-sent-events-sse" rel="noopener noreferrer"&gt;Server-Sent Events (SSE)&lt;/a&gt; which are only unidirectional.&lt;/p&gt;

&lt;p&gt;Additionally, the client application should have some sort of background job mechanism to ping GPS location while the application is in the background.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Learn more about &lt;a href="https://karanpratapsingh.com/courses/system-design/long-polling-websockets-server-sent-events" rel="noopener noreferrer"&gt;Long polling, WebSockets, Server-Sent Events (SSE)&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Ride Matching
&lt;/h3&gt;

&lt;p&gt;We need a way to efficiently store and query nearby drivers. Let's explore different solutions we can incorporate into our design.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SQL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We already have access to the latitude and longitude of our customers, and with databases like &lt;a href="https://www.postgresql.org" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt; and &lt;a href="https://www.mysql.com" rel="noopener noreferrer"&gt;MySQL&lt;/a&gt; we can perform a query to find nearby driver locations given a latitude and longitude (X, Y) within a radius (R).&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;locations&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;lat&lt;/span&gt; &lt;span class="k"&gt;BETWEEN&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;long&lt;/span&gt; &lt;span class="k"&gt;BETWEEN&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;However, this is not scalable, and performing this query on large datasets will be quite slow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Geohashing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/courses/sytem-design/geohashing-and-quadtrees#geohashing"&gt;Geohashing&lt;/a&gt; is a &lt;a href="https://en.wikipedia.org/wiki/Address_geocoding" rel="noopener noreferrer"&gt;geocoding&lt;/a&gt; method used to encode geographic coordinates such as latitude and longitude into short alphanumeric strings. It was created by &lt;a href="https://twitter.com/gniemeyer" rel="noopener noreferrer"&gt;Gustavo Niemeyer&lt;/a&gt; in 2008.&lt;/p&gt;

&lt;p&gt;Geohash is a hierarchical spatial index that uses Base-32 alphabet encoding, the first character in a geohash identifies the initial location as one of the 32 cells. This cell will also contain 32 cells. This means that to represent a point, the world is recursively divided into smaller and smaller cells with each additional bit until the desired precision is attained. The precision factor also determines the size of the cell.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgaqbb0j3921rzt5ye94x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgaqbb0j3921rzt5ye94x.png" alt="geohashing" width="800" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, San Francisco with coordinates &lt;code&gt;37.7564, -122.4016&lt;/code&gt; can be represented in geohash as &lt;code&gt;9q8yy9mf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, using the customer's geohash we can determine the nearest available driver by simply comparing it with the driver's geohash. For better performance, we will index and store the geohash of the driver in memory for faster retrieval.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quadtrees&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A &lt;a href="https://dev.to/courses/sytem-design/geohashing-and-quadtrees#quadtrees"&gt;Quadtree&lt;/a&gt; is a tree data structure in which each internal node has exactly four children. They are often used to partition a two-dimensional space by recursively subdividing it into four quadrants or regions. Each child or leaf node stores spatial information. Quadtrees are the two-dimensional analog of &lt;a href="https://en.wikipedia.org/wiki/Octree" rel="noopener noreferrer"&gt;Octrees&lt;/a&gt; which are used to partition three-dimensional space.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6o9uwwtzdl0i6lse4t9q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6o9uwwtzdl0i6lse4t9q.png" alt="quadtree" width="800" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quadtrees enable us to search points within a two-dimensional range efficiently, where those points are defined as latitude/longitude coordinates or as cartesian (x, y) coordinates.&lt;/p&gt;

&lt;p&gt;We can save further computation by only subdividing a node after a certain threshold.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fba9zwj7uu0qd00z01a6c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fba9zwj7uu0qd00z01a6c.png" alt="quadtree-subdivision" width="800" height="223"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/courses/sytem-design/geohashing-and-quadtrees#quadtrees"&gt;Quadtree&lt;/a&gt; seems perfect for our use case, we can update the Quadtree every time we receive a new location update from the driver. To reduce the load on the quadtree servers we can use an in-memory datastore such as &lt;a href="https://redis.io" rel="noopener noreferrer"&gt;Redis&lt;/a&gt; to cache the latest updates. And with the application of mapping algorithms such as the &lt;a href="https://en.wikipedia.org/wiki/Hilbert_curve" rel="noopener noreferrer"&gt;Hilbert curve&lt;/a&gt;, we can perform efficient range queries to find nearby drivers for the customer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What about race conditions?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Race conditions can easily occur when a large number of customers will be requesting rides simultaneously. To avoid this can wrap our ride matching logic in a &lt;a href="https://en.wikipedia.org/wiki/Lock_(computer_science)" rel="noopener noreferrer"&gt;Mutex&lt;/a&gt; to avoid any race conditions. Furthermore, every action should be transactional in nature.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For more details, refer to &lt;a href="https://karanpratapsingh.com/courses/system-design/transactions" rel="noopener noreferrer"&gt;Transactions&lt;/a&gt; and &lt;a href="https://karanpratapsingh.com/courses/system-design/distributed-transactions" rel="noopener noreferrer"&gt;Distributed Transactions&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to find the best drivers nearby?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once we have a list of nearby drivers from the Quadtree servers, we can perform some sort of ranking based on parameters like average ratings, relevance, past customer feedback, etc. This will allow us to broadcast notifications to the best available drivers first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dealing with high demand&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In cases of high demand, we can use the concept of Surge Pricing. Surge pricing is a dynamic pricing method where prices are temporarily increased as a reaction to increased demand and mostly limited supply. This surge price can be added to the base price of the trip.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For more details, learn how &lt;a href="https://www.uber.com/us/en/drive/driver-app/how-surge-works" rel="noopener noreferrer"&gt;surge pricing works&lt;/a&gt; with Uber.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Payments
&lt;/h3&gt;

&lt;p&gt;Handling payments at scale is challenging, to simplify our system we can use a third-party payment processor like &lt;a href="https://stripe.com" rel="noopener noreferrer"&gt;Stripe&lt;/a&gt; or &lt;a href="https://www.paypal.com" rel="noopener noreferrer"&gt;PayPal&lt;/a&gt;. Once the payment is complete, the payment processor will redirect the user back to our application and we can set up a &lt;a href="https://en.wikipedia.org/wiki/Webhook" rel="noopener noreferrer"&gt;webhook&lt;/a&gt; to capture all the payment-related data.&lt;/p&gt;
&lt;h3&gt;
  
  
  Notifications
&lt;/h3&gt;

&lt;p&gt;Push notifications will be an integral part of our platform. We can use a message queue or a message broker such as &lt;a href="https://kafka.apache.org" rel="noopener noreferrer"&gt;Apache Kafka&lt;/a&gt; with the notification service to dispatch requests to &lt;a href="https://firebase.google.com/docs/cloud-messaging" rel="noopener noreferrer"&gt;Firebase Cloud Messaging (FCM)&lt;/a&gt; or &lt;a href="https://developer.apple.com/documentation/usernotifications" rel="noopener noreferrer"&gt;Apple Push Notification Service (APNS)&lt;/a&gt; which will handle the delivery of the push notifications to user devices.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For more details, refer to the &lt;a href="https://karanpratapsingh.com/courses/system-design/whatsapp#notifications" rel="noopener noreferrer"&gt;Whatsapp&lt;/a&gt; system design where we discuss push notifications.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Detailed design
&lt;/h2&gt;

&lt;p&gt;It's time to discuss our design decisions in detail.&lt;/p&gt;
&lt;h3&gt;
  
  
  Data Partitioning
&lt;/h3&gt;

&lt;p&gt;To scale out our databases we will need to partition our data. Horizontal partitioning (aka &lt;a href="https://karanpratapsingh.com/courses/system-design/sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt;) can be a good first step. We can shard our database either based on existing &lt;a href="https://karanpratapsingh.com/courses/system-design/sharding#partitioning-criteria" rel="noopener noreferrer"&gt;partition schemes&lt;/a&gt; or regions. If we divide the locations into regions using let's say zip codes, we can effectively store all the data in a given region on a fixed node. But this can still cause uneven data and load distribution, we can solve this using &lt;a href="https://karanpratapsingh.com/courses/system-design/consistent-hashing" rel="noopener noreferrer"&gt;Consistent hashing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For more details, refer to &lt;a href="https://karanpratapsingh.com/courses/system-design/sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt; and &lt;a href="https://karanpratapsingh.com/courses/system-design/consistent-hashing" rel="noopener noreferrer"&gt;Consistent Hashing&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Metrics and Analytics
&lt;/h3&gt;

&lt;p&gt;Recording analytics and metrics is one of our extended requirements. We can capture the data from different services and run analytics on the data using &lt;a href="https://spark.apache.org" rel="noopener noreferrer"&gt;Apache Spark&lt;/a&gt; which is an open-source unified analytics engine for large-scale data processing. Additionally, we can store critical metadata in the views table to increase data points within our data.&lt;/p&gt;
&lt;h3&gt;
  
  
  Caching
&lt;/h3&gt;

&lt;p&gt;In a location services-based platform, caching is important. We have to be able to cache the recent locations of the customers and drivers for fast retrieval. We can use solutions like &lt;a href="https://redis.io" rel="noopener noreferrer"&gt;Redis&lt;/a&gt; or &lt;a href="https://memcached.org" rel="noopener noreferrer"&gt;Memcached&lt;/a&gt; but what kind of cache eviction policy would best fit our needs?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which cache eviction policy to use?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)" rel="noopener noreferrer"&gt;Least Recently Used (LRU)&lt;/a&gt; can be a good policy for our system. In this policy, we discard the least recently used key first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to handle cache miss?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Whenever there is a cache miss, our servers can hit the database directly and update the cache with the new entries.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For more details, refer to &lt;a href="https://karanpratapsingh.com/courses/system-design/caching" rel="noopener noreferrer"&gt;Caching&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Identify and resolve bottlenecks
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5r8ut610jbrz1xkjjegl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5r8ut610jbrz1xkjjegl.png" alt="uber-advanced-design" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let us identify and resolve bottlenecks such as single points of failure in our design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"What if one of our services crashes?"&lt;/li&gt;
&lt;li&gt;"How will we distribute our traffic between our components?"&lt;/li&gt;
&lt;li&gt;"How can we reduce the load on our database?"&lt;/li&gt;
&lt;li&gt;"How to improve the availability of our cache?"&lt;/li&gt;
&lt;li&gt;"How can we make our notification system more robust?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To make our system more resilient we can do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running multiple instances of each of our services.&lt;/li&gt;
&lt;li&gt;Introducing &lt;a href="https://karanpratapsingh.com/courses/system-design/load-balancing" rel="noopener noreferrer"&gt;load balancers&lt;/a&gt; between clients, servers, databases, and cache servers.&lt;/li&gt;
&lt;li&gt;Using multiple read replicas for our databases.&lt;/li&gt;
&lt;li&gt;Multiple instances and replicas for our distributed cache.&lt;/li&gt;
&lt;li&gt;Exactly once delivery and message ordering is challenging in a distributed system, we can use a dedicated &lt;a href="https://karanpratapsingh.com/courses/system-design/message-brokers" rel="noopener noreferrer"&gt;message broker&lt;/a&gt; such as &lt;a href="https://kafka.apache.org" rel="noopener noreferrer"&gt;Apache Kafka&lt;/a&gt; or &lt;a href="https://nats.io" rel="noopener noreferrer"&gt;NATS&lt;/a&gt; to make our notification system more robust.&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;&lt;em&gt;This article is part of my open source &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;System Design Course&lt;/a&gt; available on Github.&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/karanpratapsingh" rel="noopener noreferrer"&gt;
        karanpratapsingh
      &lt;/a&gt; / &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;
        system-design
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Learn how to design systems at scale and prepare for system design interviews
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;System Design&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Hey, welcome to the course. I hope this course provides a great learning experience.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This course is also available on my &lt;a href="https://karanpratapsingh.com/courses/system-design" rel="nofollow noopener noreferrer"&gt;website&lt;/a&gt; and as an ebook on &lt;a href="https://leanpub.com/systemdesign" rel="nofollow noopener noreferrer"&gt;leanpub&lt;/a&gt;. Please leave a ⭐ as motivation if this was helpful!&lt;/em&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Table of contents&lt;/h1&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#what-is-system-design" rel="noopener noreferrer"&gt;What is system design?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Chapter I&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#ip" rel="noopener noreferrer"&gt;IP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#osi-model" rel="noopener noreferrer"&gt;OSI Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#tcp-and-udp" rel="noopener noreferrer"&gt;TCP and UDP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#domain-name-system-dns" rel="noopener noreferrer"&gt;Domain Name System (DNS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#load-balancing" rel="noopener noreferrer"&gt;Load Balancing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#clustering" rel="noopener noreferrer"&gt;Clustering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#caching" rel="noopener noreferrer"&gt;Caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#content-delivery-network-cdn" rel="noopener noreferrer"&gt;Content Delivery Network (CDN)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#proxy" rel="noopener noreferrer"&gt;Proxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#availability" rel="noopener noreferrer"&gt;Availability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#scalability" rel="noopener noreferrer"&gt;Scalability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#storage" rel="noopener noreferrer"&gt;Storage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Chapter II&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#databases-and-dbms" rel="noopener noreferrer"&gt;Databases and DBMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-databases" rel="noopener noreferrer"&gt;SQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#nosql-databases" rel="noopener noreferrer"&gt;NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-vs-nosql-databases" rel="noopener noreferrer"&gt;SQL vs NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-replication" rel="noopener noreferrer"&gt;Database Replication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#indexes" rel="noopener noreferrer"&gt;Indexes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#normalization-and-denormalization" rel="noopener noreferrer"&gt;Normalization and Denormalization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#acid-and-base-consistency-models" rel="noopener noreferrer"&gt;ACID and BASE consistency models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#cap-theorem" rel="noopener noreferrer"&gt;CAP theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#pacelc-theorem" rel="noopener noreferrer"&gt;PACELC Theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#transactions" rel="noopener noreferrer"&gt;Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#distributed-transactions" rel="noopener noreferrer"&gt;Distributed Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#consistent-hashing" rel="noopener noreferrer"&gt;Consistent Hashing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-federation" rel="noopener noreferrer"&gt;Database Federation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Chapter III&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#n-tier-architecture" rel="noopener noreferrer"&gt;N-tier architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-brokers" rel="noopener noreferrer"&gt;Message Brokers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-queues" rel="noopener noreferrer"&gt;Message Queues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#publish-subscribe" rel="noopener noreferrer"&gt;Publish-Subscribe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#enterprise-service-bus-esb" rel="noopener noreferrer"&gt;Enterprise Service Bus (ESB)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#monoliths-and-microservices" rel="noopener noreferrer"&gt;Monoliths and Microservices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-driven-architecture-eda" rel="noopener noreferrer"&gt;Event-Driven Architecture (EDA)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-sourcing" rel="noopener noreferrer"&gt;Event Sourcing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#command-and-query-responsibility-segregation-cqrs" rel="noopener noreferrer"&gt;Command and Query Responsibility Segregation (CQRS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#api-gateway" rel="noopener noreferrer"&gt;API Gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#rest-graphql-grpc" rel="noopener noreferrer"&gt;REST, GraphQL, gRPC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#long-polling-websockets-server-sent-events-sse" rel="noopener noreferrer"&gt;Long polling, WebSockets, Server-Sent Events (SSE)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Chapter IV&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;…&lt;/li&gt;&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>distributedsystems</category>
      <category>architecture</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>System Design: Netflix</title>
      <dc:creator>Karan Pratap Singh</dc:creator>
      <pubDate>Thu, 22 Sep 2022 02:51:27 +0000</pubDate>
      <link>https://forem.com/karanpratapsingh/system-design-netflix-3d9g</link>
      <guid>https://forem.com/karanpratapsingh/system-design-netflix-3d9g</guid>
      <description>&lt;p&gt;Let's design a &lt;a href="https://netflix.com" rel="noopener noreferrer"&gt;Netflix&lt;/a&gt; like video streaming service, similar to services like &lt;a href="https://www.primevideo.com" rel="noopener noreferrer"&gt;Amazon Prime Video&lt;/a&gt;, &lt;a href="https://www.disneyplus.com" rel="noopener noreferrer"&gt;Disney Plus&lt;/a&gt;, &lt;a href="https://www.hulu.com" rel="noopener noreferrer"&gt;Hulu&lt;/a&gt;, &lt;a href="https://youtube.com" rel="noopener noreferrer"&gt;Youtube&lt;/a&gt;, &lt;a href="https://vimeo.com" rel="noopener noreferrer"&gt;Vimeo&lt;/a&gt;, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Netflix?
&lt;/h2&gt;

&lt;p&gt;Netflix is a subscription-based streaming service that allows its members to watch TV shows and movies on an internet-connected device. It is available on platforms such as the Web, iOS, Android, TV, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;p&gt;Our system should meet the following requirements:&lt;/p&gt;

&lt;h3&gt;
  
  
  Functional requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Users should be able to stream and share videos.&lt;/li&gt;
&lt;li&gt;The content team (or users in YouTube's case) should be able to upload new videos (movies, tv shows episodes, and other content).&lt;/li&gt;
&lt;li&gt;Users should be able to search for videos using titles or tags.&lt;/li&gt;
&lt;li&gt;Users should be able to comment on a video similar to YouTube.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Non-Functional requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;High availability with minimal latency.&lt;/li&gt;
&lt;li&gt;High reliability, no uploads should be lost.&lt;/li&gt;
&lt;li&gt;The system should be scalable and efficient.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extended requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Certain content should be &lt;a href="https://en.wikipedia.org/wiki/Geo-blocking" rel="noopener noreferrer"&gt;geo-blocked&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Resume video playback from the point user left off.&lt;/li&gt;
&lt;li&gt;Record metrics and analytics of videos.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Estimation and Constraints
&lt;/h2&gt;

&lt;p&gt;Let's start with the estimation and constraints.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Make sure to check any scale or traffic-related assumptions with your interviewer.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Traffic
&lt;/h3&gt;

&lt;p&gt;This will be a read-heavy system, let us assume we have 1 billion total users with 200 million daily active users (DAU), and on average each user watches 5 videos a day. This gives us 1 billion videos watched per day.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;200 million×5 videos=1 billion/day
200 \space million \times 5 \space videos = 1 \space billion/day
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;200&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;mi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;5&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;eos&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;bi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
Assuming, a &lt;code&gt;200:1&lt;/code&gt; read/write ratio, about 50 million videos will be uploaded every day.


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;1200×1 billion=50 million/day
\frac{1}{200} \times 1 \space billion = 50 \space million/day
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;200&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;bi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;50&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;mi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;strong&gt;What would be Requests Per Second (RPS) for our system?&lt;/strong&gt;

&lt;p&gt;1 billion requests per day translate into 12K requests per second.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;1 billion(24 hrs×3600 seconds)=∼12K requests/second
\frac{1 \space billion}{(24 \space hrs \times 3600 \space seconds)} = \sim 12K \space requests/second
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;24&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;h&lt;/span&gt;&lt;span class="mord mathnormal"&gt;rs&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3600&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;bi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;12&lt;/span&gt;&lt;span class="mord mathnormal"&gt;K&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;re&lt;/span&gt;&lt;span class="mord mathnormal"&gt;q&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mord mathnormal"&gt;es&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
### Storage

&lt;p&gt;If we assume each video is 100 MB on average, we will require about 5 PB of storage every day.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;50 million×100 MB=5 PB/day
50 \space million \times 100 \space MB = 5 \space PB/day
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;50&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;mi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;MB&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;5&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;PB&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
And for 10 years, we will require an astounding 18,250 PB of storage.


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;5 PB×365 days×10 years=∼18,250 PB
5 \space PB \times 365 \space days \times 10 \space years = \sim 18,250 \space PB
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;5&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;PB&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;365&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ys&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;10&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;ye&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;rs&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;18&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;250&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;PB&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
### Bandwidth

&lt;p&gt;As our system is handling 5 PB of ingress every day, we will a require minimum bandwidth of around 58 GB per second.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;5 PB(24 hrs×3600 seconds)=∼58 GB/second
\frac{5 \space PB}{(24 \space hrs \times 3600 \space seconds)} = \sim 58 \space GB/second
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;24&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;h&lt;/span&gt;&lt;span class="mord mathnormal"&gt;rs&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3600&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;5&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;PB&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;58&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;GB&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
### High-level estimate

&lt;p&gt;Here is our high-level estimate:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Estimate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Daily active users (DAU)&lt;/td&gt;
&lt;td&gt;200 million&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Requests per second (RPS)&lt;/td&gt;
&lt;td&gt;12K/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage (per day)&lt;/td&gt;
&lt;td&gt;~5 PB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage (10 years)&lt;/td&gt;
&lt;td&gt;~18,250 PB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bandwidth&lt;/td&gt;
&lt;td&gt;~58 GB/s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Data model design
&lt;/h2&gt;

&lt;p&gt;This is the general data model which reflects our requirements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn3395yv46k5mjdp1xa6q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn3395yv46k5mjdp1xa6q.png" alt="netflix-datamodel" width="800" height="552"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have the following tables:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;users&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This table will contain a user's information such as &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;, &lt;code&gt;dob&lt;/code&gt;, and other details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;videos&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As the name suggests, this table will store videos and their properties such as &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;streamURL&lt;/code&gt;, &lt;code&gt;tags&lt;/code&gt;, etc. We will also store the corresponding &lt;code&gt;userID&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;tags&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This table will simply store tags associated with a video.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;views&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This table helps us to store all the views received on a video.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;comments&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This table stores all the comments received on a video (like YouTube).&lt;/p&gt;
&lt;h3&gt;
  
  
  What kind of database should we use?
&lt;/h3&gt;

&lt;p&gt;While our data model seems quite relational, we don't necessarily need to store everything in a single database, as this can limit our scalability and quickly become a bottleneck.&lt;/p&gt;

&lt;p&gt;We will split the data between different services each having ownership over a particular table. Then we can use a relational database such as &lt;a href="https://www.postgresql.org" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt; or a distributed NoSQL database such as &lt;a href="https://cassandra.apache.org/_/index.html" rel="noopener noreferrer"&gt;Apache Cassandra&lt;/a&gt; for our use case.&lt;/p&gt;
&lt;h2&gt;
  
  
  API design
&lt;/h2&gt;

&lt;p&gt;Let us do a basic API design for our services:&lt;/p&gt;
&lt;h3&gt;
  
  
  Upload a video
&lt;/h3&gt;

&lt;p&gt;Given a byte stream, this API enables video to be uploaded to our service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;uploadVideo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Title (&lt;code&gt;string&lt;/code&gt;): Title of the new video.&lt;/p&gt;

&lt;p&gt;Description (&lt;code&gt;string&lt;/code&gt;): Description of the new video.&lt;/p&gt;

&lt;p&gt;Data (&lt;code&gt;Byte[]&lt;/code&gt;): Byte stream of the video data.&lt;/p&gt;

&lt;p&gt;Tags (&lt;code&gt;string[]&lt;/code&gt;): Tags for the video &lt;em&gt;(optional)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Returns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Result (&lt;code&gt;boolean&lt;/code&gt;): Represents whether the operation was successful or not.&lt;/p&gt;
&lt;h3&gt;
  
  
  Streaming a video
&lt;/h3&gt;

&lt;p&gt;This API allows our users to stream a video with the preferred codec and resolution.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;streamVideo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;videoID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;codec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resolution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Tuple&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;VideoStream&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Video ID (&lt;code&gt;UUID&lt;/code&gt;): ID of the video that needs to be streamed.&lt;/p&gt;

&lt;p&gt;Codec (&lt;code&gt;Enum&amp;lt;string&amp;gt;&lt;/code&gt;): Required &lt;a href="https://en.wikipedia.org/wiki/Video_codec" rel="noopener noreferrer"&gt;codec&lt;/a&gt; of the requested video, such as &lt;code&gt;h.265&lt;/code&gt;, &lt;code&gt;h.264&lt;/code&gt;, &lt;code&gt;VP9&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;Resolution (&lt;code&gt;Tuple&amp;lt;int&amp;gt;&lt;/code&gt;): &lt;a href="https://en.wikipedia.org/wiki/Display_resolution" rel="noopener noreferrer"&gt;Resolution&lt;/a&gt; of the requested video.&lt;/p&gt;

&lt;p&gt;Offset (&lt;code&gt;int&lt;/code&gt;): Offset of the video stream in seconds to stream data from any point in the video &lt;em&gt;(optional)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Returns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Stream (&lt;code&gt;VideoStream&lt;/code&gt;): Data stream of the requested video.&lt;/p&gt;
&lt;h3&gt;
  
  
  Search for a video
&lt;/h3&gt;

&lt;p&gt;This API will enable our users to search for a video based on its title or tags.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;searchVideo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nextPage&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Video&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Query (&lt;code&gt;string&lt;/code&gt;): Search query from the user.&lt;/p&gt;

&lt;p&gt;Next Page (&lt;code&gt;string&lt;/code&gt;): Token for the next page, this can be used for pagination &lt;em&gt;(optional)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Returns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Videos (&lt;code&gt;Video[]&lt;/code&gt;): All the videos available for a particular search query.&lt;/p&gt;
&lt;h3&gt;
  
  
  Add a comment
&lt;/h3&gt;

&lt;p&gt;This API will allow our users to post a comment on a video (like YouTube).&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;videoID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;VideoID (&lt;code&gt;UUID&lt;/code&gt;): ID of the video user wants to comment on.&lt;/p&gt;

&lt;p&gt;Comment (&lt;code&gt;string&lt;/code&gt;): The text content of the comment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Returns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Result (&lt;code&gt;boolean&lt;/code&gt;): Represents whether the operation was successful or not.&lt;/p&gt;
&lt;h2&gt;
  
  
  High-level design
&lt;/h2&gt;

&lt;p&gt;Now let us do a high-level design of our system.&lt;/p&gt;
&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;

&lt;p&gt;We will be using &lt;a href="https://karanpratapsingh.com/courses/system-design/monoliths-microservices#microservices" rel="noopener noreferrer"&gt;microservices architecture&lt;/a&gt; since it will make it easier to horizontally scale and decouple our services. Each service will have ownership of its own data model. Let's try to divide our system into some core services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This service handles user-related concerns such as authentication and user information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stream Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The tweet service will handle video streaming-related functionality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Search Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The service is responsible for handling search-related functionality. It will be discussed in detail separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Media service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This service will handle the video uploads and processing. It will be discussed in detail separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Analytics Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This service will be used for metrics and analytics use cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What about inter-service communication and service discovery?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Since our architecture is microservices-based, services will be communicating with each other as well. Generally, REST or HTTP performs well but we can further improve the performance using &lt;a href="https://karanpratapsingh.com/courses/system-design/rest-graphql-grpc#grpc" rel="noopener noreferrer"&gt;gRPC&lt;/a&gt; which is more lightweight and efficient.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://karanpratapsingh.com/courses/system-design/service-discovery" rel="noopener noreferrer"&gt;Service discovery&lt;/a&gt; is another thing we will have to take into account. We can also use a service mesh that enables managed, observable, and secure communication between individual services.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Learn more about &lt;a href="https://karanpratapsingh.com/courses/system-design/rest-graphql-grpc" rel="noopener noreferrer"&gt;REST, GraphQL, gRPC&lt;/a&gt; and how they compare with each other.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Video processing
&lt;/h3&gt;

&lt;p&gt;There are so many variables in play when it comes to processing a video. For example, an average data size of two-hour raw 8K footage from a high-end camera can easily be up to 4 TB, thus we need to have some kind of processing to reduce both storage and delivery costs.&lt;/p&gt;

&lt;p&gt;Here's how we can process videos once they're uploaded by the content team (or users in YouTube's case) and are queued for processing in our &lt;a href="https://karanpratapsingh.com/courses/system-design/message-queues" rel="noopener noreferrer"&gt;message queue&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgzffdro9wvxf8ffrot2q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgzffdro9wvxf8ffrot2q.png" alt="video-processing-pipeline" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's discuss how this works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;File Chunker&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the first step of our processing pipeline. File chunking is the process of splitting a file into smaller pieces called chunks. It can help us eliminate duplicate copies of repeating data on storage, and reduces the amount of data sent over the network by only selecting changed chunks.&lt;/p&gt;

&lt;p&gt;Usually, a video file can be split into equal size chunks based on timestamps but Netflix instead splits chunks based on scenes, this slight variation becomes a huge factor for a better user experience as whenever the client requests a chunk from the server, there is a lower chance of interruption as a complete scene will be retrieved.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo7t66h8atatrbmui4c7s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo7t66h8atatrbmui4c7s.png" alt="file-chunking" width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Content Filter&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This step checks if the video adheres to the content policy of the platform, this can be pre-approved in the case of Netflix as per the &lt;a href="https://en.wikipedia.org/wiki/Motion_picture_content_rating_system" rel="noopener noreferrer"&gt;content rating&lt;/a&gt; of the media or can be strictly enforced like YouTube.&lt;/p&gt;

&lt;p&gt;This entire step is done by a machine learning model which performs copyright, piracy, and NSFW checks. If issues are found, we can push the task to a &lt;a href="https://karanpratapsingh.com/courses/system-design/message-queues#dead-letter-queues" rel="noopener noreferrer"&gt;dead-letter queue (DLQ)&lt;/a&gt; and someone from the moderation team can do further inspection.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Transcoder&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Transcoding" rel="noopener noreferrer"&gt;Transcoding&lt;/a&gt; is a process in which the original data is decoded to an intermediate uncompressed format, which is then encoded into the target format. This process uses different &lt;a href="https://en.wikipedia.org/wiki/Video_codec" rel="noopener noreferrer"&gt;codecs&lt;/a&gt; to perform bitrate adjustment, image downsampling, or re-encoding the media.&lt;/p&gt;

&lt;p&gt;This results in a smaller size file and a much more optimized format for the target devices. Standalone solutions such as &lt;a href="https://ffmpeg.org" rel="noopener noreferrer"&gt;FFmpeg&lt;/a&gt; or cloud-based solutions like &lt;a href="https://aws.amazon.com/mediaconvert" rel="noopener noreferrer"&gt;AWS Elemental MediaConvert&lt;/a&gt; can be used to implement this step of the pipeline.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Quality Conversion&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the last step of the processing pipeline and as the name suggests, this step handles the conversion of the transcoded media from the previous step into different resolutions such as 4K, 1440p, 1080p, 720p, etc.&lt;/p&gt;

&lt;p&gt;This allows us to fetch the desired quality of the video as per the user's request, and once the media file finishes processing, it will be uploaded to a distributed file storage such as &lt;a href="https://karanpratapsingh.com/courses/system-design/storage#hdfs" rel="noopener noreferrer"&gt;HDFS&lt;/a&gt;, &lt;a href="https://www.gluster.org" rel="noopener noreferrer"&gt;GlusterFS&lt;/a&gt;, or an &lt;a href="https://karanpratapsingh.com/courses/system-design/storage#object-storage" rel="noopener noreferrer"&gt;object storage&lt;/a&gt; such as &lt;a href="https://aws.amazon.com/s3" rel="noopener noreferrer"&gt;Amazon S3&lt;/a&gt; for later retrieval during streaming.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: We can add additional steps such as subtitles and thumbnails generation as part of our pipeline.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why are we using a message queue?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Processing videos as a long-running task makes much more sense, and a &lt;a href="https://karanpratapsingh.com/courses/system-design/message-queues" rel="noopener noreferrer"&gt;message queue&lt;/a&gt; also decouples our video processing pipeline from the uploads functionality. We can use something like &lt;a href="https://aws.amazon.com/sqs" rel="noopener noreferrer"&gt;Amazon SQS&lt;/a&gt; or &lt;a href="https://www.rabbitmq.com" rel="noopener noreferrer"&gt;RabbitMQ&lt;/a&gt; to support this.&lt;/p&gt;
&lt;h3&gt;
  
  
  Video streaming
&lt;/h3&gt;

&lt;p&gt;Video streaming is a challenging task from both the client and server perspectives. Moreover, internet connection speeds vary quite a lot between different users. To make sure users don't re-fetch the same content, we can use a &lt;a href="https://karanpratapsingh.com/courses/system-design/content-delivery-network" rel="noopener noreferrer"&gt;Content Delivery Network (CDN)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Netflix takes this a step further with its &lt;a href="https://openconnect.netflix.com" rel="noopener noreferrer"&gt;Open Connect&lt;/a&gt; program. In this approach, they partner with thousands of Internet Service Providers (ISPs) to localize their traffic and deliver their content more efficiently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the difference between Netflix's Open Connect and a traditional Content Delivery Network (CDN)?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Netflix Open Connect is our purpose-built &lt;a href="https://karanpratapsingh.com/courses/system-design/content-delivery-network" rel="noopener noreferrer"&gt;Content Delivery Network (CDN)&lt;/a&gt; responsible for serving Netflix's video traffic. Around 95% of the traffic globally is delivered via direct connections between Open Connect and the ISPs their customers use to access the internet.&lt;/p&gt;

&lt;p&gt;Currently, they have Open Connect Appliances (OCAs) in over 1000 separate locations around the world. In case of issues, Open Connect Appliances (OCAs) can failover, and the traffic can be re-routed to Netflix servers.&lt;/p&gt;

&lt;p&gt;Additionally, we can use &lt;a href="https://en.wikipedia.org/wiki/Adaptive_bitrate_streaming" rel="noopener noreferrer"&gt;Adaptive bitrate streaming&lt;/a&gt; protocols such as &lt;a href="https://en.wikipedia.org/wiki/HTTP_Live_Streaming" rel="noopener noreferrer"&gt;HTTP Live Streaming (HLS)&lt;/a&gt; which is designed for reliability and it dynamically adapts to network conditions by optimizing playback for the available speed of the connections.&lt;/p&gt;

&lt;p&gt;Lastly, for playing the video from where the user left off (part of our extended requirements), we can simply use the &lt;code&gt;offset&lt;/code&gt; property we stored in the &lt;code&gt;views&lt;/code&gt; table to retrieve the scene chunk at that particular timestamp and resume the playback for the user.&lt;/p&gt;
&lt;h3&gt;
  
  
  Searching
&lt;/h3&gt;

&lt;p&gt;Sometimes traditional DBMS are not performant enough, we need something which allows us to store, search, and analyze huge volumes of data quickly and in near real-time and give results within milliseconds. &lt;a href="https://www.elastic.co" rel="noopener noreferrer"&gt;Elasticsearch&lt;/a&gt; can help us with this use case.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.elastic.co" rel="noopener noreferrer"&gt;Elasticsearch&lt;/a&gt; is a distributed, free and open search and analytics engine for all types of data, including textual, numerical, geospatial, structured, and unstructured. It is built on top of &lt;a href="https://lucene.apache.org" rel="noopener noreferrer"&gt;Apache Lucene&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do we identify trending content?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Trending functionality will be based on top of the search functionality. We can cache the most frequently searched queries in the last &lt;code&gt;N&lt;/code&gt; seconds and update them every &lt;code&gt;M&lt;/code&gt; seconds using some sort of batch job mechanism.&lt;/p&gt;
&lt;h3&gt;
  
  
  Sharing
&lt;/h3&gt;

&lt;p&gt;Sharing content is an important part of any platform, for this, we can have some sort of URL shortener service in place that can generate short URLs for the users to share.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For more details, refer to the &lt;a href="https://karanpratapsingh.com/courses/system-design/url-shortener" rel="noopener noreferrer"&gt;URL Shortener&lt;/a&gt; system design.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Detailed design
&lt;/h2&gt;

&lt;p&gt;It's time to discuss our design decisions in detail.&lt;/p&gt;
&lt;h3&gt;
  
  
  Data Partitioning
&lt;/h3&gt;

&lt;p&gt;To scale out our databases we will need to partition our data. Horizontal partitioning (aka &lt;a href="https://karanpratapsingh.com/courses/system-design/sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt;) can be a good first step. We can use partitions schemes such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hash-Based Partitioning&lt;/li&gt;
&lt;li&gt;List-Based Partitioning&lt;/li&gt;
&lt;li&gt;Range Based Partitioning&lt;/li&gt;
&lt;li&gt;Composite Partitioning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The above approaches can still cause uneven data and load distribution, we can solve this using &lt;a href="https://karanpratapsingh.com/courses/system-design/consistent-hashing" rel="noopener noreferrer"&gt;Consistent hashing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For more details, refer to &lt;a href="https://karanpratapsingh.com/courses/system-design/sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt; and &lt;a href="https://karanpratapsingh.com/courses/system-design/consistent-hashing" rel="noopener noreferrer"&gt;Consistent Hashing&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Geo-blocking
&lt;/h3&gt;

&lt;p&gt;Platforms like Netflix and YouTube use &lt;a href="https://en.wikipedia.org/wiki/Geo-blocking" rel="noopener noreferrer"&gt;Geo-blocking&lt;/a&gt; to restrict content in certain geographical areas or countries. This is primarily done due to legal distribution laws that Netflix has to adhere to when they make a deal with the production and distribution companies. In the case of YouTube, this will be controlled by the user during the publishing of the content.&lt;/p&gt;

&lt;p&gt;We can determine the user's location either using their &lt;a href="https://karanpratapsingh.com/courses/system-design/ip" rel="noopener noreferrer"&gt;IP&lt;/a&gt; or region settings in their profile then use services like &lt;a href="https://aws.amazon.com/cloudfront" rel="noopener noreferrer"&gt;Amazon CloudFront&lt;/a&gt; which supports a geographic restrictions feature or a &lt;a href="https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy-geo.html" rel="noopener noreferrer"&gt;geolocation routing policy&lt;/a&gt; with &lt;a href="https://aws.amazon.com/route53" rel="noopener noreferrer"&gt;Amazon Route53&lt;/a&gt; to restrict the content and re-route the user to an error page if the content is not available in that particular region or country.&lt;/p&gt;
&lt;h3&gt;
  
  
  Recommendations
&lt;/h3&gt;

&lt;p&gt;Netflix uses a machine learning model which uses the user's viewing history to predict what the user might like to watch next, an algorithm like &lt;a href="https://en.wikipedia.org/wiki/Collaborative_filtering" rel="noopener noreferrer"&gt;Collaborative Filtering&lt;/a&gt; can be used.&lt;/p&gt;

&lt;p&gt;However, Netflix (like YouTube) uses its own algorithm called Netflix Recommendation Engine which can track several data points such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User profile information like age, gender, and location.&lt;/li&gt;
&lt;li&gt;Browsing and scrolling behavior of the user.&lt;/li&gt;
&lt;li&gt;Time and date a user watched a title.&lt;/li&gt;
&lt;li&gt;The device which was used to stream the content.&lt;/li&gt;
&lt;li&gt;The number of searches and what terms were searched.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;For more detail, refer to &lt;a href="https://research.netflix.com/research-area/recommendations" rel="noopener noreferrer"&gt;Netflix recommendation research&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Metrics and Analytics
&lt;/h3&gt;

&lt;p&gt;Recording analytics and metrics is one of our extended requirements. We can capture the data from different services and run analytics on the data using &lt;a href="https://spark.apache.org" rel="noopener noreferrer"&gt;Apache Spark&lt;/a&gt; which is an open-source unified analytics engine for large-scale data processing. Additionally, we can store critical metadata in the views table to increase data points within our data.&lt;/p&gt;
&lt;h3&gt;
  
  
  Caching
&lt;/h3&gt;

&lt;p&gt;In a streaming platform, caching is important. We have to be able to cache as much static media content as possible to improve user experience. We can use solutions like &lt;a href="https://redis.io" rel="noopener noreferrer"&gt;Redis&lt;/a&gt; or &lt;a href="https://memcached.org" rel="noopener noreferrer"&gt;Memcached&lt;/a&gt; but what kind of cache eviction policy would best fit our needs?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which cache eviction policy to use?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)" rel="noopener noreferrer"&gt;Least Recently Used (LRU)&lt;/a&gt; can be a good policy for our system. In this policy, we discard the least recently used key first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to handle cache miss?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Whenever there is a cache miss, our servers can hit the database directly and update the cache with the new entries.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For more details, refer to &lt;a href="https://karanpratapsingh.com/courses/system-design/caching" rel="noopener noreferrer"&gt;Caching&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Media streaming and storage
&lt;/h3&gt;

&lt;p&gt;As most of our storage space will be used for storing media files such as thumbnails and videos. Per our discussion earlier, the media service will be handling both the upload and processing of media files.&lt;/p&gt;

&lt;p&gt;We will use distributed file storage such as &lt;a href="https://karanpratapsingh.com/courses/system-design/storage#hdfs" rel="noopener noreferrer"&gt;HDFS&lt;/a&gt;, &lt;a href="https://www.gluster.org" rel="noopener noreferrer"&gt;GlusterFS&lt;/a&gt;, or an &lt;a href="https://karanpratapsingh.com/courses/system-design/storage#object-storage" rel="noopener noreferrer"&gt;object storage&lt;/a&gt; such as &lt;a href="https://aws.amazon.com/s3" rel="noopener noreferrer"&gt;Amazon S3&lt;/a&gt; for storage and streaming of the content.&lt;/p&gt;
&lt;h3&gt;
  
  
  Content Delivery Network (CDN)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://karanpratapsingh.com/courses/system-design/content-delivery-network" rel="noopener noreferrer"&gt;Content Delivery Network (CDN)&lt;/a&gt; increases content availability and redundancy while reducing bandwidth costs. Generally, static files such as images, and videos are served from CDN. We can use services like &lt;a href="https://aws.amazon.com/cloudfront" rel="noopener noreferrer"&gt;Amazon CloudFront&lt;/a&gt; or &lt;a href="https://www.cloudflare.com/cdn" rel="noopener noreferrer"&gt;Cloudflare CDN&lt;/a&gt; for this use case.&lt;/p&gt;
&lt;h2&gt;
  
  
  Identify and resolve bottlenecks
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5gvmskguwhi5ww7389gj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5gvmskguwhi5ww7389gj.png" alt="netflix-advanced-design" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let us identify and resolve bottlenecks such as single points of failure in our design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"What if one of our services crashes?"&lt;/li&gt;
&lt;li&gt;"How will we distribute our traffic between our components?"&lt;/li&gt;
&lt;li&gt;"How can we reduce the load on our database?"&lt;/li&gt;
&lt;li&gt;"How to improve the availability of our cache?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To make our system more resilient we can do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running multiple instances of each of our services.&lt;/li&gt;
&lt;li&gt;Introducing &lt;a href="https://karanpratapsingh.com/courses/system-design/load-balancing" rel="noopener noreferrer"&gt;load balancers&lt;/a&gt; between clients, servers, databases, and cache servers.&lt;/li&gt;
&lt;li&gt;Using multiple read replicas for our databases.&lt;/li&gt;
&lt;li&gt;Multiple instances and replicas for our distributed cache.&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;&lt;em&gt;This article is part of my open source &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;System Design Course&lt;/a&gt; available on Github.&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/karanpratapsingh" rel="noopener noreferrer"&gt;
        karanpratapsingh
      &lt;/a&gt; / &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;
        system-design
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Learn how to design systems at scale and prepare for system design interviews
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;System Design&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Hey, welcome to the course. I hope this course provides a great learning experience.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This course is also available on my &lt;a href="https://karanpratapsingh.com/courses/system-design" rel="nofollow noopener noreferrer"&gt;website&lt;/a&gt; and as an ebook on &lt;a href="https://leanpub.com/systemdesign" rel="nofollow noopener noreferrer"&gt;leanpub&lt;/a&gt;. Please leave a ⭐ as motivation if this was helpful!&lt;/em&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Table of contents&lt;/h1&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#what-is-system-design" rel="noopener noreferrer"&gt;What is system design?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Chapter I&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#ip" rel="noopener noreferrer"&gt;IP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#osi-model" rel="noopener noreferrer"&gt;OSI Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#tcp-and-udp" rel="noopener noreferrer"&gt;TCP and UDP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#domain-name-system-dns" rel="noopener noreferrer"&gt;Domain Name System (DNS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#load-balancing" rel="noopener noreferrer"&gt;Load Balancing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#clustering" rel="noopener noreferrer"&gt;Clustering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#caching" rel="noopener noreferrer"&gt;Caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#content-delivery-network-cdn" rel="noopener noreferrer"&gt;Content Delivery Network (CDN)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#proxy" rel="noopener noreferrer"&gt;Proxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#availability" rel="noopener noreferrer"&gt;Availability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#scalability" rel="noopener noreferrer"&gt;Scalability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#storage" rel="noopener noreferrer"&gt;Storage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Chapter II&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#databases-and-dbms" rel="noopener noreferrer"&gt;Databases and DBMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-databases" rel="noopener noreferrer"&gt;SQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#nosql-databases" rel="noopener noreferrer"&gt;NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-vs-nosql-databases" rel="noopener noreferrer"&gt;SQL vs NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-replication" rel="noopener noreferrer"&gt;Database Replication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#indexes" rel="noopener noreferrer"&gt;Indexes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#normalization-and-denormalization" rel="noopener noreferrer"&gt;Normalization and Denormalization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#acid-and-base-consistency-models" rel="noopener noreferrer"&gt;ACID and BASE consistency models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#cap-theorem" rel="noopener noreferrer"&gt;CAP theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#pacelc-theorem" rel="noopener noreferrer"&gt;PACELC Theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#transactions" rel="noopener noreferrer"&gt;Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#distributed-transactions" rel="noopener noreferrer"&gt;Distributed Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#consistent-hashing" rel="noopener noreferrer"&gt;Consistent Hashing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-federation" rel="noopener noreferrer"&gt;Database Federation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Chapter III&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#n-tier-architecture" rel="noopener noreferrer"&gt;N-tier architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-brokers" rel="noopener noreferrer"&gt;Message Brokers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-queues" rel="noopener noreferrer"&gt;Message Queues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#publish-subscribe" rel="noopener noreferrer"&gt;Publish-Subscribe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#enterprise-service-bus-esb" rel="noopener noreferrer"&gt;Enterprise Service Bus (ESB)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#monoliths-and-microservices" rel="noopener noreferrer"&gt;Monoliths and Microservices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-driven-architecture-eda" rel="noopener noreferrer"&gt;Event-Driven Architecture (EDA)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-sourcing" rel="noopener noreferrer"&gt;Event Sourcing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#command-and-query-responsibility-segregation-cqrs" rel="noopener noreferrer"&gt;Command and Query Responsibility Segregation (CQRS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#api-gateway" rel="noopener noreferrer"&gt;API Gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#rest-graphql-grpc" rel="noopener noreferrer"&gt;REST, GraphQL, gRPC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#long-polling-websockets-server-sent-events-sse" rel="noopener noreferrer"&gt;Long polling, WebSockets, Server-Sent Events (SSE)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Chapter IV&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;…&lt;/li&gt;&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>distributedsystems</category>
      <category>architecture</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>System Design: Twitter</title>
      <dc:creator>Karan Pratap Singh</dc:creator>
      <pubDate>Thu, 22 Sep 2022 02:50:33 +0000</pubDate>
      <link>https://forem.com/karanpratapsingh/system-design-twitter-865</link>
      <guid>https://forem.com/karanpratapsingh/system-design-twitter-865</guid>
      <description>&lt;p&gt;Let's design a &lt;a href="https://twitter.com" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; like social media service, similar to services like &lt;a href="https://facebook.com" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt;, &lt;a href="https://instagram.com" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt;, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Twitter?
&lt;/h2&gt;

&lt;p&gt;Twitter is a social media service where users can read or post short messages (up to 280 characters) called tweets. It is available on the web and mobile platforms such as Android and iOS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;p&gt;Our system should meet the following requirements:&lt;/p&gt;

&lt;h3&gt;
  
  
  Functional requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Should be able to post new tweets (can be text, image, video, etc.).&lt;/li&gt;
&lt;li&gt;Should be able to follow other users.&lt;/li&gt;
&lt;li&gt;Should have a newsfeed feature consisting of tweets from the people the user is following.&lt;/li&gt;
&lt;li&gt;Should be able to search tweets.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Non-Functional requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;High availability with minimal latency.&lt;/li&gt;
&lt;li&gt;The system should be scalable and efficient.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extended requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Metrics and analytics.&lt;/li&gt;
&lt;li&gt;Retweet functionality.&lt;/li&gt;
&lt;li&gt;Favorite tweets.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Estimation and Constraints
&lt;/h2&gt;

&lt;p&gt;Let's start with the estimation and constraints.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Make sure to check any scale or traffic-related assumptions with your interviewer.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Traffic
&lt;/h3&gt;

&lt;p&gt;This will be a read-heavy system, let us assume we have 1 billion total users with 200 million daily active users (DAU), and on average each user tweets 5 times a day. This gives us 1 billion tweets per day.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;200 million×5 messages=1 billion/day
200 \space million \times 5 \space messages = 1 \space billion/day
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;200&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;mi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;5&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ess&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="mord mathnormal"&gt;es&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;bi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
Tweets can also contain media such as images, or videos. We can assume that 10 percent of tweets are media files shared by the users, which gives us additional 100 million files we would need to store.


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;10 percent×1 billion=100 million/day
10 \space percent \times 1 \space billion = 100 \space million/day
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;10&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="mord mathnormal"&gt;erce&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;bi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;mi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;strong&gt;What would be Requests Per Second (RPS) for our system?&lt;/strong&gt;

&lt;p&gt;1 billion requests per day translate into 12K requests per second.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;1 billion(24 hrs×3600 seconds)=∼12K requests/second
\frac{1 \space billion}{(24 \space hrs \times 3600 \space seconds)} = \sim 12K \space requests/second
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;24&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;h&lt;/span&gt;&lt;span class="mord mathnormal"&gt;rs&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3600&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;bi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;12&lt;/span&gt;&lt;span class="mord mathnormal"&gt;K&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;re&lt;/span&gt;&lt;span class="mord mathnormal"&gt;q&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mord mathnormal"&gt;es&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
### Storage

&lt;p&gt;If we assume each message on average is 100 bytes, we will require about 100 GB of database storage every day.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;1 billion×100 bytes=∼100 GB/day
1 \space billion \times 100 \space bytes = \sim 100 \space GB/day
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;bi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;es&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;GB&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
We also know that around 10 percent of our daily messages (100 million) are media files per our requirements. If we assume each file is 50 KB on average, we will require 5 TB of storage every day.


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;100 million×100 KB=5 TB/day
100 \space million \times 100 \space KB = 5 \space TB/day
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;mi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;K&lt;/span&gt;&lt;span class="mord mathnormal"&gt;B&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;5&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;TB&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
And for 10 years, we will require about 19 PB of storage.


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;(5 TB+0.1 TB)×365 days×10 years=∼19 PB
(5 \space TB + 0.1 \space TB) \times 365 \space days \times 10 \space years = \sim 19 \space PB
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;5&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;TB&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0.1&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;TB&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;365&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ys&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;10&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;ye&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;rs&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;19&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;PB&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
### Bandwidth

&lt;p&gt;As our system is handling 5.1 TB of ingress every day, we will a require minimum bandwidth of around 60 MB per second.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;5.1 TB(24 hrs×3600 seconds)=∼60 MB/second
\frac{5.1 \space TB}{(24 \space hrs \times 3600 \space seconds)} = \sim 60 \space MB/second
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;24&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;h&lt;/span&gt;&lt;span class="mord mathnormal"&gt;rs&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3600&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;5.1&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;TB&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;60&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;MB&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
### High-level estimate

&lt;p&gt;Here is our high-level estimate:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Estimate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Daily active users (DAU)&lt;/td&gt;
&lt;td&gt;100 million&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Requests per second (RPS)&lt;/td&gt;
&lt;td&gt;12K/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage (per day)&lt;/td&gt;
&lt;td&gt;~5.1 TB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage (10 years)&lt;/td&gt;
&lt;td&gt;~19 PB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bandwidth&lt;/td&gt;
&lt;td&gt;~60 MB/s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Data model design
&lt;/h2&gt;

&lt;p&gt;This is the general data model which reflects our requirements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6b9r8l506aymnwx2chqs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6b9r8l506aymnwx2chqs.png" alt="twitter-datamodel" width="800" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have the following tables:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;users&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This table will contain a user's information such as &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;, &lt;code&gt;dob&lt;/code&gt;, and other details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;tweets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As the name suggests, this table will store tweets and their properties such as &lt;code&gt;type&lt;/code&gt; (text, image, video, etc.), &lt;code&gt;content&lt;/code&gt;, etc. We will also store the corresponding &lt;code&gt;userID&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;favorites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This table maps tweets with users for the favorite tweets functionality in our application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;followers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This table maps the followers and &lt;a href="https://en.wiktionary.org/wiki/followee" rel="noopener noreferrer"&gt;followees&lt;/a&gt; as users can follow each other (N:M relationship).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;feeds&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This table stores feed properties with the corresponding &lt;code&gt;userID&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;feeds_tweets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This table maps tweets and feed (N:M relationship).&lt;/p&gt;
&lt;h3&gt;
  
  
  What kind of database should we use?
&lt;/h3&gt;

&lt;p&gt;While our data model seems quite relational, we don't necessarily need to store everything in a single database, as this can limit our scalability and quickly become a bottleneck.&lt;/p&gt;

&lt;p&gt;We will split the data between different services each having ownership over a particular table. Then we can use a relational database such as &lt;a href="https://www.postgresql.org" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt; or a distributed NoSQL database such as &lt;a href="https://cassandra.apache.org/_/index.html" rel="noopener noreferrer"&gt;Apache Cassandra&lt;/a&gt; for our use case.&lt;/p&gt;
&lt;h2&gt;
  
  
  API design
&lt;/h2&gt;

&lt;p&gt;Let us do a basic API design for our services:&lt;/p&gt;
&lt;h3&gt;
  
  
  Post a tweet
&lt;/h3&gt;

&lt;p&gt;This API will allow the user to post a tweet on the platform.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;postTweet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mediaURL&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;User ID (&lt;code&gt;UUID&lt;/code&gt;): ID of the user.&lt;/p&gt;

&lt;p&gt;Content (&lt;code&gt;string&lt;/code&gt;): Contents of the tweet.&lt;/p&gt;

&lt;p&gt;Media URL (&lt;code&gt;string&lt;/code&gt;): URL of the attached media &lt;em&gt;(optional)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Returns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Result (&lt;code&gt;boolean&lt;/code&gt;): Represents whether the operation was successful or not.&lt;/p&gt;
&lt;h3&gt;
  
  
  Follow or unfollow a user
&lt;/h3&gt;

&lt;p&gt;This API will allow the user to follow or unfollow another user.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;follow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;followerID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;followeeID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;span class="nf"&gt;unfollow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;followerID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;followeeID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Follower ID (&lt;code&gt;UUID&lt;/code&gt;): ID of the current user.&lt;/p&gt;

&lt;p&gt;Followee ID (&lt;code&gt;UUID&lt;/code&gt;): ID of the user we want to follow or unfollow.&lt;/p&gt;

&lt;p&gt;Media URL (&lt;code&gt;string&lt;/code&gt;): URL of the attached media &lt;em&gt;(optional)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Returns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Result (&lt;code&gt;boolean&lt;/code&gt;): Represents whether the operation was successful or not.&lt;/p&gt;
&lt;h3&gt;
  
  
  Get newsfeed
&lt;/h3&gt;

&lt;p&gt;This API will return all the tweets to be shown within a given newsfeed.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;getNewsfeed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Tweet&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;User ID (&lt;code&gt;UUID&lt;/code&gt;): ID of the user.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Returns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tweets (&lt;code&gt;Tweet[]&lt;/code&gt;): All the tweets to be shown within a given newsfeed.&lt;/p&gt;
&lt;h2&gt;
  
  
  High-level design
&lt;/h2&gt;

&lt;p&gt;Now let us do a high-level design of our system.&lt;/p&gt;
&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;

&lt;p&gt;We will be using &lt;a href="https://karanpratapsingh.com/courses/system-design/monoliths-microservices#microservices" rel="noopener noreferrer"&gt;microservices architecture&lt;/a&gt; since it will make it easier to horizontally scale and decouple our services. Each service will have ownership of its own data model. Let's try to divide our system into some core services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This service handles user-related concerns such as authentication and user information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Newsfeed Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This service will handle the generation and publishing of user newsfeeds. It will be discussed in detail separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tweet Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The tweet service will handle tweet-related use cases such as posting a tweet, favorites, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Search Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The service is responsible for handling search-related functionality. It will be discussed in detail separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Media service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This service will handle the media (images, videos, files, etc.) uploads. It will be discussed in detail separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notification Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This service will simply send push notifications to the users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Analytics Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This service will be used for metrics and analytics use cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What about inter-service communication and service discovery?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Since our architecture is microservices-based, services will be communicating with each other as well. Generally, REST or HTTP performs well but we can further improve the performance using &lt;a href="https://karanpratapsingh.com/courses/system-design/rest-graphql-grpc#grpc" rel="noopener noreferrer"&gt;gRPC&lt;/a&gt; which is more lightweight and efficient.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://karanpratapsingh.com/courses/system-design/service-discovery" rel="noopener noreferrer"&gt;Service discovery&lt;/a&gt; is another thing we will have to take into account. We can also use a service mesh that enables managed, observable, and secure communication between individual services.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Learn more about &lt;a href="https://karanpratapsingh.com/courses/system-design/rest-graphql-grpc" rel="noopener noreferrer"&gt;REST, GraphQL, gRPC&lt;/a&gt; and how they compare with each other.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Newsfeed
&lt;/h3&gt;

&lt;p&gt;When it comes to the newsfeed, it seems easy enough to implement, but there are a lot of things that can make or break this feature. So, let's divide our problem into two parts:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's assume we want to generate the feed for user A, we will perform the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Retrieve the IDs of all the users and entities (hashtags, topics, etc.) user A follows.&lt;/li&gt;
&lt;li&gt;Fetch the relevant tweets for each of the retrieved IDs.&lt;/li&gt;
&lt;li&gt;Use a ranking algorithm to rank the tweets based on parameters such as relevance, time, engagement, etc.&lt;/li&gt;
&lt;li&gt;Return the ranked tweets data to the client in a paginated manner.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Feed generation is an intensive process and can take quite a lot of time, especially for users following a lot of people. To improve the performance, the feed can be pre-generated and stored in the cache, then we can have a mechanism to periodically update the feed and apply our ranking algorithm to the new tweets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Publishing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Publishing is the step where the feed data is pushed according to each specific user. This can be a quite heavy operation, as a user may have millions of friends or followers. To deal with this, we have three different approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pull Model (or Fan-out on load)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwo5k9zv9xtb4usfp8z40.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwo5k9zv9xtb4usfp8z40.png" alt="newsfeed-pull-model" width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When a user creates a tweet, and a follower reloads their newsfeed, the feed is created and stored in memory. The most recent feed is only loaded when the user requests it. This approach reduces the number of write operations on our database.&lt;/p&gt;

&lt;p&gt;The downside of this approach is that the users will not be able to view recent feeds unless they "pull" the data from the server, which will increase the number of read operations on the server.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Push Model (or Fan-out on write)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5au8ruifa6gkvaca66ze.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5au8ruifa6gkvaca66ze.png" alt="newsfeed-push-model" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this model, once a user creates a tweet, it is "pushed" to all the follower's feeds immediately. This prevents the system from having to go through a user's entire followers list to check for updates.&lt;/p&gt;

&lt;p&gt;However, the downside of this approach is that it would increase the number of write operations on the database.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hybrid Model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A third approach is a hybrid model between the pull and push model. It combines the beneficial features of the above two models and tries to provide a balanced approach between the two.&lt;/p&gt;

&lt;p&gt;The hybrid model allows only users with a lesser number of followers to use the push model and for users with a higher number of followers celebrities, the pull model will be used.&lt;/p&gt;
&lt;h3&gt;
  
  
  Ranking Algorithm
&lt;/h3&gt;

&lt;p&gt;As we discussed, we will need a ranking algorithm to rank each tweet according to its relevance to each specific user.&lt;/p&gt;

&lt;p&gt;For example, Facebook used to utilize an &lt;a href="https://en.wikipedia.org/wiki/EdgeRank" rel="noopener noreferrer"&gt;EdgeRank&lt;/a&gt; algorithm, here, the rank of each feed item is described by:&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;Rank=Affinity×Weight×Decay
Rank = Affinity \times Weight \times Decay
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;R&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ank&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;A&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ff&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ini&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;W&lt;/span&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="mord mathnormal"&gt;h&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;Dec&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;

&lt;p&gt;Where,&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Affinity&lt;/code&gt;: is the "closeness" of the user to the creator of the edge. If a user frequently likes, comments, or messages the edge creator, then the value of affinity will be higher, resulting in a higher rank for the post.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Weight&lt;/code&gt;: is the value assigned according to each edge. A comment can have a higher weightage than likes, and thus a post with more comments is more likely to get a higher rank.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Decay&lt;/code&gt;: is the measure of the creation of the edge. The older the edge, the lesser will be the value of decay and eventually the rank.&lt;/p&gt;

&lt;p&gt;Nowadays, algorithms are much more complex and ranking is done using machine learning models which can take thousands of factors into consideration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Retweets
&lt;/h3&gt;

&lt;p&gt;Retweets are one of our extended requirements. To implement this feature we can simply create a new tweet with the user id of the user retweeting the original tweet and then modify the &lt;code&gt;type&lt;/code&gt; enum and &lt;code&gt;content&lt;/code&gt; property of the new tweet to link it with the original tweet.&lt;/p&gt;

&lt;p&gt;For example, the &lt;code&gt;type&lt;/code&gt; enum property can be of type tweet, similar to text, video, etc and &lt;code&gt;content&lt;/code&gt; can be the id of the original tweet. Here the first row indicates the original tweet while the second row is how we can represent a retweet.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;id&lt;/th&gt;
&lt;th&gt;userID&lt;/th&gt;
&lt;th&gt;type&lt;/th&gt;
&lt;th&gt;content&lt;/th&gt;
&lt;th&gt;createdAt&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ad34-291a-45f6-b36c&lt;/td&gt;
&lt;td&gt;7a2c-62c4-4dc8-b1bb&lt;/td&gt;
&lt;td&gt;text&lt;/td&gt;
&lt;td&gt;Hey, this is my first tweet…&lt;/td&gt;
&lt;td&gt;1658905644054&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;f064-49ad-9aa2-84a6&lt;/td&gt;
&lt;td&gt;6aa2-2bc9-4331-879f&lt;/td&gt;
&lt;td&gt;tweet&lt;/td&gt;
&lt;td&gt;ad34-291a-45f6-b36c&lt;/td&gt;
&lt;td&gt;1658906165427&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is a very basic implementation, to improve this we can create a separate table itself to store retweets.&lt;/p&gt;

&lt;h3&gt;
  
  
  Search
&lt;/h3&gt;

&lt;p&gt;Sometimes traditional DBMS are not performant enough, we need something which allows us to store, search, and analyze huge volumes of data quickly and in near real-time and give results within milliseconds. &lt;a href="https://www.elastic.co" rel="noopener noreferrer"&gt;Elasticsearch&lt;/a&gt; can help us with this use case.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.elastic.co" rel="noopener noreferrer"&gt;Elasticsearch&lt;/a&gt; is a distributed, free and open search and analytics engine for all types of data, including textual, numerical, geospatial, structured, and unstructured. It is built on top of &lt;a href="https://lucene.apache.org" rel="noopener noreferrer"&gt;Apache Lucene&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do we identify trending topics?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Trending functionality will be based on top of the search functionality. We can cache the most frequently searched queries, hashtags, and topics in the last &lt;code&gt;N&lt;/code&gt; seconds and update them every &lt;code&gt;M&lt;/code&gt; seconds using some sort of batch job mechanism. Our ranking algorithm can also be applied to the trending topics to give them more weight and personalize them for the user.&lt;/p&gt;

&lt;h3&gt;
  
  
  Notifications
&lt;/h3&gt;

&lt;p&gt;Push notifications are an integral part of any social media platform. We can use a message queue or a message broker such as &lt;a href="https://kafka.apache.org" rel="noopener noreferrer"&gt;Apache Kafka&lt;/a&gt; with the notification service to dispatch requests to &lt;a href="https://firebase.google.com/docs/cloud-messaging" rel="noopener noreferrer"&gt;Firebase Cloud Messaging (FCM)&lt;/a&gt; or &lt;a href="https://developer.apple.com/documentation/usernotifications" rel="noopener noreferrer"&gt;Apple Push Notification Service (APNS)&lt;/a&gt; which will handle the delivery of the push notifications to user devices.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For more details, refer to the &lt;a href="https://karanpratapsingh.com/courses/system-design/whatsapp#notifications" rel="noopener noreferrer"&gt;Whatsapp&lt;/a&gt; system design where we discuss push notifications.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Detailed design
&lt;/h2&gt;

&lt;p&gt;It's time to discuss our design decisions in detail.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Partitioning
&lt;/h3&gt;

&lt;p&gt;To scale out our databases we will need to partition our data. Horizontal partitioning (aka &lt;a href="https://karanpratapsingh.com/courses/system-design/sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt;) can be a good first step. We can use partitions schemes such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hash-Based Partitioning&lt;/li&gt;
&lt;li&gt;List-Based Partitioning&lt;/li&gt;
&lt;li&gt;Range Based Partitioning&lt;/li&gt;
&lt;li&gt;Composite Partitioning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The above approaches can still cause uneven data and load distribution, we can solve this using &lt;a href="https://karanpratapsingh.com/courses/system-design/consistent-hashing" rel="noopener noreferrer"&gt;Consistent hashing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For more details, refer to &lt;a href="https://karanpratapsingh.com/courses/system-design/sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt; and &lt;a href="https://karanpratapsingh.com/courses/system-design/consistent-hashing" rel="noopener noreferrer"&gt;Consistent Hashing&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Mutual friends
&lt;/h3&gt;

&lt;p&gt;For mutual friends, we can build a social graph for every user. Each node in the graph will represent a user and a directional edge will represent followers and followees. After that, we can traverse the followers of a user to find and suggest a mutual friend. This would require a graph database such as &lt;a href="https://neo4j.com" rel="noopener noreferrer"&gt;Neo4j&lt;/a&gt; and &lt;a href="https://www.arangodb.com" rel="noopener noreferrer"&gt;ArangoDB&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is a pretty simple algorithm, to improve our suggestion accuracy, we will need to incorporate a recommendation model which uses machine learning as part of our algorithm.&lt;/p&gt;

&lt;h3&gt;
  
  
  Metrics and Analytics
&lt;/h3&gt;

&lt;p&gt;Recording analytics and metrics is one of our extended requirements. As we will be using &lt;a href="https://kafka.apache.org" rel="noopener noreferrer"&gt;Apache Kafka&lt;/a&gt; to publish all sorts of events, we can process these events and run analytics on the data using &lt;a href="https://spark.apache.org" rel="noopener noreferrer"&gt;Apache Spark&lt;/a&gt; which is an open-source unified analytics engine for large-scale data processing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Caching
&lt;/h3&gt;

&lt;p&gt;In a social media application, we have to be careful about using cache as our users expect the latest data. So, to prevent usage spikes from our resources we can cache the top 20% of the tweets.&lt;/p&gt;

&lt;p&gt;To further improve efficiency we can add pagination to our system APIs. This decision will be helpful for users with limited network bandwidth as they won't have to retrieve old messages unless requested.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which cache eviction policy to use?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We can use solutions like &lt;a href="https://redis.io" rel="noopener noreferrer"&gt;Redis&lt;/a&gt; or &lt;a href="https://memcached.org" rel="noopener noreferrer"&gt;Memcached&lt;/a&gt; and cache 20% of the daily traffic but what kind of cache eviction policy would best fit our needs?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)" rel="noopener noreferrer"&gt;Least Recently Used (LRU)&lt;/a&gt; can be a good policy for our system. In this policy, we discard the least recently used key first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to handle cache miss?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Whenever there is a cache miss, our servers can hit the database directly and update the cache with the new entries.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For more details, refer to &lt;a href="https://karanpratapsingh.com/courses/system-design/caching" rel="noopener noreferrer"&gt;Caching&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Media access and storage
&lt;/h3&gt;

&lt;p&gt;As we know, most of our storage space will be used for storing media files such as images, videos, or other files. Our media service will be handling both access and storage of the user media files.&lt;/p&gt;

&lt;p&gt;But where can we store files at scale? Well, &lt;a href="https://karanpratapsingh.com/courses/system-design/storage#object-storage" rel="noopener noreferrer"&gt;object storage&lt;/a&gt; is what we're looking for. Object stores break data files up into pieces called objects. It then stores those objects in a single repository, which can be spread out across multiple networked systems. We can also use distributed file storage such as &lt;a href="https://karanpratapsingh.com/courses/system-design/storage#hdfs" rel="noopener noreferrer"&gt;HDFS&lt;/a&gt; or &lt;a href="https://www.gluster.org" rel="noopener noreferrer"&gt;GlusterFS&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Content Delivery Network (CDN)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://karanpratapsingh.com/courses/system-design/content-delivery-network" rel="noopener noreferrer"&gt;Content Delivery Network (CDN)&lt;/a&gt; increases content availability and redundancy while reducing bandwidth costs. Generally, static files such as images, and videos are served from CDN. We can use services like &lt;a href="https://aws.amazon.com/cloudfront" rel="noopener noreferrer"&gt;Amazon CloudFront&lt;/a&gt; or &lt;a href="https://www.cloudflare.com/cdn" rel="noopener noreferrer"&gt;Cloudflare CDN&lt;/a&gt; for this use case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Identify and resolve bottlenecks
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxghfib4234iqv023dcos.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxghfib4234iqv023dcos.png" alt="twitter-advanced-design" width="800" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let us identify and resolve bottlenecks such as single points of failure in our design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"What if one of our services crashes?"&lt;/li&gt;
&lt;li&gt;"How will we distribute our traffic between our components?"&lt;/li&gt;
&lt;li&gt;"How can we reduce the load on our database?"&lt;/li&gt;
&lt;li&gt;"How to improve the availability of our cache?"&lt;/li&gt;
&lt;li&gt;"How can we make our notification system more robust?"&lt;/li&gt;
&lt;li&gt;"How can we reduce media storage costs"?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To make our system more resilient we can do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running multiple instances of each of our services.&lt;/li&gt;
&lt;li&gt;Introducing &lt;a href="https://karanpratapsingh.com/courses/system-design/load-balancing" rel="noopener noreferrer"&gt;load balancers&lt;/a&gt; between clients, servers, databases, and cache servers.&lt;/li&gt;
&lt;li&gt;Using multiple read replicas for our databases.&lt;/li&gt;
&lt;li&gt;Multiple instances and replicas for our distributed cache.&lt;/li&gt;
&lt;li&gt;Exactly once delivery and message ordering is challenging in a distributed system, we can use a dedicated &lt;a href="https://karanpratapsingh.com/courses/system-design/message-brokers" rel="noopener noreferrer"&gt;message broker&lt;/a&gt; such as &lt;a href="https://kafka.apache.org" rel="noopener noreferrer"&gt;Apache Kafka&lt;/a&gt; or &lt;a href="https://nats.io" rel="noopener noreferrer"&gt;NATS&lt;/a&gt; to make our notification system more robust.&lt;/li&gt;
&lt;li&gt;We can add media processing and compression capabilities to the media service to compress large files which will save a lot of storage space and reduce cost.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;This article is part of my open source &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;System Design Course&lt;/a&gt; available on Github.&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/karanpratapsingh" rel="noopener noreferrer"&gt;
        karanpratapsingh
      &lt;/a&gt; / &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;
        system-design
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Learn how to design systems at scale and prepare for system design interviews
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;System Design&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Hey, welcome to the course. I hope this course provides a great learning experience.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This course is also available on my &lt;a href="https://karanpratapsingh.com/courses/system-design" rel="nofollow noopener noreferrer"&gt;website&lt;/a&gt; and as an ebook on &lt;a href="https://leanpub.com/systemdesign" rel="nofollow noopener noreferrer"&gt;leanpub&lt;/a&gt;. Please leave a ⭐ as motivation if this was helpful!&lt;/em&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Table of contents&lt;/h1&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#what-is-system-design" rel="noopener noreferrer"&gt;What is system design?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter I&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#ip" rel="noopener noreferrer"&gt;IP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#osi-model" rel="noopener noreferrer"&gt;OSI Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#tcp-and-udp" rel="noopener noreferrer"&gt;TCP and UDP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#domain-name-system-dns" rel="noopener noreferrer"&gt;Domain Name System (DNS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#load-balancing" rel="noopener noreferrer"&gt;Load Balancing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#clustering" rel="noopener noreferrer"&gt;Clustering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#caching" rel="noopener noreferrer"&gt;Caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#content-delivery-network-cdn" rel="noopener noreferrer"&gt;Content Delivery Network (CDN)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#proxy" rel="noopener noreferrer"&gt;Proxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#availability" rel="noopener noreferrer"&gt;Availability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#scalability" rel="noopener noreferrer"&gt;Scalability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#storage" rel="noopener noreferrer"&gt;Storage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter II&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#databases-and-dbms" rel="noopener noreferrer"&gt;Databases and DBMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-databases" rel="noopener noreferrer"&gt;SQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#nosql-databases" rel="noopener noreferrer"&gt;NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-vs-nosql-databases" rel="noopener noreferrer"&gt;SQL vs NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-replication" rel="noopener noreferrer"&gt;Database Replication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#indexes" rel="noopener noreferrer"&gt;Indexes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#normalization-and-denormalization" rel="noopener noreferrer"&gt;Normalization and Denormalization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#acid-and-base-consistency-models" rel="noopener noreferrer"&gt;ACID and BASE consistency models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#cap-theorem" rel="noopener noreferrer"&gt;CAP theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#pacelc-theorem" rel="noopener noreferrer"&gt;PACELC Theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#transactions" rel="noopener noreferrer"&gt;Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#distributed-transactions" rel="noopener noreferrer"&gt;Distributed Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#consistent-hashing" rel="noopener noreferrer"&gt;Consistent Hashing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-federation" rel="noopener noreferrer"&gt;Database Federation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter III&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#n-tier-architecture" rel="noopener noreferrer"&gt;N-tier architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-brokers" rel="noopener noreferrer"&gt;Message Brokers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-queues" rel="noopener noreferrer"&gt;Message Queues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#publish-subscribe" rel="noopener noreferrer"&gt;Publish-Subscribe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#enterprise-service-bus-esb" rel="noopener noreferrer"&gt;Enterprise Service Bus (ESB)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#monoliths-and-microservices" rel="noopener noreferrer"&gt;Monoliths and Microservices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-driven-architecture-eda" rel="noopener noreferrer"&gt;Event-Driven Architecture (EDA)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-sourcing" rel="noopener noreferrer"&gt;Event Sourcing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#command-and-query-responsibility-segregation-cqrs" rel="noopener noreferrer"&gt;Command and Query Responsibility Segregation (CQRS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#api-gateway" rel="noopener noreferrer"&gt;API Gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#rest-graphql-grpc" rel="noopener noreferrer"&gt;REST, GraphQL, gRPC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#long-polling-websockets-server-sent-events-sse" rel="noopener noreferrer"&gt;Long polling, WebSockets, Server-Sent Events (SSE)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter IV&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;…&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>distributedsystems</category>
      <category>architecture</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>System Design: WhatsApp</title>
      <dc:creator>Karan Pratap Singh</dc:creator>
      <pubDate>Wed, 21 Sep 2022 05:44:12 +0000</pubDate>
      <link>https://forem.com/karanpratapsingh/system-design-whatsapp-fld</link>
      <guid>https://forem.com/karanpratapsingh/system-design-whatsapp-fld</guid>
      <description>&lt;p&gt;Let's design a &lt;a href="https://whatsapp.com" rel="noopener noreferrer"&gt;Whatsapp&lt;/a&gt; like instant messaging service, similar to services like &lt;a href="https://www.whatsapp.com" rel="noopener noreferrer"&gt;Whatsapp&lt;/a&gt;, &lt;a href="https://www.messenger.com" rel="noopener noreferrer"&gt;Facebook Messenger&lt;/a&gt;, and &lt;a href="https://www.wechat.com" rel="noopener noreferrer"&gt;WeChat&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Whatsapp?
&lt;/h2&gt;

&lt;p&gt;Whatsapp is a chat application that provides instant messaging services to its users. It is one of the most used mobile applications on the planet connecting over 2 billion users in 180+ countries. Whatsapp is also available on the web.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;p&gt;Our system should meet the following requirements:&lt;/p&gt;

&lt;h3&gt;
  
  
  Functional requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Should support one-on-one chat.&lt;/li&gt;
&lt;li&gt;Group chats (max 100 people).&lt;/li&gt;
&lt;li&gt;Should support file sharing (image, video, etc.).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Non-functional requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;High availability with minimal latency.&lt;/li&gt;
&lt;li&gt;The system should be scalable and efficient.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extended requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Sent, Delivered, and Read receipts of the messages.&lt;/li&gt;
&lt;li&gt;Show the last seen time of users.&lt;/li&gt;
&lt;li&gt;Push notifications.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Estimation and Constraints
&lt;/h2&gt;

&lt;p&gt;Let's start with the estimation and constraints.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Make sure to check any scale or traffic-related assumptions with your interviewer.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Traffic
&lt;/h3&gt;

&lt;p&gt;Let us assume we have 50 million daily active users (DAU) and on average each user sends at least 10 messages to 4 different people every day. This gives us 2 billion messages per day.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;50 million×20 messages=2 billion/day
50 \space million \times 20 \space messages = 2 \space billion/day
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;50&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;mi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;20&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ess&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="mord mathnormal"&gt;es&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;bi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
Messages can also contain media such as images, videos, or other files. We can assume that 5 percent of messages are media files shared by the users, which gives us additional 200 million files we would need to store.


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;5 percent×2 billion=200 million/day
5 \space percent \times 2 \space billion = 200 \space million/day
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;5&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="mord mathnormal"&gt;erce&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;bi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;200&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;mi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;strong&gt;What would be Requests Per Second (RPS) for our system?&lt;/strong&gt;

&lt;p&gt;2 billion requests per day translate into 24K requests per second.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;2 billion(24 hrs×3600 seconds)=∼24K requests/second
\frac{2 \space billion}{(24 \space hrs \times 3600 \space seconds)} = \sim 24K \space requests/second
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;24&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;h&lt;/span&gt;&lt;span class="mord mathnormal"&gt;rs&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3600&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;bi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;24&lt;/span&gt;&lt;span class="mord mathnormal"&gt;K&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;re&lt;/span&gt;&lt;span class="mord mathnormal"&gt;q&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mord mathnormal"&gt;es&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
### Storage

&lt;p&gt;If we assume each message on average is 100 bytes, we will require about 200 GB of database storage every day.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;2 billion×100 bytes=∼200 GB/day
2 \space billion \times 100 \space bytes = \sim 200 \space GB/day
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;bi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;es&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;200&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;GB&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
As per our requirements, we also know that around 5 percent of our daily messages (100 million) are media files. If we assume each file is 50 KB on average, we will require 10 TB of storage every day.


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;100 million×100 KB=10 TB/day
100 \space million \times 100 \space KB = 10 \space TB/day
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;mi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;K&lt;/span&gt;&lt;span class="mord mathnormal"&gt;B&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;10&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;TB&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
And for 10 years, we will require about 38 PB of storage.


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;(10 TB+0.2 TB)×10 years×365 days=∼38 PB
(10 \space TB + 0.2 \space TB) \times 10 \space years \times 365 \space days = \sim 38 \space PB
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;10&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;TB&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0.2&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;TB&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;10&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;ye&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;rs&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;365&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ys&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;38&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;PB&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
### Bandwidth

&lt;p&gt;As our system is handling 10.2 TB of ingress every day, we will a require minimum bandwidth of around 120 MB per second.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;10.2 TB(24 hrs×3600 seconds)=∼120 MB/second
\frac{10.2 \space TB}{(24 \space hrs \times 3600 \space seconds)} = \sim 120 \space MB/second
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;24&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;h&lt;/span&gt;&lt;span class="mord mathnormal"&gt;rs&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3600&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;10.2&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;TB&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;120&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;MB&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
### High-level estimate

&lt;p&gt;Here is our high-level estimate:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Estimate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Daily active users (DAU)&lt;/td&gt;
&lt;td&gt;50 million&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Requests per second (RPS)&lt;/td&gt;
&lt;td&gt;24K/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage (per day)&lt;/td&gt;
&lt;td&gt;~10.2 TB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage (10 years)&lt;/td&gt;
&lt;td&gt;~38 PB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bandwidth&lt;/td&gt;
&lt;td&gt;~120 MB/s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Data model design
&lt;/h2&gt;

&lt;p&gt;This is the general data model which reflects our requirements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd6ivl6es8tyco7ogxzkr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd6ivl6es8tyco7ogxzkr.png" alt="whatsapp-datamodel" width="800" height="612"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have the following tables:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;users&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This table will contain a user's information such as &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;phoneNumber&lt;/code&gt;, and other details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;messages&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As the name suggests, this table will store messages with properties such as &lt;code&gt;type&lt;/code&gt; (text, image, video, etc.), &lt;code&gt;content&lt;/code&gt;, and timestamps for message delivery. The message will also have a corresponding &lt;code&gt;chatID&lt;/code&gt; or &lt;code&gt;groupID&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;chats&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This table basically represents a private chat between two users and can contain multiple messages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;users_chats&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This table maps users and chats as multiple users can have multiple chats (N:M relationship) and vice versa.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;groups&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This table represents a group between multiple users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;users_groups&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This table maps users and groups as multiple users can be a part of multiple groups (N:M relationship) and vice versa.&lt;/p&gt;
&lt;h3&gt;
  
  
  What kind of database should we use?
&lt;/h3&gt;

&lt;p&gt;While our data model seems quite relational, we don't necessarily need to store everything in a single database, as this can limit our scalability and quickly become a bottleneck.&lt;/p&gt;

&lt;p&gt;We will split the data between different services each having ownership over a particular table. Then we can use a relational database such as &lt;a href="https://www.postgresql.org" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt; or a distributed NoSQL database such as &lt;a href="https://cassandra.apache.org/_/index.html" rel="noopener noreferrer"&gt;Apache Cassandra&lt;/a&gt; for our use case.&lt;/p&gt;
&lt;h2&gt;
  
  
  API design
&lt;/h2&gt;

&lt;p&gt;Let us do a basic API design for our services:&lt;/p&gt;
&lt;h3&gt;
  
  
  Get all chats or groups
&lt;/h3&gt;

&lt;p&gt;This API will get all chats or groups for a given &lt;code&gt;userID&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;getAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Chat&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Group&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;User ID (&lt;code&gt;UUID&lt;/code&gt;): ID of the current user.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Returns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Result (&lt;code&gt;Chat[] | Group[]&lt;/code&gt;): All the chats and groups the user is a part of.&lt;/p&gt;
&lt;h3&gt;
  
  
  Get messages
&lt;/h3&gt;

&lt;p&gt;Get all messages for a user given the &lt;code&gt;channelID&lt;/code&gt; (chat or group id).&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;getMessages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;channelID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;User ID (&lt;code&gt;UUID&lt;/code&gt;): ID of the current user.&lt;/p&gt;

&lt;p&gt;Channel ID (&lt;code&gt;UUID&lt;/code&gt;): ID of the channel (chat or group) from which messages need to be retrieved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Returns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Messages (&lt;code&gt;Message[]&lt;/code&gt;): All the messages in a given chat or group.&lt;/p&gt;
&lt;h3&gt;
  
  
  Send message
&lt;/h3&gt;

&lt;p&gt;Send a message from a user to a channel (chat or group).&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;channelID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;User ID (&lt;code&gt;UUID&lt;/code&gt;): ID of the current user.&lt;/p&gt;

&lt;p&gt;Channel ID (&lt;code&gt;UUID&lt;/code&gt;): ID of the channel (chat or group) user wants to send a message to.&lt;/p&gt;

&lt;p&gt;Message (&lt;code&gt;Message&lt;/code&gt;): The message (text, image, video, etc.) that the user wants to send.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Returns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Result (&lt;code&gt;boolean&lt;/code&gt;): Represents whether the operation was successful or not.&lt;/p&gt;
&lt;h3&gt;
  
  
  Join or leave a group
&lt;/h3&gt;

&lt;p&gt;Send a message from a user to a channel (chat or group).&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;joinGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;channelID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;span class="nf"&gt;leaveGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;channelID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;User ID (&lt;code&gt;UUID&lt;/code&gt;): ID of the current user.&lt;/p&gt;

&lt;p&gt;Channel ID (&lt;code&gt;UUID&lt;/code&gt;): ID of the channel (chat or group) the user wants to join or leave.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Returns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Result (&lt;code&gt;boolean&lt;/code&gt;): Represents whether the operation was successful or not.&lt;/p&gt;
&lt;h2&gt;
  
  
  High-level design
&lt;/h2&gt;

&lt;p&gt;Now let us do a high-level design of our system.&lt;/p&gt;
&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;

&lt;p&gt;We will be using &lt;a href="https://karanpratapsingh.com/courses/system-design/monoliths-microservices#microservices" rel="noopener noreferrer"&gt;microservices architecture&lt;/a&gt; since it will make it easier to horizontally scale and decouple our services. Each service will have ownership of its own data model. Let's try to divide our system into some core services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is an HTTP-based service that handles user-related concerns such as authentication and user information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chat Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The chat service will use WebSockets and establish connections with the client to handle chat and group message-related functionality. We can also use cache to keep track of all the active connections sort of like sessions which will help us determine if the user is online or not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notification Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This service will simply send push notifications to the users. It will be discussed in detail separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Presence Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The presence service will keep track of the last seen status of all users. It will be discussed in detail separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Media service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This service will handle the media (images, videos, files, etc.) uploads. It will be discussed in detail separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What about inter-service communication and service discovery?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Since our architecture is microservices-based, services will be communicating with each other as well. Generally, REST or HTTP performs well but we can further improve the performance using &lt;a href="https://karanpratapsingh.com/courses/system-design/rest-graphql-grpc#grpc" rel="noopener noreferrer"&gt;gRPC&lt;/a&gt; which is more lightweight and efficient.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://karanpratapsingh.com/courses/system-design/service-discovery" rel="noopener noreferrer"&gt;Service discovery&lt;/a&gt; is another thing we will have to take into account. We can also use a service mesh that enables managed, observable, and secure communication between individual services.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Learn more about &lt;a href="https://karanpratapsingh.com/courses/system-design/rest-graphql-grpc" rel="noopener noreferrer"&gt;REST, GraphQL, gRPC&lt;/a&gt; and how they compare with each other.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Real-time messaging
&lt;/h3&gt;

&lt;p&gt;How do we efficiently send and receive messages? We have two different options:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pull model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The client can periodically send an HTTP request to servers to check if there are any new messages. This can be achieved via something like &lt;a href="https://karanpratapsingh.com/courses/system-design/long-polling-websockets-server-sent-events#long-polling" rel="noopener noreferrer"&gt;Long polling&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Push model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The client opens a long-lived connection with the server and once new data is available it will be pushed to the client. We can use &lt;a href="https://karanpratapsingh.com/courses/system-design/long-polling-websockets-server-sent-events#websockets" rel="noopener noreferrer"&gt;WebSockets&lt;/a&gt; or &lt;a href="https://karanpratapsingh.com/courses/system-design/long-polling-websockets-server-sent-events#server-sent-events-sse" rel="noopener noreferrer"&gt;Server-Sent Events (SSE)&lt;/a&gt; for this.&lt;/p&gt;

&lt;p&gt;The pull model approach is not scalable as it will create unnecessary request overhead on our servers and most of the time the response will be empty, thus wasting our resources. To minimize latency, using the push model with &lt;a href="https://karanpratapsingh.com/courses/system-design/long-polling-websockets-server-sent-events#websockets" rel="noopener noreferrer"&gt;WebSockets&lt;/a&gt; is a better choice because then we can push data to the client once it's available without any delay given the connection is open with the client. Also, WebSockets provide full-duplex communication, unlike &lt;a href="https://karanpratapsingh.com/courses/system-design/long-polling-websockets-server-sent-events#server-sent-events-sse" rel="noopener noreferrer"&gt;Server-Sent Events (SSE)&lt;/a&gt; which are only unidirectional.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Learn more about &lt;a href="https://karanpratapsingh.com/courses/system-design/long-polling-websockets-server-sent-events" rel="noopener noreferrer"&gt;Long polling, WebSockets, Server-Sent Events (SSE)&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Last seen
&lt;/h3&gt;

&lt;p&gt;To implement the last seen functionality, we can use a &lt;a href="https://en.wikipedia.org/wiki/Heartbeat_(computing)" rel="noopener noreferrer"&gt;heartbeat&lt;/a&gt; mechanism, where the client can periodically ping the servers indicating its liveness. Since this needs to be as low overhead as possible, we can store the last active timestamp in the cache as follows:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Key&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;User A&lt;/td&gt;
&lt;td&gt;2022-07-01T14:32:50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User B&lt;/td&gt;
&lt;td&gt;2022-07-05T05:10:35&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User C&lt;/td&gt;
&lt;td&gt;2022-07-10T04:33:25&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This will give us the last time the user was active. This functionality will be handled by the presence service combined with &lt;a href="https://redis.io" rel="noopener noreferrer"&gt;Redis&lt;/a&gt; or &lt;a href="https://memcached.org" rel="noopener noreferrer"&gt;Memcached&lt;/a&gt; as our cache.&lt;/p&gt;

&lt;p&gt;Another way to implement this is to track the latest action of the user, once the last activity crosses a certain threshold, such as &lt;em&gt;"user hasn't performed any action in the last 30 seconds"&lt;/em&gt;, we can show the user as offline and last seen with the last recorded timestamp. This will be more of a lazy update approach and might benefit us over heartbeat in certain cases.&lt;/p&gt;
&lt;h3&gt;
  
  
  Notifications
&lt;/h3&gt;

&lt;p&gt;Once a message is sent in a chat or a group, we will first check if the recipient is active or not, we can get this information by taking the user's active connection and last seen into consideration.&lt;/p&gt;

&lt;p&gt;If the recipient is not active, the chat service will add an event to a &lt;a href="https://karanpratapsingh.com/courses/system-design/message-queues" rel="noopener noreferrer"&gt;message queue&lt;/a&gt; with additional metadata such as the client's device platform which will be used to route the notification to the correct platform later on.&lt;/p&gt;

&lt;p&gt;The notification service will then consume the event from the message queue and forward the request to &lt;a href="https://firebase.google.com/docs/cloud-messaging" rel="noopener noreferrer"&gt;Firebase Cloud Messaging (FCM)&lt;/a&gt; or &lt;a href="https://developer.apple.com/documentation/usernotifications" rel="noopener noreferrer"&gt;Apple Push Notification Service (APNS)&lt;/a&gt; based on the client's device platform (Android, iOS, web, etc). We can also add support for email and SMS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why are we using a message queue?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Since most message queues provide best-effort ordering which ensures that messages are generally delivered in the same order as they're sent and that a message is delivered at least once which is an important part of our service functionality.&lt;/p&gt;

&lt;p&gt;While this seems like a classic &lt;a href="https://karanpratapsingh.com/courses/system-design/publish-subscribe" rel="noopener noreferrer"&gt;publish-subscribe&lt;/a&gt; use case, it is actually not as mobile devices and browsers each have their own way of handling push notifications. Usually, notifications are handled externally via Firebase Cloud Messaging (FCM) or Apple Push Notification Service (APNS) unlike message fan-out which we commonly see in backend services. We can use something like &lt;a href="https://aws.amazon.com/sqs" rel="noopener noreferrer"&gt;Amazon SQS&lt;/a&gt; or &lt;a href="https://www.rabbitmq.com" rel="noopener noreferrer"&gt;RabbitMQ&lt;/a&gt; to support this functionality.&lt;/p&gt;
&lt;h3&gt;
  
  
  Read receipts
&lt;/h3&gt;

&lt;p&gt;Handling read receipts can be tricky, for this use case we can wait for some sort of &lt;a href="https://en.wikipedia.org/wiki/Acknowledgement_(data_networks)" rel="noopener noreferrer"&gt;Acknowledgment (ACK)&lt;/a&gt; from the client to determine if the message was delivered and update the corresponding &lt;code&gt;deliveredAt&lt;/code&gt; field. Similarly, we will mark message the message seen once the user opens the chat and update the corresponding &lt;code&gt;seenAt&lt;/code&gt; timestamp field.&lt;/p&gt;
&lt;h3&gt;
  
  
  Design
&lt;/h3&gt;

&lt;p&gt;Now that we have identified some core components, let's do the first draft of our system design.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibq8zcctgrz760s1smf6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibq8zcctgrz760s1smf6.png" alt="whatsapp-basic-design" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Detailed design
&lt;/h2&gt;

&lt;p&gt;It's time to discuss our design decisions in detail.&lt;/p&gt;
&lt;h3&gt;
  
  
  Data Partitioning
&lt;/h3&gt;

&lt;p&gt;To scale out our databases we will need to partition our data. Horizontal partitioning (aka &lt;a href="https://karanpratapsingh.com/courses/system-design/sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt;) can be a good first step. We can use partitions schemes such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hash-Based Partitioning&lt;/li&gt;
&lt;li&gt;List-Based Partitioning&lt;/li&gt;
&lt;li&gt;Range Based Partitioning&lt;/li&gt;
&lt;li&gt;Composite Partitioning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The above approaches can still cause uneven data and load distribution, we can solve this using &lt;a href="https://karanpratapsingh.com/courses/system-design/consistent-hashing" rel="noopener noreferrer"&gt;Consistent hashing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For more details, refer to &lt;a href="https://karanpratapsingh.com/courses/system-design/sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt; and &lt;a href="https://karanpratapsingh.com/courses/system-design/consistent-hashing" rel="noopener noreferrer"&gt;Consistent Hashing&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Caching
&lt;/h3&gt;

&lt;p&gt;In a messaging application, we have to be careful about using cache as our users expect the latest data, but many users will be requesting the same messages, especially in a group chat. So, to prevent usage spikes from our resources we can cache older messages.&lt;/p&gt;

&lt;p&gt;Some group chats can have thousands of messages and sending that over the network will be really inefficient, to improve efficiency we can add pagination to our system APIs. This decision will be helpful for users with limited network bandwidth as they won't have to retrieve old messages unless requested.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which cache eviction policy to use?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We can use solutions like &lt;a href="https://redis.io" rel="noopener noreferrer"&gt;Redis&lt;/a&gt; or &lt;a href="https://memcached.org" rel="noopener noreferrer"&gt;Memcached&lt;/a&gt; and cache 20% of the daily traffic but what kind of cache eviction policy would best fit our needs?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)" rel="noopener noreferrer"&gt;Least Recently Used (LRU)&lt;/a&gt; can be a good policy for our system. In this policy, we discard the least recently used key first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to handle cache miss?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Whenever there is a cache miss, our servers can hit the database directly and update the cache with the new entries.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For more details, refer to &lt;a href="https://karanpratapsingh.com/courses/system-design/caching" rel="noopener noreferrer"&gt;Caching&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Media access and storage
&lt;/h3&gt;

&lt;p&gt;As we know, most of our storage space will be used for storing media files such as images, videos, or other files. Our media service will be handling both access and storage of the user media files.&lt;/p&gt;

&lt;p&gt;But where can we store files at scale? Well, &lt;a href="https://karanpratapsingh.com/courses/system-design/storage#object-storage" rel="noopener noreferrer"&gt;object storage&lt;/a&gt; is what we're looking for. Object stores break data files up into pieces called objects. It then stores those objects in a single repository, which can be spread out across multiple networked systems. We can also use distributed file storage such as &lt;a href="https://karanpratapsingh.com/courses/system-design/storage#hdfs" rel="noopener noreferrer"&gt;HDFS&lt;/a&gt; or &lt;a href="https://www.gluster.org" rel="noopener noreferrer"&gt;GlusterFS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Fun fact: Whatsapp deletes media on its servers once it has been downloaded by the user.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We can use object stores like &lt;a href="https://aws.amazon.com/s3" rel="noopener noreferrer"&gt;Amazon S3&lt;/a&gt;, &lt;a href="https://azure.microsoft.com/en-in/services/storage/blobs" rel="noopener noreferrer"&gt;Azure Blob Storage&lt;/a&gt;, or &lt;a href="https://cloud.google.com/storage" rel="noopener noreferrer"&gt;Google Cloud Storage&lt;/a&gt; for this use case.&lt;/p&gt;
&lt;h3&gt;
  
  
  Content Delivery Network (CDN)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://karanpratapsingh.com/courses/system-design/content-delivery-network" rel="noopener noreferrer"&gt;Content Delivery Network (CDN)&lt;/a&gt; increases content availability and redundancy while reducing bandwidth costs. Generally, static files such as images, and videos are served from CDN. We can use services like &lt;a href="https://aws.amazon.com/cloudfront" rel="noopener noreferrer"&gt;Amazon CloudFront&lt;/a&gt; or &lt;a href="https://www.cloudflare.com/cdn" rel="noopener noreferrer"&gt;Cloudflare CDN&lt;/a&gt; for this use case.&lt;/p&gt;
&lt;h3&gt;
  
  
  API gateway
&lt;/h3&gt;

&lt;p&gt;Since we will be using multiple protocols like HTTP, WebSocket, TCP/IP, deploying multiple L4 (transport layer) or L7 (application layer) type load balancers separately for each protocol will be expensive. Instead, we can use an &lt;a href="https://karanpratapsingh.com/courses/system-design/api-gateway" rel="noopener noreferrer"&gt;API Gateway&lt;/a&gt; that supports multiple protocols without any issues.&lt;/p&gt;

&lt;p&gt;API Gateway can also offer other features such as authentication, authorization, rate limiting, throttling, and API versioning which will improve the quality of our services.&lt;/p&gt;

&lt;p&gt;We can use services like &lt;a href="https://aws.amazon.com/api-gateway" rel="noopener noreferrer"&gt;Amazon API Gateway&lt;/a&gt; or &lt;a href="https://azure.microsoft.com/en-in/services/api-management" rel="noopener noreferrer"&gt;Azure API Gateway&lt;/a&gt; for this use case.&lt;/p&gt;
&lt;h2&gt;
  
  
  Identify and resolve bottlenecks
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flbzpcdilnf9o1y8f34s4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flbzpcdilnf9o1y8f34s4.png" alt="whatsapp-advanced-design" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let us identify and resolve bottlenecks such as single points of failure in our design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"What if one of our services crashes?"&lt;/li&gt;
&lt;li&gt;"How will we distribute our traffic between our components?"&lt;/li&gt;
&lt;li&gt;"How can we reduce the load on our database?"&lt;/li&gt;
&lt;li&gt;"How to improve the availability of our cache?"&lt;/li&gt;
&lt;li&gt;"Wouldn't API Gateway be a single point of failure?"&lt;/li&gt;
&lt;li&gt;"How can we make our notification system more robust?"&lt;/li&gt;
&lt;li&gt;"How can we reduce media storage costs"?&lt;/li&gt;
&lt;li&gt;"Does chat service has too much responsibility?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To make our system more resilient we can do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running multiple instances of each of our services.&lt;/li&gt;
&lt;li&gt;Introducing &lt;a href="https://karanpratapsingh.com/courses/system-design/load-balancing" rel="noopener noreferrer"&gt;load balancers&lt;/a&gt; between clients, servers, databases, and cache servers.&lt;/li&gt;
&lt;li&gt;Using multiple read replicas for our databases.&lt;/li&gt;
&lt;li&gt;Multiple instances and replicas for our distributed cache.&lt;/li&gt;
&lt;li&gt;We can have a standby replica of our API Gateway.&lt;/li&gt;
&lt;li&gt;Exactly once delivery and message ordering is challenging in a distributed system, we can use a dedicated &lt;a href="https://karanpratapsingh.com/courses/system-design/message-brokers" rel="noopener noreferrer"&gt;message broker&lt;/a&gt; such as &lt;a href="https://kafka.apache.org" rel="noopener noreferrer"&gt;Apache Kafka&lt;/a&gt; or &lt;a href="https://nats.io" rel="noopener noreferrer"&gt;NATS&lt;/a&gt; to make our notification system more robust.&lt;/li&gt;
&lt;li&gt;We can add media processing and compression capabilities to the media service to compress large files similar to Whatsapp which will save a lot of storage space and reduce cost.&lt;/li&gt;
&lt;li&gt;We can create a group service separate from the chat service to further decouple our services.&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;&lt;em&gt;This article is part of my open source &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;System Design Course&lt;/a&gt; available on Github.&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/karanpratapsingh" rel="noopener noreferrer"&gt;
        karanpratapsingh
      &lt;/a&gt; / &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;
        system-design
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Learn how to design systems at scale and prepare for system design interviews
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;System Design&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Hey, welcome to the course. I hope this course provides a great learning experience.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This course is also available on my &lt;a href="https://karanpratapsingh.com/courses/system-design" rel="nofollow noopener noreferrer"&gt;website&lt;/a&gt; and as an ebook on &lt;a href="https://leanpub.com/systemdesign" rel="nofollow noopener noreferrer"&gt;leanpub&lt;/a&gt;. Please leave a ⭐ as motivation if this was helpful!&lt;/em&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Table of contents&lt;/h1&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#what-is-system-design" rel="noopener noreferrer"&gt;What is system design?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Chapter I&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#ip" rel="noopener noreferrer"&gt;IP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#osi-model" rel="noopener noreferrer"&gt;OSI Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#tcp-and-udp" rel="noopener noreferrer"&gt;TCP and UDP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#domain-name-system-dns" rel="noopener noreferrer"&gt;Domain Name System (DNS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#load-balancing" rel="noopener noreferrer"&gt;Load Balancing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#clustering" rel="noopener noreferrer"&gt;Clustering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#caching" rel="noopener noreferrer"&gt;Caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#content-delivery-network-cdn" rel="noopener noreferrer"&gt;Content Delivery Network (CDN)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#proxy" rel="noopener noreferrer"&gt;Proxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#availability" rel="noopener noreferrer"&gt;Availability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#scalability" rel="noopener noreferrer"&gt;Scalability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#storage" rel="noopener noreferrer"&gt;Storage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Chapter II&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#databases-and-dbms" rel="noopener noreferrer"&gt;Databases and DBMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-databases" rel="noopener noreferrer"&gt;SQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#nosql-databases" rel="noopener noreferrer"&gt;NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-vs-nosql-databases" rel="noopener noreferrer"&gt;SQL vs NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-replication" rel="noopener noreferrer"&gt;Database Replication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#indexes" rel="noopener noreferrer"&gt;Indexes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#normalization-and-denormalization" rel="noopener noreferrer"&gt;Normalization and Denormalization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#acid-and-base-consistency-models" rel="noopener noreferrer"&gt;ACID and BASE consistency models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#cap-theorem" rel="noopener noreferrer"&gt;CAP theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#pacelc-theorem" rel="noopener noreferrer"&gt;PACELC Theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#transactions" rel="noopener noreferrer"&gt;Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#distributed-transactions" rel="noopener noreferrer"&gt;Distributed Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#consistent-hashing" rel="noopener noreferrer"&gt;Consistent Hashing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-federation" rel="noopener noreferrer"&gt;Database Federation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Chapter III&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#n-tier-architecture" rel="noopener noreferrer"&gt;N-tier architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-brokers" rel="noopener noreferrer"&gt;Message Brokers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-queues" rel="noopener noreferrer"&gt;Message Queues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#publish-subscribe" rel="noopener noreferrer"&gt;Publish-Subscribe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#enterprise-service-bus-esb" rel="noopener noreferrer"&gt;Enterprise Service Bus (ESB)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#monoliths-and-microservices" rel="noopener noreferrer"&gt;Monoliths and Microservices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-driven-architecture-eda" rel="noopener noreferrer"&gt;Event-Driven Architecture (EDA)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-sourcing" rel="noopener noreferrer"&gt;Event Sourcing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#command-and-query-responsibility-segregation-cqrs" rel="noopener noreferrer"&gt;Command and Query Responsibility Segregation (CQRS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#api-gateway" rel="noopener noreferrer"&gt;API Gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#rest-graphql-grpc" rel="noopener noreferrer"&gt;REST, GraphQL, gRPC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#long-polling-websockets-server-sent-events-sse" rel="noopener noreferrer"&gt;Long polling, WebSockets, Server-Sent Events (SSE)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Chapter IV&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;…&lt;/li&gt;&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>distributedsystems</category>
      <category>architecture</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>System Design: URL Shortener</title>
      <dc:creator>Karan Pratap Singh</dc:creator>
      <pubDate>Wed, 21 Sep 2022 05:44:10 +0000</pubDate>
      <link>https://forem.com/karanpratapsingh/system-design-url-shortener-10i5</link>
      <guid>https://forem.com/karanpratapsingh/system-design-url-shortener-10i5</guid>
      <description>&lt;p&gt;Let's design a URL shortener, similar to services like &lt;a href="https://bitly.com" rel="noopener noreferrer"&gt;Bitly&lt;/a&gt;, &lt;a href="https://tinyurl.com/app" rel="noopener noreferrer"&gt;TinyURL&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a URL Shortener?
&lt;/h2&gt;

&lt;p&gt;A URL shortener service creates an alias or a short URL for a long URL. Users are redirected to the original URL when they visit these short links.&lt;/p&gt;

&lt;p&gt;For example, the following long URL can be changed to a shorter URL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Long URL&lt;/strong&gt;: &lt;a href="https://karanpratapsingh.com/courses/system-design/url-shortener" rel="noopener noreferrer"&gt;https://karanpratapsingh.com/courses/system-design/url-shortener&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Short URL&lt;/strong&gt;: &lt;a href="https://bit.ly/3I71d3o" rel="noopener noreferrer"&gt;https://bit.ly/3I71d3o&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do we need a URL shortener?
&lt;/h2&gt;

&lt;p&gt;URL shortener saves space in general when we are sharing URLs. Users are also less likely to mistype shorter URLs. Moreover, we can also optimize links across devices, this allows us to track individual links.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;p&gt;Our URL shortening system should meet the following requirements:&lt;/p&gt;

&lt;h3&gt;
  
  
  Functional requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Given a URL, our service should generate a &lt;em&gt;shorter and unique&lt;/em&gt; alias for it.&lt;/li&gt;
&lt;li&gt;Users should be redirected to the original URL when they visit the short link.&lt;/li&gt;
&lt;li&gt;Links should expire after a default timespan.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Non-functional requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;High availability with minimal latency.&lt;/li&gt;
&lt;li&gt;The system should be scalable and efficient.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extended requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Prevent abuse of services.&lt;/li&gt;
&lt;li&gt;Record analytics and metrics for redirections.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Estimation and Constraints
&lt;/h2&gt;

&lt;p&gt;Let's start with the estimation and constraints.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Make sure to check any scale or traffic related assumptions with your interviewer.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Traffic
&lt;/h3&gt;

&lt;p&gt;This will be a read-heavy system, so let's assume a &lt;code&gt;100:1&lt;/code&gt; read/write ratio with 100 million links generated per month.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reads/Writes Per month&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For reads per month:&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;100×100 million=10 billion/month
100 \times 100 \space million = 10 \space billion/month
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;mi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;10&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;bi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;h&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
Similarly for writes:


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;1×100 million=100 million/month
1 \times 100 \space million = 100 \space million/month
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;mi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;mi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;h&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;strong&gt;What would be Requests Per Second (RPS) for our system?&lt;/strong&gt;

&lt;p&gt;100 million requests per month translate into 40 requests per second.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;100 million(30 days×24 hrs×3600 seconds)=∼40 URLs/second
\frac{100 \space million}{(30 \space days \times 24 \space hrs \times 3600 \space seconds)} = \sim 40 \space URLs/second
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;30&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ys&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;24&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;h&lt;/span&gt;&lt;span class="mord mathnormal"&gt;rs&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3600&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;mi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;40&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;U&lt;/span&gt;&lt;span class="mord mathnormal"&gt;R&lt;/span&gt;&lt;span class="mord mathnormal"&gt;L&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
And with a &lt;code&gt;100:1&lt;/code&gt; read/write ratio, the number of redirections will be:


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;100×40 URLs/second=4000 requests/second
100 \times 40 \space URLs/second = 4000 \space requests/second
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;40&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;U&lt;/span&gt;&lt;span class="mord mathnormal"&gt;R&lt;/span&gt;&lt;span class="mord mathnormal"&gt;L&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;4000&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;re&lt;/span&gt;&lt;span class="mord mathnormal"&gt;q&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mord mathnormal"&gt;es&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
### Bandwidth

&lt;p&gt;Since we expect about 40 URLs every second, and if we assume each request is of size 500 bytes then the total incoming data for then write requests would be:&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;40×500 bytes=20 KB/second
40 \times 500 \space bytes = 20 \space KB/second
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;40&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;500&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;es&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;20&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;K&lt;/span&gt;&lt;span class="mord mathnormal"&gt;B&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
Similarly, for the read requests, since we expect about 4K redirections, the total outgoing data would be:


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;4000 URLs/second×500 bytes=∼2 MB/second
4000 \space URLs/second \times 500 \space bytes = \sim 2 \space MB/second
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;4000&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;U&lt;/span&gt;&lt;span class="mord mathnormal"&gt;R&lt;/span&gt;&lt;span class="mord mathnormal"&gt;L&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;500&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;es&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;MB&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
### Storage

&lt;p&gt;For storage, we will assume we store each link or record in our database for 10 years. Since we expect around 100M new requests every month, the total number of records we will need to store would be:&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;100 million×10 years×12 months=12 billion
100 \space million \times 10\space years \times 12 \space months = 12 \space billion
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;mi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;10&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;ye&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;rs&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;12&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;h&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;12&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;bi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
Like earlier, if we assume each stored recorded will be approximately 500 bytes. We will need around 6TB of storage:


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;12 billion×500 bytes=6 TB
12 \space billion \times 500 \space bytes = 6 \space TB
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;12&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;bi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;500&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;es&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;6&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;TB&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
### Cache

&lt;p&gt;For caching, we will follow the classic &lt;a href="https://en.wikipedia.org/wiki/Pareto_principle" rel="noopener noreferrer"&gt;Pareto principle&lt;/a&gt; also known as the 80/20 rule. This means that 80% of the requests are for 20% of the data, so we can cache around 20% of our requests.&lt;/p&gt;

&lt;p&gt;Since we get around 4K read or redirection requests each second. This translates into 350M requests per day.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;4000 URLs/second×24 hours×3600 seconds=∼350 million requests/day
4000 \space URLs/second \times 24 \space hours \times 3600 \space seconds = \sim 350 \space million \space requests/day
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;4000&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;U&lt;/span&gt;&lt;span class="mord mathnormal"&gt;R&lt;/span&gt;&lt;span class="mord mathnormal"&gt;L&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;24&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;h&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mord mathnormal"&gt;rs&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3600&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;seco&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;350&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;mi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;re&lt;/span&gt;&lt;span class="mord mathnormal"&gt;q&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mord mathnormal"&gt;es&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
Hence, we will need around 35GB of memory per day.


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;20 percent×350 million×500 bytes=35 GB/day
20 \space percent \times 350 \space million \times 500 \space bytes = 35 \space GB/day
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;20&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="mord mathnormal"&gt;erce&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;350&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;mi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;500&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;es&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;35&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;GB&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
### High-level estimate

&lt;p&gt;Here is our high-level estimate:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Estimate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Writes (New URLs)&lt;/td&gt;
&lt;td&gt;40/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reads (Redirection)&lt;/td&gt;
&lt;td&gt;4K/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bandwidth (Incoming)&lt;/td&gt;
&lt;td&gt;20 KB/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bandwidth (Outgoing)&lt;/td&gt;
&lt;td&gt;2 MB/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage (10 years)&lt;/td&gt;
&lt;td&gt;6 TB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory (Caching)&lt;/td&gt;
&lt;td&gt;~35 GB/day&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Data model design
&lt;/h2&gt;

&lt;p&gt;Next, we will focus on the data model design. Here is our database schema:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frkm3n5dlvifffq3mfqqs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frkm3n5dlvifffq3mfqqs.png" alt="url-shortener-datamodel" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Initially, we can get started with just two tables:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;users&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Stores user's details such as &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;, &lt;code&gt;createdAt&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;urls&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Contains the new short URL's properties such as &lt;code&gt;expiration&lt;/code&gt;, &lt;code&gt;hash&lt;/code&gt;, &lt;code&gt;originalURL&lt;/code&gt;, and &lt;code&gt;userID&lt;/code&gt; of the user who created the short URL. We can also use the &lt;code&gt;hash&lt;/code&gt; column as an &lt;a href="https://karanpratapsingh.com/courses/system-design/indexes" rel="noopener noreferrer"&gt;index&lt;/a&gt; to improve the query performance.&lt;/p&gt;
&lt;h3&gt;
  
  
  What kind of database should we use?
&lt;/h3&gt;

&lt;p&gt;Since the data is not strongly relational, NoSQL databases such as &lt;a href="https://aws.amazon.com/dynamodb" rel="noopener noreferrer"&gt;Amazon DynamoDB&lt;/a&gt;, &lt;a href="https://cassandra.apache.org/_/index.html" rel="noopener noreferrer"&gt;Apache Cassandra&lt;/a&gt;, or &lt;a href="https://www.mongodb.com" rel="noopener noreferrer"&gt;MongoDB&lt;/a&gt; will be a better choice here, if we do decide to use an SQL database then we can use something like &lt;a href="https://azure.microsoft.com/en-in/products/azure-sql/database" rel="noopener noreferrer"&gt;Azure SQL Database&lt;/a&gt; or &lt;a href="https://aws.amazon.com/rds" rel="noopener noreferrer"&gt;Amazon RDS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For more details, refer to &lt;a href="https://karanpratapsingh.com/courses/system-design/sql-vs-nosql-databases" rel="noopener noreferrer"&gt;SQL vs NoSQL&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  API design
&lt;/h2&gt;

&lt;p&gt;Let us do a basic API design for our services:&lt;/p&gt;
&lt;h3&gt;
  
  
  Create URL
&lt;/h3&gt;

&lt;p&gt;This API should create a new short URL in our system given an original URL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;createURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;originalURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;expiration&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;API Key (&lt;code&gt;string&lt;/code&gt;): API key provided by the user.&lt;/p&gt;

&lt;p&gt;Original Url (&lt;code&gt;string&lt;/code&gt;): Original URL to be shortened.&lt;/p&gt;

&lt;p&gt;Expiration (&lt;code&gt;Date&lt;/code&gt;): Expiration date of the new URL &lt;em&gt;(optional)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Returns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Short URL (&lt;code&gt;string&lt;/code&gt;): New shortened URL.&lt;/p&gt;
&lt;h3&gt;
  
  
  Get URL
&lt;/h3&gt;

&lt;p&gt;This API should retrieve the original URL from a given short URL.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;getURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;shortURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;API Key (&lt;code&gt;string&lt;/code&gt;): API key provided by the user.&lt;/p&gt;

&lt;p&gt;Short Url (&lt;code&gt;string&lt;/code&gt;): Short URL mapped to the original URL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Returns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Original URL (&lt;code&gt;string&lt;/code&gt;): Original URL to be retrieved.&lt;/p&gt;
&lt;h3&gt;
  
  
  Delete URL
&lt;/h3&gt;

&lt;p&gt;This API should delete a given shortURL from our system.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;deleteURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;shortURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;API Key (&lt;code&gt;string&lt;/code&gt;): API key provided by the user.&lt;/p&gt;

&lt;p&gt;Short Url (&lt;code&gt;string&lt;/code&gt;): Short URL to be deleted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Returns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Result (&lt;code&gt;boolean&lt;/code&gt;): Represents whether the operation was successful or not.&lt;/p&gt;
&lt;h3&gt;
  
  
  Why do we need an API key?
&lt;/h3&gt;

&lt;p&gt;As you must've noticed, we're using an API key to prevent abuse of our services. Using this API key we can limit the users to a certain number of requests per second or minute. This is quite a standard practice for developer APIs and should cover our extended requirement.&lt;/p&gt;
&lt;h2&gt;
  
  
  High-level design
&lt;/h2&gt;

&lt;p&gt;Now let us do a high-level design of our system.&lt;/p&gt;
&lt;h3&gt;
  
  
  URL Encoding
&lt;/h3&gt;

&lt;p&gt;Our system's primary goal is to shorten a given URL, let's look at different approaches:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Base62 Approach&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this approach, we can encode the original URL using &lt;a href="https://en.wikipedia.org/wiki/Base62" rel="noopener noreferrer"&gt;Base62&lt;/a&gt; which consists of the capital letters A-Z, the lower case letters a-z, and the numbers 0-9.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;Number of URLs=62N
Number \space of \space URLs = 62^N
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;N&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mord mathnormal"&gt;mb&lt;/span&gt;&lt;span class="mord mathnormal"&gt;er&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;U&lt;/span&gt;&lt;span class="mord mathnormal"&gt;R&lt;/span&gt;&lt;span class="mord mathnormal"&gt;L&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;6&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;

&lt;p&gt;Where,&lt;/p&gt;

&lt;p&gt;&lt;code&gt;N&lt;/code&gt;: Number of characters in the generated URL.&lt;/p&gt;

&lt;p&gt;So, if we want to generate a URL that is 7 characters long, we will generate ~3.5 trillion different URLs.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;625=∼916 million URLs 626=∼56.8 billion URLs 627=∼3.5 trillion URLs
\begin{gather*}
62^5 = \sim 916 \space million \space URLs \

62^6 = \sim 56.8 \space billion \space URLs \

62^7 = \sim 3.5 \space trillion \space URLs
\end{gather*}
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mtable"&gt;&lt;span class="col-align-c"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;6&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;916&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;mi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;U&lt;/span&gt;&lt;span class="mord mathnormal"&gt;R&lt;/span&gt;&lt;span class="mord mathnormal"&gt;L&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord"&gt;6&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;6&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;56.8&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;bi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;U&lt;/span&gt;&lt;span class="mord mathnormal"&gt;R&lt;/span&gt;&lt;span class="mord mathnormal"&gt;L&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord"&gt;6&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;7&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3.5&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;r&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;U&lt;/span&gt;&lt;span class="mord mathnormal"&gt;R&lt;/span&gt;&lt;span class="mord mathnormal"&gt;L&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
This is the simplest solution here, but it does not guarantee non-duplicate or collision-resistant keys.

&lt;p&gt;&lt;strong&gt;MD5 Approach&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/MD5" rel="noopener noreferrer"&gt;MD5 message-digest algorithm&lt;/a&gt; is a widely used hash function producing a 128-bit hash value (or 32 hexadecimal digits). We can use these 32 hexadecimal digits for generating 7 characters long URL.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;MD5(originalurl)→base62encode→hash
MD5(original_url) \rightarrow base62encode \rightarrow hash
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;M&lt;/span&gt;&lt;span class="mord mathnormal"&gt;D&lt;/span&gt;&lt;span class="mord"&gt;5&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;or&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ina&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;u&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;r&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;→&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ba&lt;/span&gt;&lt;span class="mord mathnormal"&gt;se&lt;/span&gt;&lt;span class="mord"&gt;62&lt;/span&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;co&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;→&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ha&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mord mathnormal"&gt;h&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
However, this creates a new issue for us, which is duplication and collision. We can try to re-compute the hash until we find a unique one but that will increase the overhead of our systems. It's better to look for more scalable approaches.

&lt;p&gt;&lt;strong&gt;Counter Approach&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this approach, we will start with a single server which will maintain the count of the keys generated. Once our service receives a request, it can reach out to the counter which returns a unique number and increments the counter. When the next request comes the counter again returns the unique number and this goes on.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;Counter(0−3.5 trillion)→base62encode→hash
Counter(0-3.5 \space trillion) \rightarrow base62encode \rightarrow hash
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;C&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;er&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3.5&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;r&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;→&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ba&lt;/span&gt;&lt;span class="mord mathnormal"&gt;se&lt;/span&gt;&lt;span class="mord"&gt;62&lt;/span&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mord mathnormal"&gt;co&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;→&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ha&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mord mathnormal"&gt;h&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
The problem with this approach is that it can quickly become a single point for failure. And if we run multiple instances of the counter we can have collision as it's essentially a distributed system.

&lt;p&gt;To solve this issue we can use a distributed system manager such as &lt;a href="https://zookeeper.apache.org" rel="noopener noreferrer"&gt;Zookeeper&lt;/a&gt; which can provide distributed synchronization. Zookeeper can maintain multiple ranges for our servers.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;Range 1: 1→1,000,000 Range 2: 1,000,001→2,000,000 Range 3: 2,000,001→3,000,000 ...
\begin{align*}
&amp;amp; Range \space 1: \space 1 \rightarrow 1,000,000 \

&amp;amp; Range \space 2: \space 1,000,001 \rightarrow 2,000,000 \

&amp;amp; Range \space 3: \space 2,000,001 \rightarrow 3,000,000 \

&amp;amp; ...
\end{align*}
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mtable"&gt;&lt;span class="col-align-r"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="col-align-l"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;R&lt;/span&gt;&lt;span class="mord mathnormal"&gt;an&lt;/span&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;:&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;→&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;000&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;000&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="arraycolsep"&gt;&lt;/span&gt;&lt;span class="col-align-r"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;R&lt;/span&gt;&lt;span class="mord mathnormal"&gt;an&lt;/span&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;:&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;000&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;001&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;→&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;000&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;000&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="col-align-l"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;R&lt;/span&gt;&lt;span class="mord mathnormal"&gt;an&lt;/span&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord"&gt;3&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;:&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;000&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;001&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;→&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;000&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;000&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="arraycolsep"&gt;&lt;/span&gt;&lt;span class="col-align-r"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
Once a server reaches its maximum range Zookeeper will assign an unused counter range to the new server. This approach can guarantee non-duplicate and collision-resistant URLs. Also, we can run multiple instances of Zookeeper to remove the single point of failure.
&lt;h3&gt;
  
  
  Key Generation Service (KGS)
&lt;/h3&gt;

&lt;p&gt;As we discussed, generating a unique key at scale without duplication and collisions can be a bit of a challenge. To solve this problem, we can create a standalone Key Generation Service (KGS) that generates a unique key ahead of time and stores it in a separate database for later use. This approach can make things simple for us.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to handle concurrent access?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once the key is used, we can mark it in the database to make sure we don't reuse it, however, if there are multiple server instances reading data concurrently, two or more servers might try to use the same key.&lt;/p&gt;

&lt;p&gt;The easiest way to solve this would be to store keys in two tables. As soon as a key is used, we move it to a separate table with appropriate locking in place. Also, to improve reads, we can keep some of the keys in memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;KGS database estimations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As per our discussion, we can generate up to ~56.8 billion unique 6 character long keys which will result in us having to store 300 GB of keys.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;6 characters×56.8 billion=∼390 GB
6 \space characters \times 56.8 \space billion = \sim 390 \space GB
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;6&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;c&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ha&lt;/span&gt;&lt;span class="mord mathnormal"&gt;r&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;c&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ers&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;56.8&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;bi&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ll&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=∼&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;390&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;span class="mord mathnormal"&gt;GB&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
While 390 GB seems like a lot for this simple use case, it is important to remember this is for the entirety of our service lifetime and the size of the keys database would not increase like our main database.
&lt;h3&gt;
  
  
  Caching
&lt;/h3&gt;

&lt;p&gt;Now, let's talk about &lt;a href="https://karanpratapsingh.com/courses/system-design/caching" rel="noopener noreferrer"&gt;caching&lt;/a&gt;. As per our estimations, we will require around ~35 GB of memory per day to cache 20% of the incoming requests to our services. For this use case, we can use &lt;a href="https://redis.io" rel="noopener noreferrer"&gt;Redis&lt;/a&gt; or &lt;a href="https://memcached.org" rel="noopener noreferrer"&gt;Memcached&lt;/a&gt; servers alongside our API server.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For more details, refer to &lt;a href="https://karanpratapsingh.com/courses/system-design/caching" rel="noopener noreferrer"&gt;caching&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Design
&lt;/h3&gt;

&lt;p&gt;Now that we have identified some core components, let's do the first draft of our system design.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft8ofa2mmqqj8awgt2vlt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft8ofa2mmqqj8awgt2vlt.png" alt="url-shortener-basic-design" width="800" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's how it works:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating a new URL&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When a user creates a new URL, our API server requests a new unique key from the Key Generation Service (KGS).&lt;/li&gt;
&lt;li&gt;Key Generation Service provides a unique key to the API server and marks the key as used.&lt;/li&gt;
&lt;li&gt;API server writes the new URL entry to the database and cache.&lt;/li&gt;
&lt;li&gt;Our service returns an HTTP 201 (Created) response to the user.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Accessing a URL&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When a client navigates to a certain short URL, the request is sent to the API servers.&lt;/li&gt;
&lt;li&gt;The request first hits the cache, and if the entry is not found there then it is retrieved from the database and an HTTP 301 (Redirect) is issued to the original URL.&lt;/li&gt;
&lt;li&gt;If the key is still not found in the database, an HTTP 404 (Not found) error is sent to the user.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Detailed design
&lt;/h2&gt;

&lt;p&gt;It's time to discuss the finer details of our design.&lt;/p&gt;
&lt;h3&gt;
  
  
  Data Partitioning
&lt;/h3&gt;

&lt;p&gt;To scale out our databases we will need to partition our data. Horizontal partitioning (aka &lt;a href="https://karanpratapsingh.com/courses/system-design/sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt;) can be a good first step. We can use partitions schemes such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hash-Based Partitioning&lt;/li&gt;
&lt;li&gt;List-Based Partitioning&lt;/li&gt;
&lt;li&gt;Range Based Partitioning&lt;/li&gt;
&lt;li&gt;Composite Partitioning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The above approaches can still cause uneven data and load distribution, we can solve this using &lt;a href="https://karanpratapsingh.com/courses/system-design/consistent-hashing" rel="noopener noreferrer"&gt;Consistent hashing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For more details, refer to &lt;a href="https://karanpratapsingh.com/courses/system-design/sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt; and &lt;a href="https://karanpratapsingh.com/courses/system-design/consistent-hashing" rel="noopener noreferrer"&gt;Consistent Hashing&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Database cleanup
&lt;/h3&gt;

&lt;p&gt;This is more of a maintenance step for our services and depends on whether we keep the expired entries or remove them. If we do decide to remove expired entries, we can approach this in two different ways:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Active cleanup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In active cleanup, we will run a separate cleanup service which will periodically remove expired links from our storage and cache. This will be a very lightweight service like a &lt;a href="https://en.wikipedia.org/wiki/Cron" rel="noopener noreferrer"&gt;cron job&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Passive cleanup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For passive cleanup, we can remove the entry when a user tries to access an expired link. This can ensure a lazy cleanup of our database and cache.&lt;/p&gt;
&lt;h3&gt;
  
  
  Cache
&lt;/h3&gt;

&lt;p&gt;Now let us talk about &lt;a href="https://karanpratapsingh.com/courses/system-design/caching" rel="noopener noreferrer"&gt;caching&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which cache eviction policy to use?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As we discussed before, we can use solutions like &lt;a href="https://redis.io" rel="noopener noreferrer"&gt;Redis&lt;/a&gt; or &lt;a href="https://memcached.org" rel="noopener noreferrer"&gt;Memcached&lt;/a&gt; and cache 20% of the daily traffic but what kind of cache eviction policy would best fit our needs?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)" rel="noopener noreferrer"&gt;Least Recently Used (LRU)&lt;/a&gt; can be a good policy for our system. In this policy, we discard the least recently used key first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to handle cache miss?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Whenever there is a cache miss, our servers can hit the database directly and update the cache with the new entries.&lt;/p&gt;
&lt;h3&gt;
  
  
  Metrics and Analytics
&lt;/h3&gt;

&lt;p&gt;Recording analytics and metrics is one of our extended requirements. We can store and update metadata like visitor's country, platform, the number of views, etc alongside the URL entry in our database.&lt;/p&gt;
&lt;h3&gt;
  
  
  Security
&lt;/h3&gt;

&lt;p&gt;For security, we can introduce private URLs and authorization. A separate table can be used to store user ids that have permission to access a specific URL. If a user does not have proper permissions, we can return an HTTP 401 (Unauthorized) error.&lt;/p&gt;

&lt;p&gt;We can also use an &lt;a href="https://karanpratapsingh.com/courses/system-design/api-gateway" rel="noopener noreferrer"&gt;API Gateway&lt;/a&gt; as they can support capabilities like authorization, rate limiting, and load balancing out of the box.&lt;/p&gt;
&lt;h2&gt;
  
  
  Identify and resolve bottlenecks
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0z9s524qnnodwa10ql7n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0z9s524qnnodwa10ql7n.png" alt="url-shortener-advanced-design" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let us identify and resolve bottlenecks such as single points of failure in our design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"What if the API service or Key Generation Service crashes?"&lt;/li&gt;
&lt;li&gt;"How will we distribute our traffic between our components?"&lt;/li&gt;
&lt;li&gt;"How can we reduce the load on our database?"&lt;/li&gt;
&lt;li&gt;"What if the key database used by KGS fails?"&lt;/li&gt;
&lt;li&gt;"How to improve the availability of our cache?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To make our system more resilient we can do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running multiple instances of our Servers and Key Generation Service.&lt;/li&gt;
&lt;li&gt;Introducing &lt;a href="https://karanpratapsingh.com/courses/system-design/load-balancing" rel="noopener noreferrer"&gt;load balancers&lt;/a&gt; between clients, servers, databases, and cache servers.&lt;/li&gt;
&lt;li&gt;Using multiple read replicas for our database as it's a read-heavy system.&lt;/li&gt;
&lt;li&gt;Standby replica for our key database in case it fails.&lt;/li&gt;
&lt;li&gt;Multiple instances and replicas for our distributed cache.&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;&lt;em&gt;This article is part of my open source &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;System Design Course&lt;/a&gt; available on Github.&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/karanpratapsingh" rel="noopener noreferrer"&gt;
        karanpratapsingh
      &lt;/a&gt; / &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;
        system-design
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Learn how to design systems at scale and prepare for system design interviews
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;System Design&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Hey, welcome to the course. I hope this course provides a great learning experience.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This course is also available on my &lt;a href="https://karanpratapsingh.com/courses/system-design" rel="nofollow noopener noreferrer"&gt;website&lt;/a&gt; and as an ebook on &lt;a href="https://leanpub.com/systemdesign" rel="nofollow noopener noreferrer"&gt;leanpub&lt;/a&gt;. Please leave a ⭐ as motivation if this was helpful!&lt;/em&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Table of contents&lt;/h1&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#what-is-system-design" rel="noopener noreferrer"&gt;What is system design?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter I&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#ip" rel="noopener noreferrer"&gt;IP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#osi-model" rel="noopener noreferrer"&gt;OSI Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#tcp-and-udp" rel="noopener noreferrer"&gt;TCP and UDP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#domain-name-system-dns" rel="noopener noreferrer"&gt;Domain Name System (DNS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#load-balancing" rel="noopener noreferrer"&gt;Load Balancing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#clustering" rel="noopener noreferrer"&gt;Clustering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#caching" rel="noopener noreferrer"&gt;Caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#content-delivery-network-cdn" rel="noopener noreferrer"&gt;Content Delivery Network (CDN)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#proxy" rel="noopener noreferrer"&gt;Proxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#availability" rel="noopener noreferrer"&gt;Availability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#scalability" rel="noopener noreferrer"&gt;Scalability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#storage" rel="noopener noreferrer"&gt;Storage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter II&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#databases-and-dbms" rel="noopener noreferrer"&gt;Databases and DBMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-databases" rel="noopener noreferrer"&gt;SQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#nosql-databases" rel="noopener noreferrer"&gt;NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-vs-nosql-databases" rel="noopener noreferrer"&gt;SQL vs NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-replication" rel="noopener noreferrer"&gt;Database Replication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#indexes" rel="noopener noreferrer"&gt;Indexes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#normalization-and-denormalization" rel="noopener noreferrer"&gt;Normalization and Denormalization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#acid-and-base-consistency-models" rel="noopener noreferrer"&gt;ACID and BASE consistency models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#cap-theorem" rel="noopener noreferrer"&gt;CAP theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#pacelc-theorem" rel="noopener noreferrer"&gt;PACELC Theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#transactions" rel="noopener noreferrer"&gt;Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#distributed-transactions" rel="noopener noreferrer"&gt;Distributed Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#consistent-hashing" rel="noopener noreferrer"&gt;Consistent Hashing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-federation" rel="noopener noreferrer"&gt;Database Federation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter III&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#n-tier-architecture" rel="noopener noreferrer"&gt;N-tier architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-brokers" rel="noopener noreferrer"&gt;Message Brokers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-queues" rel="noopener noreferrer"&gt;Message Queues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#publish-subscribe" rel="noopener noreferrer"&gt;Publish-Subscribe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#enterprise-service-bus-esb" rel="noopener noreferrer"&gt;Enterprise Service Bus (ESB)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#monoliths-and-microservices" rel="noopener noreferrer"&gt;Monoliths and Microservices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-driven-architecture-eda" rel="noopener noreferrer"&gt;Event-Driven Architecture (EDA)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-sourcing" rel="noopener noreferrer"&gt;Event Sourcing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#command-and-query-responsibility-segregation-cqrs" rel="noopener noreferrer"&gt;Command and Query Responsibility Segregation (CQRS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#api-gateway" rel="noopener noreferrer"&gt;API Gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#rest-graphql-grpc" rel="noopener noreferrer"&gt;REST, GraphQL, gRPC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#long-polling-websockets-server-sent-events-sse" rel="noopener noreferrer"&gt;Long polling, WebSockets, Server-Sent Events (SSE)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter IV&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;…&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>distributedsystems</category>
      <category>architecture</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>System Design: System Design Interviews</title>
      <dc:creator>Karan Pratap Singh</dc:creator>
      <pubDate>Wed, 21 Sep 2022 05:44:06 +0000</pubDate>
      <link>https://forem.com/karanpratapsingh/system-design-system-design-interviews-47ak</link>
      <guid>https://forem.com/karanpratapsingh/system-design-system-design-interviews-47ak</guid>
      <description>&lt;p&gt;System design is a very extensive topic and system design interviews are designed to evaluate your capability to produce technical solutions to abstract problems, as such, they're not designed for a specific answer. The unique aspect of system design interviews is the two-way nature between the candidate and the interviewer.&lt;/p&gt;

&lt;p&gt;Expectations are quite different at different engineering levels as well. Because someone with a lot of practical experience will approach it quite differently from someone who's new in the industry. As a result, it's hard to come up with a single strategy that will help us stay organized during the interview.&lt;/p&gt;

&lt;p&gt;Let's look at some common strategies for the system design interviews:&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements clarifications
&lt;/h2&gt;

&lt;p&gt;System design interview questions, by nature, are vague or abstract. Asking questions about the exact scope of the problem, and clarifying functional requirements early in the interview is essential. Usually, requirements are divided into three parts:&lt;/p&gt;

&lt;h3&gt;
  
  
  Functional requirements
&lt;/h3&gt;

&lt;p&gt;These are the requirements that the end user specifically demands as basic functionalities that the system should offer. All these functionalities need to be necessarily incorporated into the system as part of the contract.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"What are the features that we need to design for this system?"&lt;/li&gt;
&lt;li&gt;"What are the edge cases we need to consider, if any, in our design?"&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Non-functional requirements
&lt;/h3&gt;

&lt;p&gt;These are the quality constraints that the system must satisfy according to the project contract. The priority or extent to which these factors are implemented varies from one project to another. They are also called non-behavioral requirements. For example, portability, maintainability, reliability, scalability, security, etc.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Each request should be processed with the minimum latency"&lt;/li&gt;
&lt;li&gt;"System should be highly available"&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extended requirements
&lt;/h3&gt;

&lt;p&gt;These are basically "nice to have" requirements that might be out of the scope of the system.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Our system should record metrics and analytics"&lt;/li&gt;
&lt;li&gt;"Service health and performance monitoring?"&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Estimation and Constraints
&lt;/h2&gt;

&lt;p&gt;Estimate the scale of the system we're going to design. It is important to ask questions such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"What is the desired scale that this system will need to handle?"&lt;/li&gt;
&lt;li&gt;"What is the read/write ratio of our system?"&lt;/li&gt;
&lt;li&gt;"How many requests per second?"&lt;/li&gt;
&lt;li&gt;"How much storage will be needed?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These questions will help us scale our design later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data model design
&lt;/h2&gt;

&lt;p&gt;Once we have the estimations, we can start with defining the database schema. Doing so in the early stages of the interview would help us to understand the data flow which is the core of every system. In this step, we basically define all the entities and relationships between them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"What are the different entities in the system?"&lt;/li&gt;
&lt;li&gt;"What are the relationships between these entities?"&lt;/li&gt;
&lt;li&gt;"How many tables do we need?"&lt;/li&gt;
&lt;li&gt;"Is NoSQL a better choice here?"&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  API design
&lt;/h2&gt;

&lt;p&gt;Next, we can start designing APIs for the system. These APIs will help us define the expectations from the system explicitly. We don't have to write any code, just a simple interface defining the API requirements such as parameters, functions, classes, types, entities, etc.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It is advised to keep the interface as simple as possible and come back to it later when covering extended requirements.&lt;/p&gt;
&lt;h2&gt;
  
  
  High-level component design
&lt;/h2&gt;

&lt;p&gt;Now we have established our data model and API design, it's time to identify system components (such as Load Balancers, API Gateway, etc.) that are needed to solve our problem and draft the first design of our system.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Is it best to design a monolithic or a microservices architecture?"&lt;/li&gt;
&lt;li&gt;"What type of database should we use?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once we have a basic diagram, we can start discussing with the interviewer how the system will work from the client's perspective.&lt;/p&gt;
&lt;h2&gt;
  
  
  Detailed design
&lt;/h2&gt;

&lt;p&gt;Now it's time to go into detail about the major components of the system we designed. As always discuss with the interviewer which component may need further improvements.&lt;/p&gt;

&lt;p&gt;Here is a good opportunity to demonstrate your experience in the areas of your expertise. Present different approaches, advantages, and disadvantages. Explain your design decisions, and back them up with examples. This is also a good time to discuss any additional features the system might be able to support, though this is optional.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"How should we partition our data?"&lt;/li&gt;
&lt;li&gt;"What about load distribution?"&lt;/li&gt;
&lt;li&gt;"Should we use cache?"&lt;/li&gt;
&lt;li&gt;"How will we handle a sudden spike in traffic?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, try not to be too opinionated about certain technologies, statements like "I believe that NoSQL databases are just better, SQL databases are not scalable" reflect poorly. As someone who has interviewed a lot of people over the years, my two cents here would be to be humble about what you know and what you do not. Use your existing knowledge with examples to navigate this part of the interview.&lt;/p&gt;
&lt;h2&gt;
  
  
  Identify and resolve bottlenecks
&lt;/h2&gt;

&lt;p&gt;Finally, it's time to discuss bottlenecks and approaches to mitigate them. Here are some important questions to ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Do we have enough database replicas?"&lt;/li&gt;
&lt;li&gt;"Is there any single point of failure?"&lt;/li&gt;
&lt;li&gt;"Is database sharding required?"&lt;/li&gt;
&lt;li&gt;"How can we make our system more robust?"&lt;/li&gt;
&lt;li&gt;"How to improve the availability of our cache?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Make sure to read the engineering blog of the company you're interviewing with. This will help you get a sense of what technology stack they're using and which problems are important to them.&lt;/p&gt;



&lt;p&gt;&lt;em&gt;This article is part of my open source &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;System Design Course&lt;/a&gt; available on Github.&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/karanpratapsingh" rel="noopener noreferrer"&gt;
        karanpratapsingh
      &lt;/a&gt; / &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;
        system-design
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Learn how to design systems at scale and prepare for system design interviews
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;System Design&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Hey, welcome to the course. I hope this course provides a great learning experience.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This course is also available on my &lt;a href="https://karanpratapsingh.com/courses/system-design" rel="nofollow noopener noreferrer"&gt;website&lt;/a&gt; and as an ebook on &lt;a href="https://leanpub.com/systemdesign" rel="nofollow noopener noreferrer"&gt;leanpub&lt;/a&gt;. Please leave a ⭐ as motivation if this was helpful!&lt;/em&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Table of contents&lt;/h1&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#what-is-system-design" rel="noopener noreferrer"&gt;What is system design?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Chapter I&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#ip" rel="noopener noreferrer"&gt;IP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#osi-model" rel="noopener noreferrer"&gt;OSI Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#tcp-and-udp" rel="noopener noreferrer"&gt;TCP and UDP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#domain-name-system-dns" rel="noopener noreferrer"&gt;Domain Name System (DNS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#load-balancing" rel="noopener noreferrer"&gt;Load Balancing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#clustering" rel="noopener noreferrer"&gt;Clustering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#caching" rel="noopener noreferrer"&gt;Caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#content-delivery-network-cdn" rel="noopener noreferrer"&gt;Content Delivery Network (CDN)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#proxy" rel="noopener noreferrer"&gt;Proxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#availability" rel="noopener noreferrer"&gt;Availability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#scalability" rel="noopener noreferrer"&gt;Scalability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#storage" rel="noopener noreferrer"&gt;Storage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Chapter II&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#databases-and-dbms" rel="noopener noreferrer"&gt;Databases and DBMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-databases" rel="noopener noreferrer"&gt;SQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#nosql-databases" rel="noopener noreferrer"&gt;NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-vs-nosql-databases" rel="noopener noreferrer"&gt;SQL vs NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-replication" rel="noopener noreferrer"&gt;Database Replication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#indexes" rel="noopener noreferrer"&gt;Indexes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#normalization-and-denormalization" rel="noopener noreferrer"&gt;Normalization and Denormalization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#acid-and-base-consistency-models" rel="noopener noreferrer"&gt;ACID and BASE consistency models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#cap-theorem" rel="noopener noreferrer"&gt;CAP theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#pacelc-theorem" rel="noopener noreferrer"&gt;PACELC Theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#transactions" rel="noopener noreferrer"&gt;Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#distributed-transactions" rel="noopener noreferrer"&gt;Distributed Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#consistent-hashing" rel="noopener noreferrer"&gt;Consistent Hashing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-federation" rel="noopener noreferrer"&gt;Database Federation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Chapter III&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#n-tier-architecture" rel="noopener noreferrer"&gt;N-tier architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-brokers" rel="noopener noreferrer"&gt;Message Brokers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-queues" rel="noopener noreferrer"&gt;Message Queues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#publish-subscribe" rel="noopener noreferrer"&gt;Publish-Subscribe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#enterprise-service-bus-esb" rel="noopener noreferrer"&gt;Enterprise Service Bus (ESB)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#monoliths-and-microservices" rel="noopener noreferrer"&gt;Monoliths and Microservices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-driven-architecture-eda" rel="noopener noreferrer"&gt;Event-Driven Architecture (EDA)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-sourcing" rel="noopener noreferrer"&gt;Event Sourcing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#command-and-query-responsibility-segregation-cqrs" rel="noopener noreferrer"&gt;Command and Query Responsibility Segregation (CQRS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#api-gateway" rel="noopener noreferrer"&gt;API Gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#rest-graphql-grpc" rel="noopener noreferrer"&gt;REST, GraphQL, gRPC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#long-polling-websockets-server-sent-events-sse" rel="noopener noreferrer"&gt;Long polling, WebSockets, Server-Sent Events (SSE)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Chapter IV&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;…&lt;/li&gt;&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>distributedsystems</category>
      <category>architecture</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>System Design: SSL, TLS, mTLS</title>
      <dc:creator>Karan Pratap Singh</dc:creator>
      <pubDate>Tue, 20 Sep 2022 12:10:19 +0000</pubDate>
      <link>https://forem.com/karanpratapsingh/system-design-ssl-tls-mtls-3nak</link>
      <guid>https://forem.com/karanpratapsingh/system-design-ssl-tls-mtls-3nak</guid>
      <description>&lt;p&gt;Let's briefly discuss some important communication security protocols such as SSL, TLS, and mTLS. I would say that from a &lt;em&gt;"big picture"&lt;/em&gt; system design perspective, this topic is not very important but still good to know about.&lt;/p&gt;

&lt;h2&gt;
  
  
  SSL
&lt;/h2&gt;

&lt;p&gt;SSL stands for Secure Sockets Layer, and it refers to a protocol for encrypting and securing communications that take place on the internet. It was first developed in 1995 but since has been deprecated in favor of TLS (Transport Layer Security).&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is it called an SSL certificate if it is deprecated?
&lt;/h3&gt;

&lt;p&gt;Most major certificate providers still refer to certificates as SSL certificates, which is why the naming convention persists.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why was SSL so important?
&lt;/h3&gt;

&lt;p&gt;Originally, data on the web was transmitted in plaintext that anyone could read if they intercepted the message. SSL was created to correct this problem and protect user privacy. By encrypting any data that goes between the user and a web server, SSL also stops certain kinds of cyber attacks by preventing attackers from tampering with data in transit.&lt;/p&gt;

&lt;h2&gt;
  
  
  TLS
&lt;/h2&gt;

&lt;p&gt;Transport Layer Security, or TLS, is a widely adopted security protocol designed to facilitate privacy and data security for communications over the internet. TLS evolved from a previous encryption protocol called Secure Sockets Layer (SSL). A primary use case of TLS is encrypting the communication between web applications and servers.&lt;/p&gt;

&lt;p&gt;There are three main components to what the TLS protocol accomplishes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Encryption&lt;/strong&gt;: hides the data being transferred from third parties.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication&lt;/strong&gt;: ensures that the parties exchanging information are who they claim to be.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integrity&lt;/strong&gt;: verifies that the data has not been forged or tampered with.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  mTLS
&lt;/h2&gt;

&lt;p&gt;Mutual TLS, or mTLS, is a method for mutual authentication. mTLS ensures that the parties at each end of a network connection are who they claim to be by verifying that they both have the correct private key. The information within their respective TLS certificates provides additional verification.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why use mTLS?
&lt;/h3&gt;

&lt;p&gt;mTLS helps ensure that the traffic is secure and trusted in both directions between a client and server. This provides an additional layer of security for users who log in to an organization's network or applications. It also verifies connections with client devices that do not follow a login process, such as Internet of Things (IoT) devices.&lt;/p&gt;

&lt;p&gt;Nowadays, mTLS is commonly used by microservices or distributed systems in a &lt;a href="https://en.wikipedia.org/wiki/Zero_trust_security_model" rel="noopener noreferrer"&gt;zero trust security model&lt;/a&gt; to verify each other.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This article is part of my open source &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;System Design Course&lt;/a&gt; available on Github.&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/karanpratapsingh" rel="noopener noreferrer"&gt;
        karanpratapsingh
      &lt;/a&gt; / &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;
        system-design
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Learn how to design systems at scale and prepare for system design interviews
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;System Design&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Hey, welcome to the course. I hope this course provides a great learning experience.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This course is also available on my &lt;a href="https://karanpratapsingh.com/courses/system-design" rel="nofollow noopener noreferrer"&gt;website&lt;/a&gt; and as an ebook on &lt;a href="https://leanpub.com/systemdesign" rel="nofollow noopener noreferrer"&gt;leanpub&lt;/a&gt;. Please leave a ⭐ as motivation if this was helpful!&lt;/em&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Table of contents&lt;/h1&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#what-is-system-design" rel="noopener noreferrer"&gt;What is system design?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter I&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#ip" rel="noopener noreferrer"&gt;IP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#osi-model" rel="noopener noreferrer"&gt;OSI Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#tcp-and-udp" rel="noopener noreferrer"&gt;TCP and UDP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#domain-name-system-dns" rel="noopener noreferrer"&gt;Domain Name System (DNS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#load-balancing" rel="noopener noreferrer"&gt;Load Balancing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#clustering" rel="noopener noreferrer"&gt;Clustering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#caching" rel="noopener noreferrer"&gt;Caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#content-delivery-network-cdn" rel="noopener noreferrer"&gt;Content Delivery Network (CDN)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#proxy" rel="noopener noreferrer"&gt;Proxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#availability" rel="noopener noreferrer"&gt;Availability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#scalability" rel="noopener noreferrer"&gt;Scalability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#storage" rel="noopener noreferrer"&gt;Storage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter II&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#databases-and-dbms" rel="noopener noreferrer"&gt;Databases and DBMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-databases" rel="noopener noreferrer"&gt;SQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#nosql-databases" rel="noopener noreferrer"&gt;NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-vs-nosql-databases" rel="noopener noreferrer"&gt;SQL vs NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-replication" rel="noopener noreferrer"&gt;Database Replication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#indexes" rel="noopener noreferrer"&gt;Indexes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#normalization-and-denormalization" rel="noopener noreferrer"&gt;Normalization and Denormalization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#acid-and-base-consistency-models" rel="noopener noreferrer"&gt;ACID and BASE consistency models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#cap-theorem" rel="noopener noreferrer"&gt;CAP theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#pacelc-theorem" rel="noopener noreferrer"&gt;PACELC Theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#transactions" rel="noopener noreferrer"&gt;Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#distributed-transactions" rel="noopener noreferrer"&gt;Distributed Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#consistent-hashing" rel="noopener noreferrer"&gt;Consistent Hashing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-federation" rel="noopener noreferrer"&gt;Database Federation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter III&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#n-tier-architecture" rel="noopener noreferrer"&gt;N-tier architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-brokers" rel="noopener noreferrer"&gt;Message Brokers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-queues" rel="noopener noreferrer"&gt;Message Queues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#publish-subscribe" rel="noopener noreferrer"&gt;Publish-Subscribe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#enterprise-service-bus-esb" rel="noopener noreferrer"&gt;Enterprise Service Bus (ESB)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#monoliths-and-microservices" rel="noopener noreferrer"&gt;Monoliths and Microservices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-driven-architecture-eda" rel="noopener noreferrer"&gt;Event-Driven Architecture (EDA)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-sourcing" rel="noopener noreferrer"&gt;Event Sourcing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#command-and-query-responsibility-segregation-cqrs" rel="noopener noreferrer"&gt;Command and Query Responsibility Segregation (CQRS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#api-gateway" rel="noopener noreferrer"&gt;API Gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#rest-graphql-grpc" rel="noopener noreferrer"&gt;REST, GraphQL, gRPC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#long-polling-websockets-server-sent-events-sse" rel="noopener noreferrer"&gt;Long polling, WebSockets, Server-Sent Events (SSE)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter IV&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;…&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>distributedsystems</category>
      <category>architecture</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>System Design: Single Sign-On (SSO)</title>
      <dc:creator>Karan Pratap Singh</dc:creator>
      <pubDate>Tue, 20 Sep 2022 12:10:05 +0000</pubDate>
      <link>https://forem.com/karanpratapsingh/system-design-single-sign-on-sso-2cdb</link>
      <guid>https://forem.com/karanpratapsingh/system-design-single-sign-on-sso-2cdb</guid>
      <description>&lt;p&gt;Single Sign-On (SSO) is an authentication process in which a user is provided access to multiple applications or websites by using only a single set of login credentials. This prevents the need for the user to log separately into the different applications.&lt;/p&gt;

&lt;p&gt;The user credentials and other identifying information are stored and managed by a centralized system called Identity Provider (IdP). The Identity Provider is a trusted system that provides access to other websites and applications.&lt;/p&gt;

&lt;p&gt;Single Sign-On (SSO) based authentication systems are commonly used in enterprise environments where employees require access to multiple applications of their organizations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Components
&lt;/h2&gt;

&lt;p&gt;Let's discuss some key components of Single Sign-On (SSO).&lt;/p&gt;

&lt;h3&gt;
  
  
  Identity Provider (IdP)
&lt;/h3&gt;

&lt;p&gt;User Identity information is stored and managed by a centralized system called Identity Provider (IdP). The Identity Provider authenticates the user and provides access to the service provider.&lt;/p&gt;

&lt;p&gt;The identity provider can directly authenticate the user by validating a username and password or by validating an assertion about the user's identity as presented by a separate identity provider. The identity provider handles the management of user identities in order to free the service provider from this responsibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  Service Provider
&lt;/h3&gt;

&lt;p&gt;A service provider provides services to the end-user. They rely on identity providers to assert the identity of a user, and typically certain attributes about the user are managed by the identity provider. Service providers may also maintain a local account for the user along with attributes that are unique to their service.&lt;/p&gt;

&lt;h3&gt;
  
  
  Identity Broker
&lt;/h3&gt;

&lt;p&gt;An identity broker acts as an intermediary that connects multiple service providers with various different identity providers. Using Identity Broker, we can perform single sign-on over any application without the hassle of the protocol it follows.&lt;/p&gt;

&lt;h2&gt;
  
  
  SAML
&lt;/h2&gt;

&lt;p&gt;Security Assertion Markup Language is an open standard that allows clients to share security information about identity, authentication, and permission across different systems. SAML is implemented with the Extensible Markup Language (XML) standard for sharing data.&lt;/p&gt;

&lt;p&gt;SAML specifically enables identity federation, making it possible for identity providers (IdPs) to seamlessly and securely pass authenticated identities and their attributes to service providers.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does SSO work?
&lt;/h2&gt;

&lt;p&gt;Now, let's discuss how Single Sign-On works:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5vs73jbwj8u4njy2i5r6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5vs73jbwj8u4njy2i5r6.png" alt="sso" width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The user requests a resource from their desired application.&lt;/li&gt;
&lt;li&gt;The application redirects the user to the Identity Provider (IdP) for authentication.&lt;/li&gt;
&lt;li&gt;The user signs in with their credentials (usually, username and password).&lt;/li&gt;
&lt;li&gt;Identity Provider (IdP) sends a Single Sign-On response back to the client application.&lt;/li&gt;
&lt;li&gt;The application grants access to the user.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  SAML vs OAuth 2.0 and OpenID Connect (OIDC)
&lt;/h2&gt;

&lt;p&gt;There are many differences between SAML, OAuth, and OIDC. SAML uses XML to pass messages, while OAuth and OIDC use JSON. OAuth provides a simpler experience, while SAML is geared towards enterprise security.&lt;/p&gt;

&lt;p&gt;OAuth and OIDC use RESTful communication extensively, which is why mobile, and modern web applications find OAuth and OIDC a better experience for the user. SAML, on the other hand, drops a session cookie in a browser that allows a user to access certain web pages. This is great for short-lived workloads.&lt;/p&gt;

&lt;p&gt;OIDC is developer-friendly and simpler to implement, which broadens the use cases for which it might be implemented. It can be implemented from scratch pretty fast, via freely available libraries in all common programming languages. SAML can be complex to install and maintain, which only enterprise-size companies can handle well.&lt;/p&gt;

&lt;p&gt;OpenID Connect is essentially a layer on top of the OAuth framework. Therefore, it can offer a built-in layer of permission that asks a user to agree to what the service provider might access. Although SAML is also capable of allowing consent flow, it achieves this by hard-coding carried out by a developer and not as part of its protocol.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Both of these authentication protocols are good at what they do. As always, a lot depends on our specific use cases and target audience.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages
&lt;/h2&gt;

&lt;p&gt;Following are the benefits of using Single Sign-On:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ease of use as users only need to remember one set of credentials.&lt;/li&gt;
&lt;li&gt;Ease of access without having to go through a lengthy authorization process.&lt;/li&gt;
&lt;li&gt;Enforced security and compliance to protect sensitive data.&lt;/li&gt;
&lt;li&gt;Simplifying the management with reduced IT support cost and admin time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Disadvantages
&lt;/h2&gt;

&lt;p&gt;Here are some disadvantages of Single Sign-On:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Single Password Vulnerability, if the main SSO password gets compromised, all the supported applications get compromised.&lt;/li&gt;
&lt;li&gt;The authentication process using Single Sign-On is slower than traditional authentication as every application has to request the SSO provider for verification.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Examples
&lt;/h2&gt;

&lt;p&gt;These are some commonly used Identity Providers (IdP):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.okta.com" rel="noopener noreferrer"&gt;Okta&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/architecture/identity/single-sign-on" rel="noopener noreferrer"&gt;Google&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://auth0.com" rel="noopener noreferrer"&gt;Auth0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.onelogin.com" rel="noopener noreferrer"&gt;OneLogin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;This article is part of my open source &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;System Design Course&lt;/a&gt; available on Github.&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/karanpratapsingh" rel="noopener noreferrer"&gt;
        karanpratapsingh
      &lt;/a&gt; / &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;
        system-design
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Learn how to design systems at scale and prepare for system design interviews
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;System Design&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Hey, welcome to the course. I hope this course provides a great learning experience.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This course is also available on my &lt;a href="https://karanpratapsingh.com/courses/system-design" rel="nofollow noopener noreferrer"&gt;website&lt;/a&gt; and as an ebook on &lt;a href="https://leanpub.com/systemdesign" rel="nofollow noopener noreferrer"&gt;leanpub&lt;/a&gt;. Please leave a ⭐ as motivation if this was helpful!&lt;/em&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Table of contents&lt;/h1&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#what-is-system-design" rel="noopener noreferrer"&gt;What is system design?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter I&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#ip" rel="noopener noreferrer"&gt;IP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#osi-model" rel="noopener noreferrer"&gt;OSI Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#tcp-and-udp" rel="noopener noreferrer"&gt;TCP and UDP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#domain-name-system-dns" rel="noopener noreferrer"&gt;Domain Name System (DNS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#load-balancing" rel="noopener noreferrer"&gt;Load Balancing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#clustering" rel="noopener noreferrer"&gt;Clustering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#caching" rel="noopener noreferrer"&gt;Caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#content-delivery-network-cdn" rel="noopener noreferrer"&gt;Content Delivery Network (CDN)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#proxy" rel="noopener noreferrer"&gt;Proxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#availability" rel="noopener noreferrer"&gt;Availability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#scalability" rel="noopener noreferrer"&gt;Scalability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#storage" rel="noopener noreferrer"&gt;Storage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter II&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#databases-and-dbms" rel="noopener noreferrer"&gt;Databases and DBMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-databases" rel="noopener noreferrer"&gt;SQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#nosql-databases" rel="noopener noreferrer"&gt;NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-vs-nosql-databases" rel="noopener noreferrer"&gt;SQL vs NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-replication" rel="noopener noreferrer"&gt;Database Replication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#indexes" rel="noopener noreferrer"&gt;Indexes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#normalization-and-denormalization" rel="noopener noreferrer"&gt;Normalization and Denormalization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#acid-and-base-consistency-models" rel="noopener noreferrer"&gt;ACID and BASE consistency models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#cap-theorem" rel="noopener noreferrer"&gt;CAP theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#pacelc-theorem" rel="noopener noreferrer"&gt;PACELC Theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#transactions" rel="noopener noreferrer"&gt;Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#distributed-transactions" rel="noopener noreferrer"&gt;Distributed Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#consistent-hashing" rel="noopener noreferrer"&gt;Consistent Hashing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-federation" rel="noopener noreferrer"&gt;Database Federation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter III&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#n-tier-architecture" rel="noopener noreferrer"&gt;N-tier architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-brokers" rel="noopener noreferrer"&gt;Message Brokers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-queues" rel="noopener noreferrer"&gt;Message Queues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#publish-subscribe" rel="noopener noreferrer"&gt;Publish-Subscribe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#enterprise-service-bus-esb" rel="noopener noreferrer"&gt;Enterprise Service Bus (ESB)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#monoliths-and-microservices" rel="noopener noreferrer"&gt;Monoliths and Microservices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-driven-architecture-eda" rel="noopener noreferrer"&gt;Event-Driven Architecture (EDA)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-sourcing" rel="noopener noreferrer"&gt;Event Sourcing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#command-and-query-responsibility-segregation-cqrs" rel="noopener noreferrer"&gt;Command and Query Responsibility Segregation (CQRS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#api-gateway" rel="noopener noreferrer"&gt;API Gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#rest-graphql-grpc" rel="noopener noreferrer"&gt;REST, GraphQL, gRPC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#long-polling-websockets-server-sent-events-sse" rel="noopener noreferrer"&gt;Long polling, WebSockets, Server-Sent Events (SSE)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter IV&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;…&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>distributedsystems</category>
      <category>architecture</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>System Design: OAuth 2.0 and OpenID Connect (OIDC)</title>
      <dc:creator>Karan Pratap Singh</dc:creator>
      <pubDate>Tue, 20 Sep 2022 12:09:56 +0000</pubDate>
      <link>https://forem.com/karanpratapsingh/system-design-oauth-20-and-openid-connect-oidc-5g8c</link>
      <guid>https://forem.com/karanpratapsingh/system-design-oauth-20-and-openid-connect-oidc-5g8c</guid>
      <description>&lt;h2&gt;
  
  
  OAuth 2.0
&lt;/h2&gt;

&lt;p&gt;OAuth 2.0, which stands for Open Authorization, is a standard designed to provide consented access to resources on behalf of the user, without ever sharing the user's credentials. OAuth 2.0 is an authorization protocol and not an authentication protocol, it is designed primarily as a means of granting access to a set of resources, for example, remote APIs or user's data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Concepts
&lt;/h3&gt;

&lt;p&gt;The OAuth 2.0 protocol defines the following entities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Resource Owner&lt;/strong&gt;: The user or system that owns the protected resources and can grant access to them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client&lt;/strong&gt;: The client is the system that requires access to the protected resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authorization Server&lt;/strong&gt;: This server receives requests from the Client for Access Tokens and issues them upon successful authentication and consent by the Resource Owner.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource Server&lt;/strong&gt;: A server that protects the user's resources and receives access requests from the Client. It accepts and validates an Access Token from the Client and returns the appropriate resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scopes&lt;/strong&gt;: They are used to specify exactly the reason for which access to resources may be granted. Acceptable scope values, and which resources they relate to, are dependent on the Resource Server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access Token&lt;/strong&gt;: A piece of data that represents the authorization to access resources on behalf of the end-user.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How does OAuth 2.0 work?
&lt;/h3&gt;

&lt;p&gt;Let's learn how OAuth 2.0 works:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnk20l52hvmpbs3titxe6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnk20l52hvmpbs3titxe6.png" alt="oauth2" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The client requests authorization from the Authorization Server, supplying the client id and secret as identification. It also provides the scopes and an endpoint URI to send the Access Token or the Authorization Code.&lt;/li&gt;
&lt;li&gt;The Authorization Server authenticates the client and verifies that the requested scopes are permitted.&lt;/li&gt;
&lt;li&gt;The resource owner interacts with the authorization server to grant access.&lt;/li&gt;
&lt;li&gt;The Authorization Server redirects back to the client with either an Authorization Code or Access Token, depending on the grant type. A Refresh Token may also be returned.&lt;/li&gt;
&lt;li&gt;With the Access Token, the client can request access to the resource from the Resource Server.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;p&gt;Here are the most common disadvantages of OAuth 2.0:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lacks built-in security features.&lt;/li&gt;
&lt;li&gt;No standard implementation.&lt;/li&gt;
&lt;li&gt;No common set of scopes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  OpenID Connect
&lt;/h2&gt;

&lt;p&gt;OAuth 2.0 is designed only for &lt;em&gt;authorization&lt;/em&gt;, for granting access to data and features from one application to another. OpenID Connect (OIDC) is a thin layer that sits on top of OAuth 2.0 that adds login and profile information about the person who is logged in.&lt;/p&gt;

&lt;p&gt;When an Authorization Server supports OIDC, it is sometimes called an identity provider (IdP), since it provides information about the Resource Owner back to the Client. OpenID Connect is relatively new, resulting in lower adoption and industry implementation of best practices compared to OAuth.&lt;/p&gt;

&lt;h3&gt;
  
  
  Concepts
&lt;/h3&gt;

&lt;p&gt;The OpenID Connect (OIDC) protocol defines the following entities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Relying Party&lt;/strong&gt;: The current application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenID Provider&lt;/strong&gt;: This is essentially an intermediate service that provides a one-time code to the Relying Party.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token Endpoint&lt;/strong&gt;: A web server that accepts the One-Time Code (OTC) and provides an access code that's valid for an hour. The main difference between OIDC and OAuth 2.0 is that the token is provided using JSON Web Token (JWT).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UserInfo Endpoint&lt;/strong&gt;: The Relying Party communicates with this endpoint, providing a secure token and receiving information about the end-user&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both OAuth 2.0 and OIDC are easy to implement and are JSON based, which is supported by most web and mobile applications. However, the OpenID Connect (OIDC) specification is more strict than that of basic OAuth.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This article is part of my open source &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;System Design Course&lt;/a&gt; available on Github.&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/karanpratapsingh" rel="noopener noreferrer"&gt;
        karanpratapsingh
      &lt;/a&gt; / &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;
        system-design
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Learn how to design systems at scale and prepare for system design interviews
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;System Design&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Hey, welcome to the course. I hope this course provides a great learning experience.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This course is also available on my &lt;a href="https://karanpratapsingh.com/courses/system-design" rel="nofollow noopener noreferrer"&gt;website&lt;/a&gt; and as an ebook on &lt;a href="https://leanpub.com/systemdesign" rel="nofollow noopener noreferrer"&gt;leanpub&lt;/a&gt;. Please leave a ⭐ as motivation if this was helpful!&lt;/em&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Table of contents&lt;/h1&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#what-is-system-design" rel="noopener noreferrer"&gt;What is system design?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter I&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#ip" rel="noopener noreferrer"&gt;IP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#osi-model" rel="noopener noreferrer"&gt;OSI Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#tcp-and-udp" rel="noopener noreferrer"&gt;TCP and UDP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#domain-name-system-dns" rel="noopener noreferrer"&gt;Domain Name System (DNS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#load-balancing" rel="noopener noreferrer"&gt;Load Balancing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#clustering" rel="noopener noreferrer"&gt;Clustering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#caching" rel="noopener noreferrer"&gt;Caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#content-delivery-network-cdn" rel="noopener noreferrer"&gt;Content Delivery Network (CDN)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#proxy" rel="noopener noreferrer"&gt;Proxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#availability" rel="noopener noreferrer"&gt;Availability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#scalability" rel="noopener noreferrer"&gt;Scalability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#storage" rel="noopener noreferrer"&gt;Storage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter II&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#databases-and-dbms" rel="noopener noreferrer"&gt;Databases and DBMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-databases" rel="noopener noreferrer"&gt;SQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#nosql-databases" rel="noopener noreferrer"&gt;NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-vs-nosql-databases" rel="noopener noreferrer"&gt;SQL vs NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-replication" rel="noopener noreferrer"&gt;Database Replication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#indexes" rel="noopener noreferrer"&gt;Indexes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#normalization-and-denormalization" rel="noopener noreferrer"&gt;Normalization and Denormalization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#acid-and-base-consistency-models" rel="noopener noreferrer"&gt;ACID and BASE consistency models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#cap-theorem" rel="noopener noreferrer"&gt;CAP theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#pacelc-theorem" rel="noopener noreferrer"&gt;PACELC Theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#transactions" rel="noopener noreferrer"&gt;Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#distributed-transactions" rel="noopener noreferrer"&gt;Distributed Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#consistent-hashing" rel="noopener noreferrer"&gt;Consistent Hashing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-federation" rel="noopener noreferrer"&gt;Database Federation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter III&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#n-tier-architecture" rel="noopener noreferrer"&gt;N-tier architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-brokers" rel="noopener noreferrer"&gt;Message Brokers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-queues" rel="noopener noreferrer"&gt;Message Queues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#publish-subscribe" rel="noopener noreferrer"&gt;Publish-Subscribe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#enterprise-service-bus-esb" rel="noopener noreferrer"&gt;Enterprise Service Bus (ESB)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#monoliths-and-microservices" rel="noopener noreferrer"&gt;Monoliths and Microservices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-driven-architecture-eda" rel="noopener noreferrer"&gt;Event-Driven Architecture (EDA)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-sourcing" rel="noopener noreferrer"&gt;Event Sourcing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#command-and-query-responsibility-segregation-cqrs" rel="noopener noreferrer"&gt;Command and Query Responsibility Segregation (CQRS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#api-gateway" rel="noopener noreferrer"&gt;API Gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#rest-graphql-grpc" rel="noopener noreferrer"&gt;REST, GraphQL, gRPC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#long-polling-websockets-server-sent-events-sse" rel="noopener noreferrer"&gt;Long polling, WebSockets, Server-Sent Events (SSE)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter IV&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;…&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>distributedsystems</category>
      <category>architecture</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>System Design: Virtual Machines (VMs) and Containers</title>
      <dc:creator>Karan Pratap Singh</dc:creator>
      <pubDate>Mon, 19 Sep 2022 06:29:55 +0000</pubDate>
      <link>https://forem.com/karanpratapsingh/system-design-virtual-machines-vms-and-containers-e1m</link>
      <guid>https://forem.com/karanpratapsingh/system-design-virtual-machines-vms-and-containers-e1m</guid>
      <description>&lt;p&gt;Before we discuss virtualization vs containerization, let's learn what are virtual machines (VMs) and Containers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Virtual Machines (VM)
&lt;/h2&gt;

&lt;p&gt;A Virtual Machine (VM) is a virtual environment that functions as a virtual computer system with its own CPU, memory, network interface, and storage, created on a physical hardware system. A software called a hypervisor separates the machine's resources from the hardware and provisions them appropriately so they can be used by the VM.&lt;/p&gt;

&lt;p&gt;VMs are isolated from the rest of the system, and multiple VMs can exist on a single piece of hardware, like a server. They can be moved between host servers depending on the demand or to use resources more efficiently.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a Hypervisor?
&lt;/h3&gt;

&lt;p&gt;A Hypervisor sometimes called a Virtual Machine Monitor (VMM), isolates the operating system and resources from the virtual machines and enables the creation and management of those VMs. The hypervisor treats resources like CPU, memory, and storage as a pool of resources that can be easily reallocated between existing guests or new virtual machines.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why use a Virtual Machine?
&lt;/h3&gt;

&lt;p&gt;Server consolidation is a top reason to use VMs. Most operating system and application deployments only use a small amount of the physical resources available. By virtualizing our servers, we can place many virtual servers onto each physical server to improve hardware utilization. This keeps us from needing to purchase additional physical resources.&lt;/p&gt;

&lt;p&gt;A VM provides an environment that is isolated from the rest of a system, so whatever is running inside a VM won't interfere with anything else running on the host hardware. Because VMs are isolated, they are a good option for testing new applications or setting up a production environment. We can also run a single-purpose VM to support a specific use case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Containers
&lt;/h2&gt;

&lt;p&gt;A container is a standard unit of software that packages up code and all its dependencies such as specific versions of runtimes and libraries so that the application runs quickly and reliably from one computing environment to another. Containers offer a logical packaging mechanism in which applications can be abstracted from the environment in which they actually run. This decoupling allows container-based applications to be deployed easily and consistently, regardless of the target environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why do we need containers?
&lt;/h3&gt;

&lt;p&gt;Let's discuss some advantages of using containers:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Separation of responsibility&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Containerization provides a clear separation of responsibility, as developers focus on application logic and dependencies, while operations teams can focus on deployment and management.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Workload portability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Containers can run virtually anywhere, greatly easing development and deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Application isolation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Containers virtualize CPU, memory, storage, and network resources at the operating system level, providing developers with a view of the OS logically isolated from other applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agile development&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Containers allow developers to move much more quickly by avoiding concerns about dependencies and environments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Efficient operations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Containers are lightweight and allow us to use just the computing resources we need.&lt;/p&gt;

&lt;h2&gt;
  
  
  Virtualization vs Containerization
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fctovwjnqklqg67xudh1u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fctovwjnqklqg67xudh1u.png" alt="virtualization-vs-containerization" width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In traditional virtualization, a hypervisor virtualizes physical hardware. The result is that each virtual machine contains a guest OS, a virtual copy of the hardware that the OS requires to run, and an application and its associated libraries and dependencies.&lt;/p&gt;

&lt;p&gt;Instead of virtualizing the underlying hardware, containers virtualize the operating system so each container contains only the application and its dependencies making them much more lightweight than VMs. Containers also share the OS kernel and use a fraction of the memory VMs require.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This article is part of my open source &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;System Design Course&lt;/a&gt; available on Github.&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/karanpratapsingh" rel="noopener noreferrer"&gt;
        karanpratapsingh
      &lt;/a&gt; / &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;
        system-design
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Learn how to design systems at scale and prepare for system design interviews
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;System Design&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Hey, welcome to the course. I hope this course provides a great learning experience.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This course is also available on my &lt;a href="https://karanpratapsingh.com/courses/system-design" rel="nofollow noopener noreferrer"&gt;website&lt;/a&gt; and as an ebook on &lt;a href="https://leanpub.com/systemdesign" rel="nofollow noopener noreferrer"&gt;leanpub&lt;/a&gt;. Please leave a ⭐ as motivation if this was helpful!&lt;/em&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Table of contents&lt;/h1&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#what-is-system-design" rel="noopener noreferrer"&gt;What is system design?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter I&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#ip" rel="noopener noreferrer"&gt;IP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#osi-model" rel="noopener noreferrer"&gt;OSI Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#tcp-and-udp" rel="noopener noreferrer"&gt;TCP and UDP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#domain-name-system-dns" rel="noopener noreferrer"&gt;Domain Name System (DNS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#load-balancing" rel="noopener noreferrer"&gt;Load Balancing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#clustering" rel="noopener noreferrer"&gt;Clustering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#caching" rel="noopener noreferrer"&gt;Caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#content-delivery-network-cdn" rel="noopener noreferrer"&gt;Content Delivery Network (CDN)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#proxy" rel="noopener noreferrer"&gt;Proxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#availability" rel="noopener noreferrer"&gt;Availability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#scalability" rel="noopener noreferrer"&gt;Scalability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#storage" rel="noopener noreferrer"&gt;Storage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter II&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#databases-and-dbms" rel="noopener noreferrer"&gt;Databases and DBMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-databases" rel="noopener noreferrer"&gt;SQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#nosql-databases" rel="noopener noreferrer"&gt;NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-vs-nosql-databases" rel="noopener noreferrer"&gt;SQL vs NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-replication" rel="noopener noreferrer"&gt;Database Replication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#indexes" rel="noopener noreferrer"&gt;Indexes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#normalization-and-denormalization" rel="noopener noreferrer"&gt;Normalization and Denormalization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#acid-and-base-consistency-models" rel="noopener noreferrer"&gt;ACID and BASE consistency models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#cap-theorem" rel="noopener noreferrer"&gt;CAP theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#pacelc-theorem" rel="noopener noreferrer"&gt;PACELC Theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#transactions" rel="noopener noreferrer"&gt;Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#distributed-transactions" rel="noopener noreferrer"&gt;Distributed Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#consistent-hashing" rel="noopener noreferrer"&gt;Consistent Hashing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-federation" rel="noopener noreferrer"&gt;Database Federation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter III&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#n-tier-architecture" rel="noopener noreferrer"&gt;N-tier architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-brokers" rel="noopener noreferrer"&gt;Message Brokers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-queues" rel="noopener noreferrer"&gt;Message Queues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#publish-subscribe" rel="noopener noreferrer"&gt;Publish-Subscribe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#enterprise-service-bus-esb" rel="noopener noreferrer"&gt;Enterprise Service Bus (ESB)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#monoliths-and-microservices" rel="noopener noreferrer"&gt;Monoliths and Microservices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-driven-architecture-eda" rel="noopener noreferrer"&gt;Event-Driven Architecture (EDA)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-sourcing" rel="noopener noreferrer"&gt;Event Sourcing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#command-and-query-responsibility-segregation-cqrs" rel="noopener noreferrer"&gt;Command and Query Responsibility Segregation (CQRS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#api-gateway" rel="noopener noreferrer"&gt;API Gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#rest-graphql-grpc" rel="noopener noreferrer"&gt;REST, GraphQL, gRPC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#long-polling-websockets-server-sent-events-sse" rel="noopener noreferrer"&gt;Long polling, WebSockets, Server-Sent Events (SSE)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter IV&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;…&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>distributedsystems</category>
      <category>architecture</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>System Design: Disaster recovery</title>
      <dc:creator>Karan Pratap Singh</dc:creator>
      <pubDate>Mon, 19 Sep 2022 06:29:53 +0000</pubDate>
      <link>https://forem.com/karanpratapsingh/system-design-disaster-recovery-3kf4</link>
      <guid>https://forem.com/karanpratapsingh/system-design-disaster-recovery-3kf4</guid>
      <description>&lt;p&gt;Disaster recovery (DR) is a process of regaining access and functionality of the infrastructure after events like a natural disaster, cyber attack, or even business disruptions.&lt;/p&gt;

&lt;p&gt;Disaster recovery relies upon the replication of data and computer processing in an off-premises location not affected by the disaster. When servers go down because of a disaster, a business needs to recover lost data from a second location where the data is backed up. Ideally, an organization can transfer its computer processing to that remote location as well in order to continue operations.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disaster Recovery is often not actively discussed during system design interviews but it's important to have some basic understanding of this topic. You can learn more about disaster recovery from &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/plan-for-disaster-recovery-dr.html" rel="noopener noreferrer"&gt;AWS Well-Architected Framework&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is disaster recovery important?
&lt;/h2&gt;

&lt;p&gt;Disaster recovery can have the following benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Minimize interruption and downtime&lt;/li&gt;
&lt;li&gt;Limit damages&lt;/li&gt;
&lt;li&gt;Fast restoration&lt;/li&gt;
&lt;li&gt;Better customer retention&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Terms
&lt;/h2&gt;

&lt;p&gt;Let's discuss some important terms relevantly for disaster recovery:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F70tpq041b3eovaf0ri0n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F70tpq041b3eovaf0ri0n.png" alt="disaster-recovery" width="800" height="128"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  RTO
&lt;/h3&gt;

&lt;p&gt;Recovery Time Objective (RTO) is the maximum acceptable delay between the interruption of service and restoration of service. This determines what is considered an acceptable time window when service is unavailable.&lt;/p&gt;

&lt;h3&gt;
  
  
  RPO
&lt;/h3&gt;

&lt;p&gt;Recovery Point Objective (RPO) is the maximum acceptable amount of time since the last data recovery point. This determines what is considered an acceptable loss of data between the last recovery point and the interruption of service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Strategies
&lt;/h2&gt;

&lt;p&gt;A variety of disaster recovery (DR) strategies can be part of a disaster recovery plan.&lt;/p&gt;

&lt;h3&gt;
  
  
  Back-up
&lt;/h3&gt;

&lt;p&gt;This is the simplest type of disaster recovery and involves storing data off-site or on a removable drive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cold Site
&lt;/h3&gt;

&lt;p&gt;In this type of disaster recovery, an organization sets up basic infrastructure in a second site.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hot site
&lt;/h3&gt;

&lt;p&gt;A hot site maintains up-to-date copies of data at all times. Hot sites are time-consuming to set up and more expensive than cold sites, but they dramatically reduce downtime.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This article is part of my open source &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;System Design Course&lt;/a&gt; available on Github.&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/karanpratapsingh" rel="noopener noreferrer"&gt;
        karanpratapsingh
      &lt;/a&gt; / &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;
        system-design
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Learn how to design systems at scale and prepare for system design interviews
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;System Design&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Hey, welcome to the course. I hope this course provides a great learning experience.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This course is also available on my &lt;a href="https://karanpratapsingh.com/courses/system-design" rel="nofollow noopener noreferrer"&gt;website&lt;/a&gt; and as an ebook on &lt;a href="https://leanpub.com/systemdesign" rel="nofollow noopener noreferrer"&gt;leanpub&lt;/a&gt;. Please leave a ⭐ as motivation if this was helpful!&lt;/em&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Table of contents&lt;/h1&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#what-is-system-design" rel="noopener noreferrer"&gt;What is system design?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter I&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#ip" rel="noopener noreferrer"&gt;IP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#osi-model" rel="noopener noreferrer"&gt;OSI Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#tcp-and-udp" rel="noopener noreferrer"&gt;TCP and UDP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#domain-name-system-dns" rel="noopener noreferrer"&gt;Domain Name System (DNS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#load-balancing" rel="noopener noreferrer"&gt;Load Balancing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#clustering" rel="noopener noreferrer"&gt;Clustering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#caching" rel="noopener noreferrer"&gt;Caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#content-delivery-network-cdn" rel="noopener noreferrer"&gt;Content Delivery Network (CDN)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#proxy" rel="noopener noreferrer"&gt;Proxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#availability" rel="noopener noreferrer"&gt;Availability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#scalability" rel="noopener noreferrer"&gt;Scalability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#storage" rel="noopener noreferrer"&gt;Storage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter II&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#databases-and-dbms" rel="noopener noreferrer"&gt;Databases and DBMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-databases" rel="noopener noreferrer"&gt;SQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#nosql-databases" rel="noopener noreferrer"&gt;NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-vs-nosql-databases" rel="noopener noreferrer"&gt;SQL vs NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-replication" rel="noopener noreferrer"&gt;Database Replication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#indexes" rel="noopener noreferrer"&gt;Indexes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#normalization-and-denormalization" rel="noopener noreferrer"&gt;Normalization and Denormalization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#acid-and-base-consistency-models" rel="noopener noreferrer"&gt;ACID and BASE consistency models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#cap-theorem" rel="noopener noreferrer"&gt;CAP theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#pacelc-theorem" rel="noopener noreferrer"&gt;PACELC Theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#transactions" rel="noopener noreferrer"&gt;Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#distributed-transactions" rel="noopener noreferrer"&gt;Distributed Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#consistent-hashing" rel="noopener noreferrer"&gt;Consistent Hashing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-federation" rel="noopener noreferrer"&gt;Database Federation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter III&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#n-tier-architecture" rel="noopener noreferrer"&gt;N-tier architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-brokers" rel="noopener noreferrer"&gt;Message Brokers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-queues" rel="noopener noreferrer"&gt;Message Queues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#publish-subscribe" rel="noopener noreferrer"&gt;Publish-Subscribe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#enterprise-service-bus-esb" rel="noopener noreferrer"&gt;Enterprise Service Bus (ESB)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#monoliths-and-microservices" rel="noopener noreferrer"&gt;Monoliths and Microservices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-driven-architecture-eda" rel="noopener noreferrer"&gt;Event-Driven Architecture (EDA)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-sourcing" rel="noopener noreferrer"&gt;Event Sourcing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#command-and-query-responsibility-segregation-cqrs" rel="noopener noreferrer"&gt;Command and Query Responsibility Segregation (CQRS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#api-gateway" rel="noopener noreferrer"&gt;API Gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#rest-graphql-grpc" rel="noopener noreferrer"&gt;REST, GraphQL, gRPC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#long-polling-websockets-server-sent-events-sse" rel="noopener noreferrer"&gt;Long polling, WebSockets, Server-Sent Events (SSE)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter IV&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;…&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>distributedsystems</category>
      <category>architecture</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>System Design: SLA, SLO, SLI</title>
      <dc:creator>Karan Pratap Singh</dc:creator>
      <pubDate>Mon, 19 Sep 2022 06:29:51 +0000</pubDate>
      <link>https://forem.com/karanpratapsingh/system-design-sla-slo-sli-446p</link>
      <guid>https://forem.com/karanpratapsingh/system-design-sla-slo-sli-446p</guid>
      <description>&lt;p&gt;Let's briefly discuss SLA, SLO, and SLI. These are mostly related to the business and site reliability side of things but good to know nonetheless.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why are they important?
&lt;/h2&gt;

&lt;p&gt;SLAs, SLOs, and SLIs allow companies to define, track and monitor the promises made for a service to its users. Together, SLAs, SLOs, and SLIs should help teams generate more user trust in their services with an added emphasis on continuous improvement to incident management and response processes.&lt;/p&gt;

&lt;h2&gt;
  
  
  SLA
&lt;/h2&gt;

&lt;p&gt;An SLA, or Service Level Agreement, is an agreement made between a company and its users of a given service. The SLA defines the different promises that the company makes to users regarding specific metrics, such as service availability.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;SLAs are often written by a company's business or legal team.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  SLO
&lt;/h2&gt;

&lt;p&gt;An SLO, or Service Level Objective, is the promise that a company makes to users regarding a specific metric such as incident response or uptime. SLOs exist within an SLA as individual promises contained within the full user agreement. The SLO is the specific goal that the service must meet in order to comply with the SLA. SLOs should always be simple, clearly defined, and easily measured to determine whether or not the objective is being fulfilled.&lt;/p&gt;

&lt;h2&gt;
  
  
  SLI
&lt;/h2&gt;

&lt;p&gt;An SLI, or Service Level Indicator, is a key metric used to determine whether or not the SLO is being met. It is the measured value of the metric described within the SLO. In order to remain in compliance with the SLA, the SLI's value must always meet or exceed the value determined by the SLO.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This article is part of my open source &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;System Design Course&lt;/a&gt; available on Github.&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/karanpratapsingh" rel="noopener noreferrer"&gt;
        karanpratapsingh
      &lt;/a&gt; / &lt;a href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;
        system-design
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Learn how to design systems at scale and prepare for system design interviews
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;System Design&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Hey, welcome to the course. I hope this course provides a great learning experience.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This course is also available on my &lt;a href="https://karanpratapsingh.com/courses/system-design" rel="nofollow noopener noreferrer"&gt;website&lt;/a&gt; and as an ebook on &lt;a href="https://leanpub.com/systemdesign" rel="nofollow noopener noreferrer"&gt;leanpub&lt;/a&gt;. Please leave a ⭐ as motivation if this was helpful!&lt;/em&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Table of contents&lt;/h1&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#what-is-system-design" rel="noopener noreferrer"&gt;What is system design?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter I&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#ip" rel="noopener noreferrer"&gt;IP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#osi-model" rel="noopener noreferrer"&gt;OSI Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#tcp-and-udp" rel="noopener noreferrer"&gt;TCP and UDP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#domain-name-system-dns" rel="noopener noreferrer"&gt;Domain Name System (DNS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#load-balancing" rel="noopener noreferrer"&gt;Load Balancing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#clustering" rel="noopener noreferrer"&gt;Clustering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#caching" rel="noopener noreferrer"&gt;Caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#content-delivery-network-cdn" rel="noopener noreferrer"&gt;Content Delivery Network (CDN)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#proxy" rel="noopener noreferrer"&gt;Proxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#availability" rel="noopener noreferrer"&gt;Availability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#scalability" rel="noopener noreferrer"&gt;Scalability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#storage" rel="noopener noreferrer"&gt;Storage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter II&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#databases-and-dbms" rel="noopener noreferrer"&gt;Databases and DBMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-databases" rel="noopener noreferrer"&gt;SQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#nosql-databases" rel="noopener noreferrer"&gt;NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sql-vs-nosql-databases" rel="noopener noreferrer"&gt;SQL vs NoSQL databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-replication" rel="noopener noreferrer"&gt;Database Replication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#indexes" rel="noopener noreferrer"&gt;Indexes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#normalization-and-denormalization" rel="noopener noreferrer"&gt;Normalization and Denormalization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#acid-and-base-consistency-models" rel="noopener noreferrer"&gt;ACID and BASE consistency models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#cap-theorem" rel="noopener noreferrer"&gt;CAP theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#pacelc-theorem" rel="noopener noreferrer"&gt;PACELC Theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#transactions" rel="noopener noreferrer"&gt;Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#distributed-transactions" rel="noopener noreferrer"&gt;Distributed Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#sharding" rel="noopener noreferrer"&gt;Sharding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#consistent-hashing" rel="noopener noreferrer"&gt;Consistent Hashing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#database-federation" rel="noopener noreferrer"&gt;Database Federation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter III&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#n-tier-architecture" rel="noopener noreferrer"&gt;N-tier architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-brokers" rel="noopener noreferrer"&gt;Message Brokers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#message-queues" rel="noopener noreferrer"&gt;Message Queues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#publish-subscribe" rel="noopener noreferrer"&gt;Publish-Subscribe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#enterprise-service-bus-esb" rel="noopener noreferrer"&gt;Enterprise Service Bus (ESB)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#monoliths-and-microservices" rel="noopener noreferrer"&gt;Monoliths and Microservices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-driven-architecture-eda" rel="noopener noreferrer"&gt;Event-Driven Architecture (EDA)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#event-sourcing" rel="noopener noreferrer"&gt;Event Sourcing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#command-and-query-responsibility-segregation-cqrs" rel="noopener noreferrer"&gt;Command and Query Responsibility Segregation (CQRS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#api-gateway" rel="noopener noreferrer"&gt;API Gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#rest-graphql-grpc" rel="noopener noreferrer"&gt;REST, GraphQL, gRPC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/karanpratapsingh/system-design#long-polling-websockets-server-sent-events-sse" rel="noopener noreferrer"&gt;Long polling, WebSockets, Server-Sent Events (SSE)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chapter IV&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;…&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/karanpratapsingh/system-design" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>distributedsystems</category>
      <category>architecture</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
