<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Engineering At Scale]]></title><description><![CDATA[Weekly column simplifying databases, system design, architecture, and engineering careers with easy explanations, valuable insights, and expert advice.]]></description><link>https://engineeringatscale.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!M_xX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7efb20e0-ea8c-4c24-a919-8bdd744eb285_500x500.png</url><title>Engineering At Scale</title><link>https://engineeringatscale.substack.com</link></image><generator>Substack</generator><lastBuildDate>Sat, 11 Apr 2026 05:40:42 GMT</lastBuildDate><atom:link href="https://engineeringatscale.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Animesh Gaitonde]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[engineeringatscale@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[engineeringatscale@substack.com]]></itunes:email><itunes:name><![CDATA[Animesh Gaitonde]]></itunes:name></itunes:owner><itunes:author><![CDATA[Animesh Gaitonde]]></itunes:author><googleplay:owner><![CDATA[engineeringatscale@substack.com]]></googleplay:owner><googleplay:email><![CDATA[engineeringatscale@substack.com]]></googleplay:email><googleplay:author><![CDATA[Animesh Gaitonde]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[How Distributed Systems Store Files: Databases, Object Storage, and the Trade-offs]]></title><description><![CDATA[From database BLOBs to object stores &#8212; understanding the architecture patterns and when to use each]]></description><link>https://engineeringatscale.substack.com/p/when-to-use-blob-storage-vs-database</link><guid isPermaLink="false">https://engineeringatscale.substack.com/p/when-to-use-blob-storage-vs-database</guid><dc:creator><![CDATA[Animesh Gaitonde]]></dc:creator><pubDate>Sun, 22 Mar 2026 02:23:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!EPZ1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0acef4-fcf3-4570-b1f2-1685be7d5670_3062x1386.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>What&#8217;s the right approach for storing a file? Should you store it in a database or in a blob storage service like S3? &#129300;</p><p>A few years ago, I ran into this exact question while designing a file upload service. After weighing the trade-offs, I chose object storage for scalability and cost.</p><p>But that decision isn&#8217;t always obvious.</p><p>Are there cases where storing files directly in the database is actually the better choice? &#129300;</p><p>In this article, we&#8217;ll break down both the approaches, explore their trade-offs, and look at how real systems decide between them.</p><p>With that, let&#8217;s begin by defining the problem statement for our system.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/subscribe?"><span>Subscribe now</span></a></p><h2>Problem Statement</h2><p>We want to build a web application that supports:</p><ol><li><p>File uploads with metadata (title, description, category).</p></li><li><p>Retrieves recent uploads with image previews.</p></li></ol><p>The diagram below shows the application&#8217;s UI screen.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9_Eq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c3da90-e9b7-429a-aecc-9d11d276bbe7_1024x990.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9_Eq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c3da90-e9b7-429a-aecc-9d11d276bbe7_1024x990.png 424w, https://substackcdn.com/image/fetch/$s_!9_Eq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c3da90-e9b7-429a-aecc-9d11d276bbe7_1024x990.png 848w, https://substackcdn.com/image/fetch/$s_!9_Eq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c3da90-e9b7-429a-aecc-9d11d276bbe7_1024x990.png 1272w, https://substackcdn.com/image/fetch/$s_!9_Eq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c3da90-e9b7-429a-aecc-9d11d276bbe7_1024x990.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9_Eq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c3da90-e9b7-429a-aecc-9d11d276bbe7_1024x990.png" width="1024" height="990" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/91c3da90-e9b7-429a-aecc-9d11d276bbe7_1024x990.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:990,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:75071,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/191023489?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c3da90-e9b7-429a-aecc-9d11d276bbe7_1024x990.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9_Eq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c3da90-e9b7-429a-aecc-9d11d276bbe7_1024x990.png 424w, https://substackcdn.com/image/fetch/$s_!9_Eq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c3da90-e9b7-429a-aecc-9d11d276bbe7_1024x990.png 848w, https://substackcdn.com/image/fetch/$s_!9_Eq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c3da90-e9b7-429a-aecc-9d11d276bbe7_1024x990.png 1272w, https://substackcdn.com/image/fetch/$s_!9_Eq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91c3da90-e9b7-429a-aecc-9d11d276bbe7_1024x990.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>File Upload</strong></figcaption></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!aYLh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84a1468d-9af0-4cd9-b114-ebfad182db35_1608x474.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!aYLh!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84a1468d-9af0-4cd9-b114-ebfad182db35_1608x474.png 424w, https://substackcdn.com/image/fetch/$s_!aYLh!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84a1468d-9af0-4cd9-b114-ebfad182db35_1608x474.png 848w, https://substackcdn.com/image/fetch/$s_!aYLh!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84a1468d-9af0-4cd9-b114-ebfad182db35_1608x474.png 1272w, https://substackcdn.com/image/fetch/$s_!aYLh!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84a1468d-9af0-4cd9-b114-ebfad182db35_1608x474.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!aYLh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84a1468d-9af0-4cd9-b114-ebfad182db35_1608x474.png" width="1456" height="429" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/84a1468d-9af0-4cd9-b114-ebfad182db35_1608x474.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:429,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:143401,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/191023489?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84a1468d-9af0-4cd9-b114-ebfad182db35_1608x474.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!aYLh!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84a1468d-9af0-4cd9-b114-ebfad182db35_1608x474.png 424w, https://substackcdn.com/image/fetch/$s_!aYLh!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84a1468d-9af0-4cd9-b114-ebfad182db35_1608x474.png 848w, https://substackcdn.com/image/fetch/$s_!aYLh!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84a1468d-9af0-4cd9-b114-ebfad182db35_1608x474.png 1272w, https://substackcdn.com/image/fetch/$s_!aYLh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84a1468d-9af0-4cd9-b114-ebfad182db35_1608x474.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Recent Uploads</strong></figcaption></figure></div><p>Let&#8217;s explore the simplest technique to solve this problem.</p><h2>Naive Solution - Store files in the database</h2><p>Most databases can persist files in a binary format. PostgreSQL provides a data type <strong>bytea</strong> to store raw binary data directly inside the database. </p><p>Here&#8217;s how you can define a schema with a column to store binary files:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QqDn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34105e44-5981-4cf7-bd73-bdc651ae1004_1040x472.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QqDn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34105e44-5981-4cf7-bd73-bdc651ae1004_1040x472.png 424w, https://substackcdn.com/image/fetch/$s_!QqDn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34105e44-5981-4cf7-bd73-bdc651ae1004_1040x472.png 848w, https://substackcdn.com/image/fetch/$s_!QqDn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34105e44-5981-4cf7-bd73-bdc651ae1004_1040x472.png 1272w, https://substackcdn.com/image/fetch/$s_!QqDn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34105e44-5981-4cf7-bd73-bdc651ae1004_1040x472.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QqDn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34105e44-5981-4cf7-bd73-bdc651ae1004_1040x472.png" width="1040" height="472" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/34105e44-5981-4cf7-bd73-bdc651ae1004_1040x472.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:472,&quot;width&quot;:1040,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:130338,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/191023489?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34105e44-5981-4cf7-bd73-bdc651ae1004_1040x472.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!QqDn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34105e44-5981-4cf7-bd73-bdc651ae1004_1040x472.png 424w, https://substackcdn.com/image/fetch/$s_!QqDn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34105e44-5981-4cf7-bd73-bdc651ae1004_1040x472.png 848w, https://substackcdn.com/image/fetch/$s_!QqDn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34105e44-5981-4cf7-bd73-bdc651ae1004_1040x472.png 1272w, https://substackcdn.com/image/fetch/$s_!QqDn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34105e44-5981-4cf7-bd73-bdc651ae1004_1040x472.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>File upload schema</strong></figcaption></figure></div><p>In the above schema, the field <strong>file_data </strong>will store the binary file data. </p><p>Most databases (e.g., PostgreSQL bytea, MySQL BLOB, MongoDB GridFS) support storing binary data directly.</p><p>You can use any database of our choice and add backend servers that expose upload and retrieval APIs to build the application.</p><p>The diagram below shows the detailed architecture of our system.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!19cm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef1e9204-8d07-4015-96a7-d3e6f1bf1f40_2868x982.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!19cm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef1e9204-8d07-4015-96a7-d3e6f1bf1f40_2868x982.png 424w, https://substackcdn.com/image/fetch/$s_!19cm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef1e9204-8d07-4015-96a7-d3e6f1bf1f40_2868x982.png 848w, https://substackcdn.com/image/fetch/$s_!19cm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef1e9204-8d07-4015-96a7-d3e6f1bf1f40_2868x982.png 1272w, https://substackcdn.com/image/fetch/$s_!19cm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef1e9204-8d07-4015-96a7-d3e6f1bf1f40_2868x982.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!19cm!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef1e9204-8d07-4015-96a7-d3e6f1bf1f40_2868x982.png" width="1200" height="411.2637362637363" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ef1e9204-8d07-4015-96a7-d3e6f1bf1f40_2868x982.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:499,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:224865,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/191023489?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef1e9204-8d07-4015-96a7-d3e6f1bf1f40_2868x982.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!19cm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef1e9204-8d07-4015-96a7-d3e6f1bf1f40_2868x982.png 424w, https://substackcdn.com/image/fetch/$s_!19cm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef1e9204-8d07-4015-96a7-d3e6f1bf1f40_2868x982.png 848w, https://substackcdn.com/image/fetch/$s_!19cm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef1e9204-8d07-4015-96a7-d3e6f1bf1f40_2868x982.png 1272w, https://substackcdn.com/image/fetch/$s_!19cm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef1e9204-8d07-4015-96a7-d3e6f1bf1f40_2868x982.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>File Upload system architecture</strong></figcaption></figure></div><p>Our solution is simple and easy to manage with less dependencies. This works well for low-traffic, basic use cases.</p><p>But, what would happen with more uploads or user growth? Would the system scale? &#129300;</p><p>Before reading further, take a moment to think what can go wrong while operating the system at scale.</p><h3>Challenges</h3><ul><li><p><strong>Performance bottlenecks:</strong> Large binary data increases memory usage, slows queries, and impacts backend throughput.</p></li><li><p><strong>Backend server performance</strong> - With traffic growth, increased memory pressure on backend servers leads to Out of Memory errors leading to unavailability.</p></li><li><p><strong>Size constraints:</strong> Databases impose limits on maximum field sizes. For example: PostgreSQL limits the max field size to <strong>1 GB</strong> while MySQL supports <strong>4 GB</strong>.</p></li><li><p><strong>Operational overhead:</strong> Replication and backups become slower due to large data volumes.</p></li><li><p><strong>Cost inefficiency</strong> - Databases are <strong>5-20x</strong> more expensive for storing large binary objects than blob storage.</p></li></ul><p>We will now see how we can address these challenges through a well-known pattern used in the industry.</p><h2>Blob storage for file content, Database for metadata</h2><p>Instead of storing the whole file in the database, we can separate file content from metadata and store them independently. Here&#8217;s how we can solve it:</p><ul><li><p><strong>File content</strong> - The actual raw binary data can be stored in a blob storage like S3.</p></li><li><p><strong>File metadata</strong> - The attributes(title, description, etc) can be stored in any database along with the reference to the path of the file stored in the blob storage.</p></li></ul><p>We will remove the <strong>file_data </strong>column from the table and substitute it with <strong>file_path</strong> column. Here&#8217;s the new database schema:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eXYX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5ba86d-1981-48bb-9182-a6ef71f57c63_1024x448.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eXYX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5ba86d-1981-48bb-9182-a6ef71f57c63_1024x448.png 424w, https://substackcdn.com/image/fetch/$s_!eXYX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5ba86d-1981-48bb-9182-a6ef71f57c63_1024x448.png 848w, https://substackcdn.com/image/fetch/$s_!eXYX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5ba86d-1981-48bb-9182-a6ef71f57c63_1024x448.png 1272w, https://substackcdn.com/image/fetch/$s_!eXYX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5ba86d-1981-48bb-9182-a6ef71f57c63_1024x448.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eXYX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5ba86d-1981-48bb-9182-a6ef71f57c63_1024x448.png" width="1024" height="448" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3d5ba86d-1981-48bb-9182-a6ef71f57c63_1024x448.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:448,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:132460,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/191023489?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5ba86d-1981-48bb-9182-a6ef71f57c63_1024x448.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!eXYX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5ba86d-1981-48bb-9182-a6ef71f57c63_1024x448.png 424w, https://substackcdn.com/image/fetch/$s_!eXYX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5ba86d-1981-48bb-9182-a6ef71f57c63_1024x448.png 848w, https://substackcdn.com/image/fetch/$s_!eXYX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5ba86d-1981-48bb-9182-a6ef71f57c63_1024x448.png 1272w, https://substackcdn.com/image/fetch/$s_!eXYX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5ba86d-1981-48bb-9182-a6ef71f57c63_1024x448.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>New database schema with file_path</strong></figcaption></figure></div><p>Unlike the previous approach, the file upload becomes a two step process:</p><ol><li><p> Store metadata and generate a pre-signed URL.</p></li><li><p>Upload file content directly to object storage using that pre-signed URL.</p></li></ol><p>The diagram below illustrates the process and the architecture.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EPZ1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0acef4-fcf3-4570-b1f2-1685be7d5670_3062x1386.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EPZ1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0acef4-fcf3-4570-b1f2-1685be7d5670_3062x1386.png 424w, https://substackcdn.com/image/fetch/$s_!EPZ1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0acef4-fcf3-4570-b1f2-1685be7d5670_3062x1386.png 848w, https://substackcdn.com/image/fetch/$s_!EPZ1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0acef4-fcf3-4570-b1f2-1685be7d5670_3062x1386.png 1272w, https://substackcdn.com/image/fetch/$s_!EPZ1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0acef4-fcf3-4570-b1f2-1685be7d5670_3062x1386.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EPZ1!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0acef4-fcf3-4570-b1f2-1685be7d5670_3062x1386.png" width="1200" height="543.1318681318681" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5b0acef4-fcf3-4570-b1f2-1685be7d5670_3062x1386.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:659,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:303459,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/191023489?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0acef4-fcf3-4570-b1f2-1685be7d5670_3062x1386.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!EPZ1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0acef4-fcf3-4570-b1f2-1685be7d5670_3062x1386.png 424w, https://substackcdn.com/image/fetch/$s_!EPZ1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0acef4-fcf3-4570-b1f2-1685be7d5670_3062x1386.png 848w, https://substackcdn.com/image/fetch/$s_!EPZ1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0acef4-fcf3-4570-b1f2-1685be7d5670_3062x1386.png 1272w, https://substackcdn.com/image/fetch/$s_!EPZ1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0acef4-fcf3-4570-b1f2-1685be7d5670_3062x1386.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>File Upload Process</strong></figcaption></figure></div><p>Here&#8217;s how this solution overcomes the challenges of the naive approach:</p><ol><li><p><strong>Database performance</strong> - The database doesn&#8217;t store binary content. Since the metadata size for each record is less than 100 KBs, it can easily scale to millions of records without any performance impact.</p></li><li><p><strong>Backend server performance</strong> - Files are served directly from blob storage, bypassing the backend entirely. This prevents Out of Memory errors ensuring high availability.</p></li><li><p><strong>Database constraints </strong>- The blob storage doesn&#8217;t impose specific limits and can scale to handle terabytes of data.</p></li><li><p><strong>Database backup and replication</strong> - Backups and replication are faster since large files are excluded.</p></li><li><p><strong>Cost</strong> <strong>efficiency </strong>- Storing data in a blob storage is significantly cheaper than storing in a database. This significantly reduces the application costs.</p></li></ol><p>While this solution is efficient and scalable, it has the following downsides:</p><ul><li><p><strong>Eventual consistency: </strong>Metadata and file content are stored separately, requiring reconciliation.</p></li><li><p><strong>Operational complexity: </strong>Multi-step uploads and failure handling (e.g., retries, cleanup) must be managed.</p></li><li><p><strong>Dual backups:</strong> Both database and object storage must be maintained reliably.</p></li></ul><p>However, the above trade-offs are acceptable given its scalability benefits.</p><blockquote><p><strong>Food for thought</strong> - How do you handle file upload failures while using blob storage? &#129300; (Leave your thoughts in the comments)</p></blockquote><p>Now that you know two solutions exist, how do you choose between the two while solving real-world problems?</p><p>Let&#8217;s now walk through a few real-world scenarios and understand the suitable approach with the reasoning for each.</p><h2>Real-world scenarios</h2><h3>Financial transactions and receipts</h3><p>Financial transactions store the receipts in the form of pdf or image files. They also require strong atomicity guarantees.</p><p>For example: The system must generate receipt immediately after receiving the amount and persist it. A multi-step process involving a blob storage upload is not ACID compliant and requires separate reconciliation pipeline for eventual consistency.</p><p>Relational databases provide strong consistency out of the box. This makes them appropriate for use cases like storing invoices, receipts, signed tax forms, etc.</p><h3>Social media assets</h3><p>Storing billions of files in a database isn&#8217;t practical for social media companies like WhatsApp, Instagram, X, etc. They prefer to keep the media files such as images, videos and gifs in blob storage than the database.</p><p>Blob storage allows users to store large files (&gt; <strong>100 MB</strong>) through multi-part uploads. Similarly, the direct CDN integration and caching improves read performance.</p><h3>Configuration files</h3><p>Software development teams keep YAML, XML and other small configuration files in the database. Unlike social media assets, these files are not viewed frequently on a UI and only read once by the application during the startup.</p><h3>Secure/controlled access environments</h3><p>For strict security and regulatory compliance, defense or government systems store files in databases that provide built-in encryption, access control, and audit logging.</p><h2>Conclusion</h2><p>We learnt that there&#8217;s no one size fits all solution for storing files. Each problem is unique with its own constraints.</p><p>The below table provides a framework to choose between the two approaches based on the different quality attributes.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uSzM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2ee05ee-3400-42a9-b866-74e554b179d0_2022x806.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uSzM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2ee05ee-3400-42a9-b866-74e554b179d0_2022x806.png 424w, https://substackcdn.com/image/fetch/$s_!uSzM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2ee05ee-3400-42a9-b866-74e554b179d0_2022x806.png 848w, https://substackcdn.com/image/fetch/$s_!uSzM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2ee05ee-3400-42a9-b866-74e554b179d0_2022x806.png 1272w, https://substackcdn.com/image/fetch/$s_!uSzM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2ee05ee-3400-42a9-b866-74e554b179d0_2022x806.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uSzM!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2ee05ee-3400-42a9-b866-74e554b179d0_2022x806.png" width="1200" height="478.02197802197804" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c2ee05ee-3400-42a9-b866-74e554b179d0_2022x806.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:580,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:352084,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/191023489?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2ee05ee-3400-42a9-b866-74e554b179d0_2022x806.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uSzM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2ee05ee-3400-42a9-b866-74e554b179d0_2022x806.png 424w, https://substackcdn.com/image/fetch/$s_!uSzM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2ee05ee-3400-42a9-b866-74e554b179d0_2022x806.png 848w, https://substackcdn.com/image/fetch/$s_!uSzM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2ee05ee-3400-42a9-b866-74e554b179d0_2022x806.png 1272w, https://substackcdn.com/image/fetch/$s_!uSzM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2ee05ee-3400-42a9-b866-74e554b179d0_2022x806.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Decision matrix to choose between the two approaches</strong></figcaption></figure></div><p>If your system prioritizes strong consistency, simplicity, and small file sizes, storing files directly in the database can be the right decision. </p><p>But if you need scalability, high-throughput and cost-efficiency, blob storage becomes the most robust and future-proof choice.</p><p>Many companies often adopt a hybrid approach - using databases for critical, tightly coupled data and object storage for large, scalable assets. </p><p>This helps companies get best of both worlds rather than constraining to one pattern.</p><p>The key is to decide based on the first principles: data size, access patterns, consistency guarantees, and operational complexity&#8212;not just convention.</p><p>What approach are you using today&#8212;database or object storage? &#129300; And what trade-offs have you run into? Leave your thoughts in the comments below.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/when-to-use-blob-storage-vs-database?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/p/when-to-use-blob-storage-vs-database?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p>Before you go:</p><ul><li><p>&#10084;&#65039; the story and follow the newsletter for more such articles</p></li><li><p>&#128276; Follow me: <a href="https://www.linkedin.com/in/animesh-gaitonde/">LinkedIn</a>, <a href="https://twitter.com/animesh3436">Twitter</a>, <a href="https://medium.com/@animeshgaitonde">Medium</a></p></li><li><p>Your support helps keep this newsletter free and fuels future content. Consider a small donation to show your appreciation here - <a href="https://www.paypal.com/ncp/payment/EUGP54EHQFDZC">Paypal Donate</a></p></li></ul><p></p>]]></content:encoded></item><item><title><![CDATA[Database Proxies: Connection Management at Scale]]></title><description><![CDATA[How to scale a database to handle 100K connections?]]></description><link>https://engineeringatscale.substack.com/p/scaling-databases-with-proxies</link><guid isPermaLink="false">https://engineeringatscale.substack.com/p/scaling-databases-with-proxies</guid><dc:creator><![CDATA[Animesh Gaitonde]]></dc:creator><pubDate>Sat, 13 Dec 2025 09:58:15 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!UkUZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35e6b1bb-5df0-47a7-8538-5bc00624faf9_2790x1632.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the last article, we learned how connection pools play a pivotal role in managing database connections. </p><p>But, do they fully safeguard a database from unexpected traffic spikes? Would adding 10 service instances result in a 10&#215; increase in database connections? &#129300;</p><p>Database proxies prevent this by residing between the service and the database and acting as connection multiplexers.</p><p>Moreover, proxies also help in solving other challenges such request routing, query caching, failover, and so on ensuring scalability and reliability.</p><p>In this article, we will understand how proxies solve the scaling and availability challenges in distributed systems. The article will also discuss trade-offs and include a decision matrix to guide the proxy decision.</p><p>With that, let&#8217;s first understand the various challenges in building distributed applications with a relational database like PostgreSQL or MySQL.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://engineeringatscale.substack.com/subscribe?"><span>Subscribe now</span></a></p><h2>Distributed System Challenges</h2><p>Assume that we have a service managing social media tweets that is capable of handling <strong>4K</strong> TPS. Let&#8217;s say that it fetches the data from a PostgreSQL instance by creating <strong>100</strong> connections.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cegS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F315fa385-b831-4678-af7a-a2ed85a6c1d7_1894x520.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cegS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F315fa385-b831-4678-af7a-a2ed85a6c1d7_1894x520.png 424w, https://substackcdn.com/image/fetch/$s_!cegS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F315fa385-b831-4678-af7a-a2ed85a6c1d7_1894x520.png 848w, https://substackcdn.com/image/fetch/$s_!cegS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F315fa385-b831-4678-af7a-a2ed85a6c1d7_1894x520.png 1272w, https://substackcdn.com/image/fetch/$s_!cegS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F315fa385-b831-4678-af7a-a2ed85a6c1d7_1894x520.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cegS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F315fa385-b831-4678-af7a-a2ed85a6c1d7_1894x520.png" width="1456" height="400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/315fa385-b831-4678-af7a-a2ed85a6c1d7_1894x520.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:96535,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/180864059?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F315fa385-b831-4678-af7a-a2ed85a6c1d7_1894x520.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!cegS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F315fa385-b831-4678-af7a-a2ed85a6c1d7_1894x520.png 424w, https://substackcdn.com/image/fetch/$s_!cegS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F315fa385-b831-4678-af7a-a2ed85a6c1d7_1894x520.png 848w, https://substackcdn.com/image/fetch/$s_!cegS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F315fa385-b831-4678-af7a-a2ed85a6c1d7_1894x520.png 1272w, https://substackcdn.com/image/fetch/$s_!cegS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F315fa385-b831-4678-af7a-a2ed85a6c1d7_1894x520.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Application with 100 database connections</strong></figcaption></figure></div><p>What would happen if the TPS rises<strong> </strong>from <strong>4K </strong>to <strong>40K</strong>? How would we manage the additional load?</p><h3>Scaling</h3><p>We would need to deploy 10 service instances to handle the load of <strong>40K</strong> TPS. Since each service instance requires 100 connections, there would be 1000 (<strong>100 x 10</strong>) connections to our PostgreSQL instance.</p><p>The diagram below illustrates how horizontal scaling can increase the number of database connections.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Vypf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcad3043-c986-4b85-8936-243ff0a75ff4_2190x1346.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Vypf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcad3043-c986-4b85-8936-243ff0a75ff4_2190x1346.png 424w, https://substackcdn.com/image/fetch/$s_!Vypf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcad3043-c986-4b85-8936-243ff0a75ff4_2190x1346.png 848w, https://substackcdn.com/image/fetch/$s_!Vypf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcad3043-c986-4b85-8936-243ff0a75ff4_2190x1346.png 1272w, https://substackcdn.com/image/fetch/$s_!Vypf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcad3043-c986-4b85-8936-243ff0a75ff4_2190x1346.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Vypf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcad3043-c986-4b85-8936-243ff0a75ff4_2190x1346.png" width="1456" height="895" data-attrs="{&quot;src&quot;:&quot;https://substackcdn.com/image/fetch/$s_!Vypf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcad3043-c986-4b85-8936-243ff0a75ff4_2190x1346.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:895,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:219682,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/180864059?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcad3043-c986-4b85-8936-243ff0a75ff4_2190x1346.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Vypf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcad3043-c986-4b85-8936-243ff0a75ff4_2190x1346.png 424w, https://substackcdn.com/image/fetch/$s_!Vypf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcad3043-c986-4b85-8936-243ff0a75ff4_2190x1346.png 848w, https://substackcdn.com/image/fetch/$s_!Vypf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcad3043-c986-4b85-8936-243ff0a75ff4_2190x1346.png 1272w, https://substackcdn.com/image/fetch/$s_!Vypf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcad3043-c986-4b85-8936-243ff0a75ff4_2190x1346.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>How horizontal scaling increases database connections.</strong></figcaption></figure></div><p>The database would struggle to handle the connection surge and fail new connections. Thus, the database would become a bottleneck and limit the system&#8217;s scalability.</p><h3>Duplicate requests</h3><p>At <strong>40K TPS</strong>, there would be multiple requests for the same resource. For example: a request to fetch the same tweet.</p><p>With several instances, the same SQL query would be executed multiple times returning the same data. This would result in an additional database load slowing the overall execution and leading to a poor user experience.</p><p>We can solve this challenge through a technique known as <strong>sharding</strong> that distributes the data over multiple database or by having read replicas. But it brings in a different set of challenges that we will see in the next section.</p><h3>Sharding and Read replicas</h3><p>With several database instances, we now need to pass the configuration (host, port, etc) of each database instance to the application. We need to write additional code so that the application is aware of the different shards and handle the read/write segregation explicitly.</p><p>This introduces the following challenges:</p><ol><li><p><strong>Tight coupling</strong> - The application is tightly coupled with the sharding logic and the available shards.</p></li><li><p><strong>Scaling challenges</strong> - The application needs to be updated with the addition of each new replica by passing the updated configuration.</p></li><li><p><strong>Inflexibility</strong> - If application code is rewritten in a different stack, it would require duplication of the existing sharding logic.</p></li></ol><p>The below diagram shows how an architecture involving database replicas and read/write segregation increases the complexity.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XmI1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8efcb9e0-3f4f-4f6d-b902-f40d8b170f4e_1964x1246.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XmI1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8efcb9e0-3f4f-4f6d-b902-f40d8b170f4e_1964x1246.png 424w, https://substackcdn.com/image/fetch/$s_!XmI1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8efcb9e0-3f4f-4f6d-b902-f40d8b170f4e_1964x1246.png 848w, https://substackcdn.com/image/fetch/$s_!XmI1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8efcb9e0-3f4f-4f6d-b902-f40d8b170f4e_1964x1246.png 1272w, https://substackcdn.com/image/fetch/$s_!XmI1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8efcb9e0-3f4f-4f6d-b902-f40d8b170f4e_1964x1246.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XmI1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8efcb9e0-3f4f-4f6d-b902-f40d8b170f4e_1964x1246.png" width="1456" height="924" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8efcb9e0-3f4f-4f6d-b902-f40d8b170f4e_1964x1246.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:924,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:210938,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/180864059?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8efcb9e0-3f4f-4f6d-b902-f40d8b170f4e_1964x1246.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!XmI1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8efcb9e0-3f4f-4f6d-b902-f40d8b170f4e_1964x1246.png 424w, https://substackcdn.com/image/fetch/$s_!XmI1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8efcb9e0-3f4f-4f6d-b902-f40d8b170f4e_1964x1246.png 848w, https://substackcdn.com/image/fetch/$s_!XmI1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8efcb9e0-3f4f-4f6d-b902-f40d8b170f4e_1964x1246.png 1272w, https://substackcdn.com/image/fetch/$s_!XmI1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8efcb9e0-3f4f-4f6d-b902-f40d8b170f4e_1964x1246.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Database shard with replicas</strong></figcaption></figure></div><p>While these problems can be solved, it would require building a library for handling the sharding logic. We would need to develop this for every programming language and database.</p><p>Now that you understand the core problem, let&#8217;s understand how Database proxies solve the problem.</p><h2>What is a database proxy?</h2><p>Database proxies are software applications that sit between a service and a database. They create and manage a pool of database connections, and applications connect to the proxy instead of directly to the database.</p><p>They intercept the service connections and multiplex them onto a fixed pool of database connections.</p><p>The below sequence diagram shows how the process works.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!woUr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0553e70f-f2a1-40c0-8599-25735d117c6c_1692x1172.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!woUr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0553e70f-f2a1-40c0-8599-25735d117c6c_1692x1172.png 424w, https://substackcdn.com/image/fetch/$s_!woUr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0553e70f-f2a1-40c0-8599-25735d117c6c_1692x1172.png 848w, https://substackcdn.com/image/fetch/$s_!woUr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0553e70f-f2a1-40c0-8599-25735d117c6c_1692x1172.png 1272w, https://substackcdn.com/image/fetch/$s_!woUr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0553e70f-f2a1-40c0-8599-25735d117c6c_1692x1172.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!woUr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0553e70f-f2a1-40c0-8599-25735d117c6c_1692x1172.png" width="1456" height="1009" data-attrs="{&quot;src&quot;:&quot;https://substackcdn.com/image/fetch/$s_!woUr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0553e70f-f2a1-40c0-8599-25735d117c6c_1692x1172.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1009,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:170455,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/180864059?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0553e70f-f2a1-40c0-8599-25735d117c6c_1692x1172.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!woUr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0553e70f-f2a1-40c0-8599-25735d117c6c_1692x1172.png 424w, https://substackcdn.com/image/fetch/$s_!woUr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0553e70f-f2a1-40c0-8599-25735d117c6c_1692x1172.png 848w, https://substackcdn.com/image/fetch/$s_!woUr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0553e70f-f2a1-40c0-8599-25735d117c6c_1692x1172.png 1272w, https://substackcdn.com/image/fetch/$s_!woUr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0553e70f-f2a1-40c0-8599-25735d117c6c_1692x1172.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>How a Database Proxy Works</strong></figcaption></figure></div><p>Let&#8217;s now understand how Proxies solve the scaling challenges described in the previous section.</p><h3>Scaling</h3><p>Proxies create a fixed number of connections to the database. While the service-proxy connections increase with horizontal scaling, the number of database connections remains constant.</p><p>This design protects the database from additional connections reducing the chances of failing new connections. Similarly, the load on the database remains stable due to fixed number of connections.</p><blockquote><p>How many connections do you think a single Proxy can support? &#129300; (Share your answers in the comments below)</p></blockquote><p>The following diagram shows how Proxy handles additional connections from application by keeping fixed number of database connections.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UkUZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35e6b1bb-5df0-47a7-8538-5bc00624faf9_2790x1632.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UkUZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35e6b1bb-5df0-47a7-8538-5bc00624faf9_2790x1632.png 424w, https://substackcdn.com/image/fetch/$s_!UkUZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35e6b1bb-5df0-47a7-8538-5bc00624faf9_2790x1632.png 848w, https://substackcdn.com/image/fetch/$s_!UkUZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35e6b1bb-5df0-47a7-8538-5bc00624faf9_2790x1632.png 1272w, https://substackcdn.com/image/fetch/$s_!UkUZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35e6b1bb-5df0-47a7-8538-5bc00624faf9_2790x1632.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UkUZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35e6b1bb-5df0-47a7-8538-5bc00624faf9_2790x1632.png" width="1456" height="852" data-attrs="{&quot;src&quot;:&quot;https://substackcdn.com/image/fetch/$s_!UkUZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35e6b1bb-5df0-47a7-8538-5bc00624faf9_2790x1632.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:852,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:314957,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/180864059?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35e6b1bb-5df0-47a7-8538-5bc00624faf9_2790x1632.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!UkUZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35e6b1bb-5df0-47a7-8538-5bc00624faf9_2790x1632.png 424w, https://substackcdn.com/image/fetch/$s_!UkUZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35e6b1bb-5df0-47a7-8538-5bc00624faf9_2790x1632.png 848w, https://substackcdn.com/image/fetch/$s_!UkUZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35e6b1bb-5df0-47a7-8538-5bc00624faf9_2790x1632.png 1272w, https://substackcdn.com/image/fetch/$s_!UkUZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35e6b1bb-5df0-47a7-8538-5bc00624faf9_2790x1632.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>How a proxy prevents database connection spikes.</strong></figcaption></figure></div><p>Functions as a Service (FaaS) platforms like Lambdas widely adopt proxies. Since every Lambda is short-lived, every invocation leads to setup and teardown of a database connection.</p><p>Additionally, the problem amplifies when the number of concurrent executions exceeds maximum database connections. </p><p>With proxies, Lambdas no longer connect to the database directly and instead connect to the proxies. As a result, the database remains shielded from any spike in the Lambda layer.</p><h3>Read Caching</h3><p>Many proxies can be configured to cache the database query results. The proxy then returns the results from the cache instead of executing the database query.</p><p>Caching improves the response time and also reduces the overall load on the database. Proxies such as ProxySQL and Pgpool-II support native in-memory caching with configurable cache size and the TTL (time-to-live).</p><h3>Sharding and Read replicas</h3><p>Proxies can be configured with rules to segregate the read/write requests. Similarly, we can leverage the same technique to shard the data across several database servers.</p><p>The following diagram shows how proxies simplify configuration and abstract database shards/replicas.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uPe8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e63e63-32ea-43fa-a39b-0f16497aa1e3_2916x1508.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uPe8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e63e63-32ea-43fa-a39b-0f16497aa1e3_2916x1508.png 424w, https://substackcdn.com/image/fetch/$s_!uPe8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e63e63-32ea-43fa-a39b-0f16497aa1e3_2916x1508.png 848w, https://substackcdn.com/image/fetch/$s_!uPe8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e63e63-32ea-43fa-a39b-0f16497aa1e3_2916x1508.png 1272w, https://substackcdn.com/image/fetch/$s_!uPe8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e63e63-32ea-43fa-a39b-0f16497aa1e3_2916x1508.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uPe8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e63e63-32ea-43fa-a39b-0f16497aa1e3_2916x1508.png" width="1456" height="753" data-attrs="{&quot;src&quot;:&quot;https://substackcdn.com/image/fetch/$s_!uPe8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e63e63-32ea-43fa-a39b-0f16497aa1e3_2916x1508.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:753,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:327129,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/180864059?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e63e63-32ea-43fa-a39b-0f16497aa1e3_2916x1508.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!uPe8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e63e63-32ea-43fa-a39b-0f16497aa1e3_2916x1508.png 424w, https://substackcdn.com/image/fetch/$s_!uPe8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e63e63-32ea-43fa-a39b-0f16497aa1e3_2916x1508.png 848w, https://substackcdn.com/image/fetch/$s_!uPe8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e63e63-32ea-43fa-a39b-0f16497aa1e3_2916x1508.png 1272w, https://substackcdn.com/image/fetch/$s_!uPe8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e63e63-32ea-43fa-a39b-0f16497aa1e3_2916x1508.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Sharding/Replication with and without a database proxy</strong></figcaption></figure></div><p>Unlike traditional ways of hardcoding sharding in the application, proxies help through:</p><ol><li><p><strong>Reduced coupling</strong> - The sharding logic is abstracted and configurable eliminating the tight coupling.</p></li><li><p><strong>Ease of scaling </strong>- New shards/replicas can be easily introduced by making configuration changes using admin interface.</p></li><li><p><strong>Flexibility</strong> - Rewriting the application code wouldn&#8217;t require additional efforts to integrate the sharding logic.</p></li></ol><p>While database proxies offer several benefits, do you think it makes sense to use it always?. Let&#8217;s now dive into the trade-offs that would help us decide whether to use a proxy or not.</p><h2>Trade-offs</h2><h3>Deployment complexity</h3><p>Since proxies are separate applications, they need to be deployed resulting in an additional overhead. This overhead compounds when you have to deploy a proxy on a different machine than the database server.</p><h3>Maintenance overhead</h3><p>The development team now needs to maintain, patch and update the proxy. Similarly, they need to manage the OS upgrades and fix vulnerabilities in the server hosting the proxy.</p><h3>Latency</h3><p>Since the queries go via the proxy, it could increases the latency by 10-15 ms. This could impact the performance in case the application requires strict latencies.</p><p>Proxies are a must when your system has complex use cases such as sharding, replication, read/write segregation and caching. In such cases, the benefits outweigh the costs. However, for a single database system, they are can often become an overkill.</p><p>Let&#8217;s conclude with a decision matrix to help you decide whether to use a proxy.</p><h2>Conclusion</h2><p>While database proxies are versatile and solve several distributed system challenges, they are not always required. Before using one, you should think about your workload, performance needs, and the complexity that you are willing to manage. </p><p>Here&#8217;s a decision matrix to help you decide whether you should use a proxy in your architecture.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xTDV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f780cc-4f51-47f2-b8ad-5f4627df493b_1680x1264.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xTDV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f780cc-4f51-47f2-b8ad-5f4627df493b_1680x1264.png 424w, https://substackcdn.com/image/fetch/$s_!xTDV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f780cc-4f51-47f2-b8ad-5f4627df493b_1680x1264.png 848w, https://substackcdn.com/image/fetch/$s_!xTDV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f780cc-4f51-47f2-b8ad-5f4627df493b_1680x1264.png 1272w, https://substackcdn.com/image/fetch/$s_!xTDV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f780cc-4f51-47f2-b8ad-5f4627df493b_1680x1264.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xTDV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f780cc-4f51-47f2-b8ad-5f4627df493b_1680x1264.png" width="1456" height="1095" data-attrs="{&quot;src&quot;:&quot;https://substackcdn.com/image/fetch/$s_!xTDV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f780cc-4f51-47f2-b8ad-5f4627df493b_1680x1264.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1095,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:257696,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/180864059?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f780cc-4f51-47f2-b8ad-5f4627df493b_1680x1264.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!xTDV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f780cc-4f51-47f2-b8ad-5f4627df493b_1680x1264.png 424w, https://substackcdn.com/image/fetch/$s_!xTDV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f780cc-4f51-47f2-b8ad-5f4627df493b_1680x1264.png 848w, https://substackcdn.com/image/fetch/$s_!xTDV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f780cc-4f51-47f2-b8ad-5f4627df493b_1680x1264.png 1272w, https://substackcdn.com/image/fetch/$s_!xTDV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42f780cc-4f51-47f2-b8ad-5f4627df493b_1680x1264.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Decision matrix to decide a proxy</strong></figcaption></figure></div><p>Now that you understand the working of proxies, here&#8217;s a question that&#8217;s worth reflecting on - Can proxies become a single point of failure and bring down your application? &#129300; If yes, how do we prevent such scenarios? </p><p>Leave your thoughts in the comments below. We will address this question in the next article.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/scaling-databases-with-proxies?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/p/scaling-databases-with-proxies?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p>Before you go:</p><ul><li><p>&#10084;&#65039; the story and follow the newsletter for more such articles</p></li><li><p>&#128276; Follow me: <a href="https://www.linkedin.com/in/animesh-gaitonde/">LinkedIn</a>, <a href="https://twitter.com/animesh3436">Twitter</a>, <a href="https://medium.com/@animeshgaitonde">Medium</a></p></li><li><p>Your support helps keep this newsletter free and fuels future content. Consider a small donation to show your appreciation here - <a href="https://www.paypal.com/ncp/payment/EUGP54EHQFDZC">Paypal Donate</a></p></li></ul><div><hr></div><p><em><strong><a href="https://www.linkedin.com/company/educative-inc/">Educative</a></strong> has officially launched their Year End sale&#8212; and it&#8217;s their strongest offer of the entire year. </em></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-FuX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cb79738-ea54-4fd3-9b61-4fc71ad22efb_2714x618.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-FuX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cb79738-ea54-4fd3-9b61-4fc71ad22efb_2714x618.png 424w, https://substackcdn.com/image/fetch/$s_!-FuX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cb79738-ea54-4fd3-9b61-4fc71ad22efb_2714x618.png 848w, https://substackcdn.com/image/fetch/$s_!-FuX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cb79738-ea54-4fd3-9b61-4fc71ad22efb_2714x618.png 1272w, https://substackcdn.com/image/fetch/$s_!-FuX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cb79738-ea54-4fd3-9b61-4fc71ad22efb_2714x618.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-FuX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cb79738-ea54-4fd3-9b61-4fc71ad22efb_2714x618.png" width="1456" height="332" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4cb79738-ea54-4fd3-9b61-4fc71ad22efb_2714x618.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:332,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:378155,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/180864059?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cb79738-ea54-4fd3-9b61-4fc71ad22efb_2714x618.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!-FuX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cb79738-ea54-4fd3-9b61-4fc71ad22efb_2714x618.png 424w, https://substackcdn.com/image/fetch/$s_!-FuX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cb79738-ea54-4fd3-9b61-4fc71ad22efb_2714x618.png 848w, https://substackcdn.com/image/fetch/$s_!-FuX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cb79738-ea54-4fd3-9b61-4fc71ad22efb_2714x618.png 1272w, https://substackcdn.com/image/fetch/$s_!-FuX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cb79738-ea54-4fd3-9b61-4fc71ad22efb_2714x618.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><em>Whether you&#8217;re preparing for interviews, mastering new technologies, or strengthening your fundamentals, Educative provides high-quality, in-browser learning with no setup required.</em></p><p><em>Use my <a href="https://www.educative.io/courses/grokking-the-system-design-interview?aff=BYJl">link</a> to get an extra 10% off</em></p><div><hr></div>]]></content:encoded></item><item><title><![CDATA[Connection Pooling: Fundamentals, Challenges and Trade-offs]]></title><description><![CDATA[How to handle 10,000 concurrent requests without crashing your database]]></description><link>https://engineeringatscale.substack.com/p/database-connection-pooling-guide</link><guid isPermaLink="false">https://engineeringatscale.substack.com/p/database-connection-pooling-guide</guid><dc:creator><![CDATA[Animesh Gaitonde]]></dc:creator><pubDate>Sat, 29 Nov 2025 10:47:26 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!7sz4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722200d3-1692-4173-a51b-1c56a44c4eca_2416x632.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Database integration is easy until your application receives thousands of concurrent requests.  Your application can horizontally scale and handle spike in user requests, but the database like PostgreSQL, or MySQL would struggle to do so.</p><p>Under the hood, your application uses a TCP connection to connect to the database. A spike in the number of connections would overwhelm the database and slow down the query execution.</p><p>Connection pooling solves this by maintaining a pool of reusable connections. While the concept appears simple, there&#8217;s complex engineering behind an effective connection pool implementation.</p><p>In this article, we will dive deep and understand how connection pooling works. We will explore the different challenges that a connection pooling library tackles and common trade-offs that engineers make while using a connection pool.</p><p>With that, let&#8217;s see what happens under the hood when your application executes a query.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/subscribe?"><span>Subscribe now</span></a></p><h2>Query Execution</h2><p>Let&#8217;s assume that your system stores users in a relational database like PostgreSQL and exposes an API to fetch user information. Your application will execute the query - <code>Select * from users where userId = 30 </code>to fetch the user information.</p><p>The below diagram illustrates the database connection establishment that happens before your application executes any query.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kctZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5ac991d-ef35-4eac-b052-190fafd3b9f8_1858x950.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kctZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5ac991d-ef35-4eac-b052-190fafd3b9f8_1858x950.png 424w, https://substackcdn.com/image/fetch/$s_!kctZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5ac991d-ef35-4eac-b052-190fafd3b9f8_1858x950.png 848w, https://substackcdn.com/image/fetch/$s_!kctZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5ac991d-ef35-4eac-b052-190fafd3b9f8_1858x950.png 1272w, https://substackcdn.com/image/fetch/$s_!kctZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5ac991d-ef35-4eac-b052-190fafd3b9f8_1858x950.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kctZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5ac991d-ef35-4eac-b052-190fafd3b9f8_1858x950.png" width="728" height="372" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d5ac991d-ef35-4eac-b052-190fafd3b9f8_1858x950.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:744,&quot;width&quot;:1456,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:154760,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/180228646?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5ac991d-ef35-4eac-b052-190fafd3b9f8_1858x950.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kctZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5ac991d-ef35-4eac-b052-190fafd3b9f8_1858x950.png 424w, https://substackcdn.com/image/fetch/$s_!kctZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5ac991d-ef35-4eac-b052-190fafd3b9f8_1858x950.png 848w, https://substackcdn.com/image/fetch/$s_!kctZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5ac991d-ef35-4eac-b052-190fafd3b9f8_1858x950.png 1272w, https://substackcdn.com/image/fetch/$s_!kctZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5ac991d-ef35-4eac-b052-190fafd3b9f8_1858x950.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Database connection establishment</strong></figcaption></figure></div><p>The connection establishment can take anywhere between <strong>20-50 ms</strong> and <strong>200+ ms</strong> if the database is in a different region.</p><p>With this setup, what would happen if the clients make multiple API calls to fetch different users?</p><p>Here&#8217;s what would happen for every API call:-</p><ol><li><p>The application would create a database connection.</p></li><li><p>It would use the connection and send the SQL query.</p></li><li><p>Get and process the results of the SQL query and send the data back to the client.</p></li></ol><p>The below diagram shows how the application would create a connection for every API call.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bmSV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa06f4907-b0a5-42b0-8629-e4a119560873_2010x796.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bmSV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa06f4907-b0a5-42b0-8629-e4a119560873_2010x796.png 424w, https://substackcdn.com/image/fetch/$s_!bmSV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa06f4907-b0a5-42b0-8629-e4a119560873_2010x796.png 848w, https://substackcdn.com/image/fetch/$s_!bmSV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa06f4907-b0a5-42b0-8629-e4a119560873_2010x796.png 1272w, https://substackcdn.com/image/fetch/$s_!bmSV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa06f4907-b0a5-42b0-8629-e4a119560873_2010x796.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bmSV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa06f4907-b0a5-42b0-8629-e4a119560873_2010x796.png" width="1456" height="577" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a06f4907-b0a5-42b0-8629-e4a119560873_2010x796.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:577,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:178777,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/180228646?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa06f4907-b0a5-42b0-8629-e4a119560873_2010x796.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!bmSV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa06f4907-b0a5-42b0-8629-e4a119560873_2010x796.png 424w, https://substackcdn.com/image/fetch/$s_!bmSV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa06f4907-b0a5-42b0-8629-e4a119560873_2010x796.png 848w, https://substackcdn.com/image/fetch/$s_!bmSV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa06f4907-b0a5-42b0-8629-e4a119560873_2010x796.png 1272w, https://substackcdn.com/image/fetch/$s_!bmSV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa06f4907-b0a5-42b0-8629-e4a119560873_2010x796.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Per-request connection model</strong></figcaption></figure></div><p>While the above setup may work for 100-200 requests per second, do you think it would handle <strong>10K</strong> or <strong>100K</strong> requests?</p><p>Let&#8217;s explore in the next section the ways in which the system would break.</p><h2>Database limitations</h2><p> Let&#8217;s evaluate the impact on scalability, resource utilisation and performance.</p><h3>Scalability</h3><p>If the system receives <strong>10K</strong> RPS (requests per second), it would make equal number of connections to the database. Most of the databases are not optimized to handle <strong>10K</strong> simultaneous connections. For eg:- PostgreSQL sets default max value of connections to <strong>100</strong> (can be increased).</p><p>This would result in connection throttling and database would return an error like &#8220;<em><strong>sorry, too many clients already</strong></em>&#8220;.</p><h3>Resource utilisation</h3><p>At 10K RPS, the CPU utilisation would spike to handle large number of TCP connections. It would also increase the context switching and potential network-level throttling.</p><p>Every connection also consumes memory and it would increase the chances of memory exhaustion in database.</p><h3>Performance</h3><p>Every connection setup would add 20-50 ms to the latency. Further, resource exhaustion would slow down the queries and increase the API latency. The slowness would degrade the user experience.</p><p>As a result, the database becomes a bottleneck when a connection is created for every request. Let&#8217;s now see ways to overcome this bottleneck through Connection Pooling.</p><h2>Connection Pooling</h2><p>A connection pool is a collection of pre-established database connections that an application can reuse. Here&#8217;s how an application creates and uses the connection pool:</p><ol><li><p>During the application startup, the application creates pre-defined number of database connections.</p></li><li><p>The connections are then stored in a data structure for future use.</p></li><li><p>If an application thread wants to execute a query, it would borrow one connection, use it for query execution and return it back to the pool after completion.</p></li><li><p>In case all the connections are exhausted, the thread waits until a connection becomes available and then continue its execution.</p></li></ol><p>The below diagram describes how a connection pool works.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7sz4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722200d3-1692-4173-a51b-1c56a44c4eca_2416x632.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7sz4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722200d3-1692-4173-a51b-1c56a44c4eca_2416x632.png 424w, https://substackcdn.com/image/fetch/$s_!7sz4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722200d3-1692-4173-a51b-1c56a44c4eca_2416x632.png 848w, https://substackcdn.com/image/fetch/$s_!7sz4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722200d3-1692-4173-a51b-1c56a44c4eca_2416x632.png 1272w, https://substackcdn.com/image/fetch/$s_!7sz4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722200d3-1692-4173-a51b-1c56a44c4eca_2416x632.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7sz4!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722200d3-1692-4173-a51b-1c56a44c4eca_2416x632.png" width="1200" height="314.010989010989" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/722200d3-1692-4173-a51b-1c56a44c4eca_2416x632.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:381,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:190133,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/180228646?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722200d3-1692-4173-a51b-1c56a44c4eca_2416x632.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7sz4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722200d3-1692-4173-a51b-1c56a44c4eca_2416x632.png 424w, https://substackcdn.com/image/fetch/$s_!7sz4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722200d3-1692-4173-a51b-1c56a44c4eca_2416x632.png 848w, https://substackcdn.com/image/fetch/$s_!7sz4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722200d3-1692-4173-a51b-1c56a44c4eca_2416x632.png 1272w, https://substackcdn.com/image/fetch/$s_!7sz4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F722200d3-1692-4173-a51b-1c56a44c4eca_2416x632.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>How Connection Pool works</strong></figcaption></figure></div><p>Here&#8217;s sample Java code that illustrates how connection pool is used by an application.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!q9mA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f00d438-d87a-45fb-84d9-c7ac1dbd926f_1256x1408.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!q9mA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f00d438-d87a-45fb-84d9-c7ac1dbd926f_1256x1408.png 424w, https://substackcdn.com/image/fetch/$s_!q9mA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f00d438-d87a-45fb-84d9-c7ac1dbd926f_1256x1408.png 848w, https://substackcdn.com/image/fetch/$s_!q9mA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f00d438-d87a-45fb-84d9-c7ac1dbd926f_1256x1408.png 1272w, https://substackcdn.com/image/fetch/$s_!q9mA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f00d438-d87a-45fb-84d9-c7ac1dbd926f_1256x1408.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!q9mA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f00d438-d87a-45fb-84d9-c7ac1dbd926f_1256x1408.png" width="1256" height="1408" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0f00d438-d87a-45fb-84d9-c7ac1dbd926f_1256x1408.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1408,&quot;width&quot;:1256,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:348463,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/180228646?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f00d438-d87a-45fb-84d9-c7ac1dbd926f_1256x1408.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!q9mA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f00d438-d87a-45fb-84d9-c7ac1dbd926f_1256x1408.png 424w, https://substackcdn.com/image/fetch/$s_!q9mA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f00d438-d87a-45fb-84d9-c7ac1dbd926f_1256x1408.png 848w, https://substackcdn.com/image/fetch/$s_!q9mA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f00d438-d87a-45fb-84d9-c7ac1dbd926f_1256x1408.png 1272w, https://substackcdn.com/image/fetch/$s_!q9mA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f00d438-d87a-45fb-84d9-c7ac1dbd926f_1256x1408.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Java Code using Connection Pool</strong></figcaption></figure></div><p>The above code uses a popular library named <strong>Hikari-CP</strong> in Java. As seen in the code, it first initializes the pool&#8217;s configuration using parameters such as maximum pool size, idle connection count, etc and then fetches the connection.</p><p>With the above approach, the connection pool ensures:</p><ul><li><p><strong>Scalability</strong> - The database is not overwhelmed with large number of connections preventing connection throttling. </p></li><li><p><strong>Resource utilization</strong> - Since the number of connections are limited, it optimally uses resources such as memory, network and CPU.</p></li><li><p><strong>Performance</strong> - The connection creation overhead is eliminated and thus can save <strong>20-50 ms </strong>for every query execution. Further, limited connections exert less pressure on the database ensuring predictable performance.</p></li></ul><div><hr></div><p><em>The Biggest Black Friday Deal for Developers Is LIVE!<br>Educative just launched their Black Friday + Cyber Monday sale, and it&#8217;s hands down their best offer of the entire year.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!T-HT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff87484dc-80cf-479b-bece-f72985b1d09b_2791x1461.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!T-HT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff87484dc-80cf-479b-bece-f72985b1d09b_2791x1461.jpeg 424w, https://substackcdn.com/image/fetch/$s_!T-HT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff87484dc-80cf-479b-bece-f72985b1d09b_2791x1461.jpeg 848w, https://substackcdn.com/image/fetch/$s_!T-HT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff87484dc-80cf-479b-bece-f72985b1d09b_2791x1461.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!T-HT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff87484dc-80cf-479b-bece-f72985b1d09b_2791x1461.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!T-HT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff87484dc-80cf-479b-bece-f72985b1d09b_2791x1461.jpeg" width="1456" height="762" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f87484dc-80cf-479b-bece-f72985b1d09b_2791x1461.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:762,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:376778,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/180228646?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff87484dc-80cf-479b-bece-f72985b1d09b_2791x1461.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!T-HT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff87484dc-80cf-479b-bece-f72985b1d09b_2791x1461.jpeg 424w, https://substackcdn.com/image/fetch/$s_!T-HT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff87484dc-80cf-479b-bece-f72985b1d09b_2791x1461.jpeg 848w, https://substackcdn.com/image/fetch/$s_!T-HT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff87484dc-80cf-479b-bece-f72985b1d09b_2791x1461.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!T-HT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff87484dc-80cf-479b-bece-f72985b1d09b_2791x1461.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Look no further than Educative.io&#8217;s course on <a href="https://www.educative.io/courses/grokking-the-system-design-interview">Grokking the System Design Interview</a>. You can use this <a href="https://www.educative.io/unlimited?aff=BYJl">link</a> to get an additional 10% off.</em></p><div><hr></div><h2>Pool-size Trade-offs</h2><p>One question that puzzles most developers is What should be the right pool size? When I first used a connection pool, it took me several weeks of tuning to get the correct pool size.</p><p>Here&#8217;s why getting the right pool size is a tough nut to crack:</p><ol><li><p><strong>Small pool size</strong> - Small size implies few connections and less database resources. With request spike, waiting time increases for additional requests slowing down the execution.</p></li><li><p><strong>Large pool size</strong> - Large pool size are reliable to handle a sudden spike in the load without degrading the performance. However, it wastes resources if the workload has low volume.</p></li></ol><p>There&#8217;s a resource-performance trade-off and developers need to strike a right balance between the two.</p><p>Instead of blindly setting the pool size, one can follow the following approach:</p><ol><li><p>Start with a small pool size (20-30 connections).</p></li><li><p>Load test with real traffic and observe the impact on metrics such as database CPU, memory, wait time, request latency, etc</p></li><li><p>Experiment with different number of connections and observe the impact on the metrics.</p></li><li><p>Keep a buffer of 15-20% above peak usage while setting the maximum pool size.</p></li></ol><p>At times, it helps to have multiple pools with each catered for a different workload pattern. For eg:- A small pool for low-volume traffic and a large pool for high-volume traffic.</p><p>Now that you understand the trade-offs, let&#8217;s uncover the challenges behind building a connection pool.</p><h2>Challenges</h2><p>The connection pool&#8217;s <code>dataSource.getConnection()</code> abstracts most of the complexity from the users. It hides all the challenging semantics related to concurrency, database driver and network.</p><p>Building a connection pool library from scratch is exciting and equally gruelling task for a developer. Unlike usual programming task, it involves design considerations such as:</p><ul><li><p><strong>High-performance</strong> - It must be able to handle multiple concurrent calls with low contention. Best libraries often leverage lock-free data structure to achieve the same.</p></li><li><p><strong>Zero-overhead</strong> - Connection creation is an expensive process and results in a performance penalty. Hence, the library must ensure it returns live connections.</p></li><li><p><strong>Simple and flexible</strong> - The interface must be simple to use and easily configurable through parameter tuning.</p></li></ul><p>If you want to learn more about connection pooling, you can go through the code of one of the open source libraries. Personally, I would recommend navigating <a href="https://github.com/brettwooldridge/HikariCP">HikariCP</a>&#8217;s code.</p><p>Moreover, if you are learning a new language like Rust, you can build a connection pooling library from scratch and then experiment with it.</p><p>So far, we considered a single application instance using a connection pool for our understanding. In case there are 10x instances, wouldn&#8217;t the number of database connections also 10x? &#129300;</p><p>Wouldn&#8217;t the database get overwhelmed this time again? &#129300; If yes, how can we solve this? Leave your thoughts in the comments below. We&#8217;ll take up this question in the next article on database proxies.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/database-connection-pooling-guide?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/p/database-connection-pooling-guide?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p>Before you go:</p><ul><li><p>&#10084;&#65039; the story and follow the newsletter for more such articles</p></li><li><p>&#128276; Follow me: <a href="https://www.linkedin.com/in/animesh-gaitonde/">LinkedIn</a>, <a href="https://twitter.com/animesh3436">Twitter</a>, <a href="https://medium.com/@animeshgaitonde">Medium</a></p></li><li><p>Your support helps keep this newsletter free and fuels future content. Consider a small donation to show your appreciation here - <a href="https://www.paypal.com/ncp/payment/EUGP54EHQFDZC">Paypal Donate</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[API Pagination: Techniques, Real-World Applications And Best Practices]]></title><description><![CDATA[Learn how X (Twitter) and Spotify use API pagination to handle massive datasets efficiently]]></description><link>https://engineeringatscale.substack.com/p/api-pagination-limit-offset-vs-cursor</link><guid isPermaLink="false">https://engineeringatscale.substack.com/p/api-pagination-limit-offset-vs-cursor</guid><dc:creator><![CDATA[Animesh Gaitonde]]></dc:creator><pubDate>Mon, 20 Oct 2025 13:05:47 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!3CtP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2c7213f-6249-448c-a155-70c9e41872fb_2840x1698.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Introduction</h2><p>Have you wondered how X(Twitter) let&#8217;s you scroll infinitely through a stream of tweets? Does the app pre-fetch all the data or does it fetch as you scroll?</p><p>Similarly, how does Spotify let you view all the albums and songs of any artist in a single page? Does it use a technique similar to X?</p><p>Both the features solve the same fundamental Computer Science problem - <em>Retrieve and display a subset of data from a large dataset</em>.</p><p>That&#8217;s where <strong>API pagination</strong> comes in. It&#8217;s a technique that splits large datasets into smaller chunks that are fetched and displayed as needed.</p><p>In this article, we&#8217;ll break down how pagination works under the hood using real-world examples from X and Spotify. </p><p>By the end, you&#8217;ll be able to confidently choose the right pagination strategy by understanding the trade-offs between <strong>Limit-Offset</strong> and <strong>Cursor-based</strong> pagination.</p><p>Let&#8217;s start by exploring <strong>why pagination is even necessary.</strong></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/subscribe?"><span>Subscribe now</span></a></p><p></p><h2>Why Pagination?</h2><p>Imagine you&#8217;re building a system like X, where the client fetches tweets from a server. The server stores billions of tweets, but each user might only need a few dozen at a time for an infinite scroll experience.</p><p><strong>What if we fetched everything upfront?</strong></p><p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oTeX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56046e3d-2557-43ac-9611-65777b67d9e1_2614x1258.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oTeX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56046e3d-2557-43ac-9611-65777b67d9e1_2614x1258.png 424w, https://substackcdn.com/image/fetch/$s_!oTeX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56046e3d-2557-43ac-9611-65777b67d9e1_2614x1258.png 848w, https://substackcdn.com/image/fetch/$s_!oTeX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56046e3d-2557-43ac-9611-65777b67d9e1_2614x1258.png 1272w, https://substackcdn.com/image/fetch/$s_!oTeX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56046e3d-2557-43ac-9611-65777b67d9e1_2614x1258.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oTeX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56046e3d-2557-43ac-9611-65777b67d9e1_2614x1258.png" width="724.4921875" height="348.81114247081047" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/56046e3d-2557-43ac-9611-65777b67d9e1_2614x1258.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:701,&quot;width&quot;:1456,&quot;resizeWidth&quot;:724.4921875,&quot;bytes&quot;:259316,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/176039893?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56046e3d-2557-43ac-9611-65777b67d9e1_2614x1258.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!oTeX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56046e3d-2557-43ac-9611-65777b67d9e1_2614x1258.png 424w, https://substackcdn.com/image/fetch/$s_!oTeX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56046e3d-2557-43ac-9611-65777b67d9e1_2614x1258.png 848w, https://substackcdn.com/image/fetch/$s_!oTeX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56046e3d-2557-43ac-9611-65777b67d9e1_2614x1258.png 1272w, https://substackcdn.com/image/fetch/$s_!oTeX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56046e3d-2557-43ac-9611-65777b67d9e1_2614x1258.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Brute-force approach to fetch tweets</strong></figcaption></figure></div><p>Let&#8217;s say the client pre-fetched 10,000 tweets and cached them locally. It would make scrolling seamless &#8212; but at a huge cost:</p><ol><li><p><strong>Slowness</strong> - Given 10K records, initial fetching would be extremely slow.</p></li><li><p><strong>Bandwidth</strong> - Fetching 10K tweets for millions of users would be redundant and waste the bandwidth.</p></li><li><p><strong>Memory</strong> - Storing 10K records would consume and drains app&#8217;s memory. Similarly, it would consume the server&#8217;s memory due to caching (as shown in the above diagram).</p></li></ol><p>As a result, it's not practical to retrieve all the tweets from the backend server. So, what&#8217;s the solution?</p><p>It&#8217;s simple. You break down the large dataset into small chunks, and fetch each chunk. This pagination approach would be fast, save bandwidth and also optimize memory.</p><p>Now, that you know what pagination is needed, let&#8217;s now dive deep into the different techniques.</p><div><hr></div><p><em>Ready to analyze complex system failures like a senior engineer? Learn the system design patterns that prevent outages and impress interviewers at top tech companies.</em></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TQeJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda4e934e-33d1-4a80-aedc-261842821783_310x162.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TQeJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda4e934e-33d1-4a80-aedc-261842821783_310x162.png 424w, https://substackcdn.com/image/fetch/$s_!TQeJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda4e934e-33d1-4a80-aedc-261842821783_310x162.png 848w, https://substackcdn.com/image/fetch/$s_!TQeJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda4e934e-33d1-4a80-aedc-261842821783_310x162.png 1272w, https://substackcdn.com/image/fetch/$s_!TQeJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda4e934e-33d1-4a80-aedc-261842821783_310x162.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TQeJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda4e934e-33d1-4a80-aedc-261842821783_310x162.png" width="310" height="162" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/da4e934e-33d1-4a80-aedc-261842821783_310x162.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:162,&quot;width&quot;:310,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2927,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/176039893?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda4e934e-33d1-4a80-aedc-261842821783_310x162.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!TQeJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda4e934e-33d1-4a80-aedc-261842821783_310x162.png 424w, https://substackcdn.com/image/fetch/$s_!TQeJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda4e934e-33d1-4a80-aedc-261842821783_310x162.png 848w, https://substackcdn.com/image/fetch/$s_!TQeJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda4e934e-33d1-4a80-aedc-261842821783_310x162.png 1272w, https://substackcdn.com/image/fetch/$s_!TQeJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda4e934e-33d1-4a80-aedc-261842821783_310x162.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><em>Look no further than Educative.io&#8217;s course on <a href="https://www.educative.io/courses/grokking-the-system-design-interview">Grokking the System Design Interview</a>. You can use this <a href="https://www.educative.io/unlimited?aff=BYJl">link</a> to get an additional 10% off.</em></p><div><hr></div><h2>Limit-Offset Pagination</h2><p>In this technique, the server divides the dataset into different pages with each page consisting of a set of records. The client sends the below attributes:</p><ol><li><p><strong>LIMIT</strong> - The number of records that the server must return.</p></li><li><p><strong>OFFSET</strong> - The page number or the number of initial records to skip.</p></li></ol><p>Let&#8217;s understand this with the example of Spotify. Spotify allows users to browse the different albums of an artist. </p><p>It exposes the following API endpoint along with the request body to retrieve the data:</p><pre><code><strong>POST</strong> - https://api-partner.spotify.com/pathfinder/v2/query
<strong>Request</strong> - 
{
  "operationName": "queryArtistDiscographyAlbums",
  &#8220;variables&#8221;: {
     "uri": "spotify:artist:12345"
     "offset": 1,
     "limit": 3
  }
}</code></pre><p>Here&#8217;s how the server processes the request:-</p><ol><li><p>Extracts the <em>limit</em> and <em>offset </em>fields from the request. </p></li><li><p>Constructs a database query by passing the value of <em>limit</em> and <em>offset</em>.</p></li><li><p>Executes the database query to skip the first <em>offset</em>  records and then fetch the count of records stated in the <em>limit</em>.</p></li></ol><p>The below diagram shows how the process works behind the scenes.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rGMQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4763550d-1639-4e68-9fb7-65758c370693_2774x758.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rGMQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4763550d-1639-4e68-9fb7-65758c370693_2774x758.png 424w, https://substackcdn.com/image/fetch/$s_!rGMQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4763550d-1639-4e68-9fb7-65758c370693_2774x758.png 848w, https://substackcdn.com/image/fetch/$s_!rGMQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4763550d-1639-4e68-9fb7-65758c370693_2774x758.png 1272w, https://substackcdn.com/image/fetch/$s_!rGMQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4763550d-1639-4e68-9fb7-65758c370693_2774x758.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rGMQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4763550d-1639-4e68-9fb7-65758c370693_2774x758.png" width="724.7421875" height="198.1094715831044" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4763550d-1639-4e68-9fb7-65758c370693_2774x758.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:398,&quot;width&quot;:1456,&quot;resizeWidth&quot;:724.7421875,&quot;bytes&quot;:246075,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/176039893?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4763550d-1639-4e68-9fb7-65758c370693_2774x758.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rGMQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4763550d-1639-4e68-9fb7-65758c370693_2774x758.png 424w, https://substackcdn.com/image/fetch/$s_!rGMQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4763550d-1639-4e68-9fb7-65758c370693_2774x758.png 848w, https://substackcdn.com/image/fetch/$s_!rGMQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4763550d-1639-4e68-9fb7-65758c370693_2774x758.png 1272w, https://substackcdn.com/image/fetch/$s_!rGMQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4763550d-1639-4e68-9fb7-65758c370693_2774x758.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption"><strong>LIMIT-OFFSET Pagination in action</strong></figcaption></figure></div><p>As you scroll down, the app would further sends one more request to fetch the next 3 albums (using <em>offset=4</em> and <em>limit=3</em>). </p><p>This technique offers the below advantages:-</p><ol><li><p><strong>Simplicity</strong> - It&#8217;s simple to understand and easy to implement.</p></li><li><p><strong>Easy navigation</strong> - Users can skip first N records (<em>offset</em>) and jump to the desired page of choice simplifying the navigation.</p></li></ol><p>While this technique works for Spotify&#8217;s use case of showing artist&#8217;s albums, do you think it would work for X&#8217;s infinite scroll? Take a moment to think before reading further.</p><p>With the Limit&#8211;Offset approach, the database reads all records and skips the first <em>N</em> records specified by the <em>offset</em>. This results in redundant computation making the process inefficient.</p><blockquote><p><strong>Food for thought</strong> - How would you decide the result size (i.e <em>limit</em>) for each page in Limit-Offset pagination? &#129300; (Leave your thoughts in the comments)</p></blockquote><p>The approach has the following limitations:-</p><ol><li><p><strong>Poor Scalability</strong> - It struggles with large datasets since it needs to read and skip large number of records.</p></li><li><p><strong>Subpar Performance</strong> - With large datasets, the latency to read the records increases thereby spiking the user&#8217;s page load times. This results in a poor user experience.</p></li><li><p><strong>Data Inconsistency</strong> - As new records are added/deleted, the users may view duplicate or missing items while scrolling through the pages. This makes the approach unstable.</p></li></ol><p>Now that you understand the Limit-Offset based pagination, let&#8217;s explore how Cursor-based pagination tackles its downsides.</p><h2>Cursor-based Pagination</h2><p>In this approach, the server returns records along with a cursor or a marker. The cursor is a string that points to the last record returned in the list.</p><p>In the subsequent requests, the client passes the cursor. The server then resumes reading from the first record after the cursor.</p><p>Let&#8217;s understand this in the context of X&#8217;s timeline. X exposes the following API for fetching the timeline of a user:-</p><pre><code><strong>POST</strong> - https://x.com/i/api/graphql/{<strong>userId</strong>}/HomeTimeline
<strong>Request </strong>- 
{
{
  &#8220;count&#8221;: 20,
  &#8220;<strong>cursor</strong>&#8221;: &#8220;DAABCgABG3hmIsG__0cKAAIbd4b1v1axJAgAAwAAAAIAAA&#8221;,
  &#8220;includePromotedContent&#8221;: true,
  &#8220;latestControlAvailable&#8221;: true,
  &#8220;withCommunity&#8221;: true,
  &#8220;seenTweetIds&#8221;: [
    &#8220;1979104903193923617&#8221;,
    &#8220;1979054161174942195&#8221;,
    &#8220;1979205840008597948&#8221;,
    &#8220;1979194565870616788&#8221;,
    &#8220;1979221342953382229&#8221;,
    &#8220;1979080720552427991&#8221;
  ]
}
} 
</code></pre><p>Here&#8217;s what happens when the client calls the <strong>HomeTimeline</strong> API:-</p><ol><li><p>During the initial load, the client wouldn&#8217;t set the cursor and the server would return 10-15 latest and top-ranked tweets along with the cursor.</p></li><li><p>Once the client scrolls and reaches the last tweet, it would send another request with the cursor (sent in the last response).</p></li><li><p>The server would then fetch the tweets (starting from 16th Tweet) and return it.</p></li></ol><p>This process would continue and the client would get infinite scrolling capability.</p><p>The diagram below illustrates the working of how X renders the timeline using Cursor-based pagination.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3CtP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2c7213f-6249-448c-a155-70c9e41872fb_2840x1698.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3CtP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2c7213f-6249-448c-a155-70c9e41872fb_2840x1698.png 424w, https://substackcdn.com/image/fetch/$s_!3CtP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2c7213f-6249-448c-a155-70c9e41872fb_2840x1698.png 848w, https://substackcdn.com/image/fetch/$s_!3CtP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2c7213f-6249-448c-a155-70c9e41872fb_2840x1698.png 1272w, https://substackcdn.com/image/fetch/$s_!3CtP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2c7213f-6249-448c-a155-70c9e41872fb_2840x1698.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3CtP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2c7213f-6249-448c-a155-70c9e41872fb_2840x1698.png" width="1456" height="871" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a2c7213f-6249-448c-a155-70c9e41872fb_2840x1698.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:871,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:429343,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/176039893?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2c7213f-6249-448c-a155-70c9e41872fb_2840x1698.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3CtP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2c7213f-6249-448c-a155-70c9e41872fb_2840x1698.png 424w, https://substackcdn.com/image/fetch/$s_!3CtP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2c7213f-6249-448c-a155-70c9e41872fb_2840x1698.png 848w, https://substackcdn.com/image/fetch/$s_!3CtP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2c7213f-6249-448c-a155-70c9e41872fb_2840x1698.png 1272w, https://substackcdn.com/image/fetch/$s_!3CtP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2c7213f-6249-448c-a155-70c9e41872fb_2840x1698.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Cursor-based pagination in action</strong></figcaption></figure></div><p>The cursor usually is a part of the indexed database attribute (like <strong>post_id</strong>) to speed the look-up. When the server receives the cursor, it performs a fast lookup and jumps to the record corresponding to the cursor. Subsequently, it reads the number of records specified in the <code>count</code>. </p><p>Here&#8217;s how the approach overcomes the downsides of Limit-Offset based approach:-</p><ol><li><p><strong>Scalability</strong> - The database directly navigates to the cursor instead of reading the first N records. This makes the process efficient and scales to a large number of records.</p></li><li><p><strong>High-performance</strong> - With index-based lookups, the latency is much lower resulting in excellent user experience.</p></li><li><p><strong>Stability</strong> - Since it fetches the records after the cursor, so addition or removal of records doesn&#8217;t affect the user experience. This makes the process stable compared to Limit-Offset based approach.  </p></li></ol><blockquote><p><strong>Food for thought</strong> - Do you think the cursors should have an expiry? What if the record at the cursor is deleted? &#129300; (Leave your thoughts in the comments)</p></blockquote><p>However, the approach is less flexible since the users can&#8217;t navigate and jump between the different pages.</p><p>So, you now know how Spotify and X handle pagination &#8212; but designing your own API isn&#8217;t just about picking a technique. Let&#8217;s look at some best practices that make pagination efficient, scalable, and easy to maintain.</p><h2>API Pagination Best Practices</h2><p>Here are some common best practices to follow:</p><ul><li><p><strong>Make the cursor opaque</strong> - The server must either encode or encrypt the cursor. This hides the implementation details and prevents clients from reconstructing the cursors.</p></li><li><p><strong>Validation on the page size</strong> - The server must validate <code>LIMIT</code>, <code>OFFSET</code>, <code>COUNT</code> set by the client. It must return appropriate response (<em>400 Bad Request</em>) in case of validation failures. This prevents the clients from misusing the server resources.</p></li><li><p><strong>Mandatory for all List operations</strong> - Use pagination for all list operations to handle large datasets efficiently.</p></li><li><p><strong>Caching</strong> - Caching prevents the load on the database and speeds up the reads. Wherever needed, caching can be used to improve the performance. However, cache invalidation also needs to be addressed in case the data changes frequently.</p></li><li><p><strong>Monitor pagination usage</strong> - Monitor the frequently requested page size, common cursors, % errors, etc. This helps you understand the client&#8217;s request patterns and tune the pagination parameters.</p></li></ul><h2>Conclusion</h2><p>API Pagination enables us to divide a large dataset into small chunks and return it to the clients. We learnt about two techniques - Limit-offset and Cursor-based Pagination. </p><p>Both the approaches have their pros/cons and we must use the approach that&#8217;s effective for the problem being solved.</p><p>The following table summarises the different use cases and the right pagination technique to use.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PQ_S!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c80aa68-9ff7-40b5-bfa1-165178a0b321_1948x1066.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PQ_S!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c80aa68-9ff7-40b5-bfa1-165178a0b321_1948x1066.png 424w, https://substackcdn.com/image/fetch/$s_!PQ_S!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c80aa68-9ff7-40b5-bfa1-165178a0b321_1948x1066.png 848w, https://substackcdn.com/image/fetch/$s_!PQ_S!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c80aa68-9ff7-40b5-bfa1-165178a0b321_1948x1066.png 1272w, https://substackcdn.com/image/fetch/$s_!PQ_S!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c80aa68-9ff7-40b5-bfa1-165178a0b321_1948x1066.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PQ_S!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c80aa68-9ff7-40b5-bfa1-165178a0b321_1948x1066.png" width="1456" height="797" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9c80aa68-9ff7-40b5-bfa1-165178a0b321_1948x1066.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:797,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:422691,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/176039893?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c80aa68-9ff7-40b5-bfa1-165178a0b321_1948x1066.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!PQ_S!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c80aa68-9ff7-40b5-bfa1-165178a0b321_1948x1066.png 424w, https://substackcdn.com/image/fetch/$s_!PQ_S!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c80aa68-9ff7-40b5-bfa1-165178a0b321_1948x1066.png 848w, https://substackcdn.com/image/fetch/$s_!PQ_S!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c80aa68-9ff7-40b5-bfa1-165178a0b321_1948x1066.png 1272w, https://substackcdn.com/image/fetch/$s_!PQ_S!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c80aa68-9ff7-40b5-bfa1-165178a0b321_1948x1066.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Use cases along with the right pagination strategy</strong></figcaption></figure></div><p>Now that you understand pagination, do you think Search engines like Google use LIMIT-OFFSET based pagination to show the results?&#129300;  Let me know your thoughts in the comments below. &#128071;</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/api-pagination-limit-offset-vs-cursor?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/p/api-pagination-limit-offset-vs-cursor?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p></p><p>Before you go:</p><ul><li><p>&#10084;&#65039; the story and follow the newsletter for more such articles</p></li><li><p>&#128276; Follow me: <a href="https://www.linkedin.com/in/animesh-gaitonde/">LinkedIn</a>, <a href="https://twitter.com/animesh3436">Twitter</a>, <a href="https://medium.com/@animeshgaitonde">Medium</a></p></li><li><p>Your support helps keep this newsletter free and fuels future content. Consider a small donation to show your appreciation here - <a href="https://www.paypal.com/ncp/payment/EUGP54EHQFDZC">Paypal Donate</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[Anatomy of Facebook's 2010 outage: Cache invalidation gone wrong]]></title><description><![CDATA[How a cache validation bug cascaded into Facebook's longest downtime]]></description><link>https://engineeringatscale.substack.com/p/facebook-2010-outage-cache-invalidation-analysis</link><guid isPermaLink="false">https://engineeringatscale.substack.com/p/facebook-2010-outage-cache-invalidation-analysis</guid><dc:creator><![CDATA[Animesh Gaitonde]]></dc:creator><pubDate>Tue, 02 Sep 2025 05:07:59 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!pS9R!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66df92cf-f237-4e53-9d6f-faf4962eb3d0_2478x1088.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In 2010, Facebook faced a <strong>2.5-hour</strong> outage that left millions unable to access the site.</p><p>A small misconfigured value led to a huge spike in the database load. While the mitigation was simple, it worsened the problem. The only way to solve the problem was to deliberately turn off the website traffic.   </p><p>But why turn off the traffic? Weren&#8217;t there any other options available?</p><p>This article will answer the above questions in detail. We will understand in simple words the root cause of the issue. The article will also recommend strategies to avoid such massive outages in the future.</p><p>With that, let&#8217;s begin with background of Facebook&#8217;s architecture.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/subscribe?"><span>Subscribe now</span></a></p><h2>Facebook&#8217;s architecture</h2><p>By 2010, Facebook had evolved beyond simple social sharing, adding chat, ads, photo support, and more.</p><p>With thousands of engineers, the software architecture was complex and comprised of several services. But at its core, it was a simple client-server-database model like any other website.</p><p>For performance and scalability, they used caching heavily and majority of the requests were served through the cache. The services fetched the data from the database in case of cache misses.</p><p>The following diagram illustrates the high-level architecture:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XIsv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703e519-10ca-4ef0-a3f3-f13ff59ab82d_2718x764.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XIsv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703e519-10ca-4ef0-a3f3-f13ff59ab82d_2718x764.png 424w, https://substackcdn.com/image/fetch/$s_!XIsv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703e519-10ca-4ef0-a3f3-f13ff59ab82d_2718x764.png 848w, https://substackcdn.com/image/fetch/$s_!XIsv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703e519-10ca-4ef0-a3f3-f13ff59ab82d_2718x764.png 1272w, https://substackcdn.com/image/fetch/$s_!XIsv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703e519-10ca-4ef0-a3f3-f13ff59ab82d_2718x764.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XIsv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703e519-10ca-4ef0-a3f3-f13ff59ab82d_2718x764.png" width="1456" height="409" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1703e519-10ca-4ef0-a3f3-f13ff59ab82d_2718x764.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:409,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:181102,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/172445644?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703e519-10ca-4ef0-a3f3-f13ff59ab82d_2718x764.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XIsv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703e519-10ca-4ef0-a3f3-f13ff59ab82d_2718x764.png 424w, https://substackcdn.com/image/fetch/$s_!XIsv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703e519-10ca-4ef0-a3f3-f13ff59ab82d_2718x764.png 848w, https://substackcdn.com/image/fetch/$s_!XIsv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703e519-10ca-4ef0-a3f3-f13ff59ab82d_2718x764.png 1272w, https://substackcdn.com/image/fetch/$s_!XIsv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703e519-10ca-4ef0-a3f3-f13ff59ab82d_2718x764.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Facebook&#8217;s high-level client-server architecture</strong></figcaption></figure></div><p><strong>Disclaimer</strong>: <em>The above diagram is only for representative purpose and doesn&#8217;t reflect the actual state of Facebook&#8217;s production architecture</em>.</p><p>One of the caching layer served configuration values. The configuration values often changed due to deployments or developer changes. </p><p>So, it was essential to replace the values periodically. They devised an automated mechanism to replace the cache values.</p><p>Let&#8217;s now understand this automated mechanism in detail.</p><div><hr></div><p><em>Ready to analyze complex system failures like a senior engineer? Learn the system design patterns that prevent outages and impress interviewers at top tech companies.</em></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OPEA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a4c3030-e76a-425f-be6a-9d964c19e635_310x162.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OPEA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a4c3030-e76a-425f-be6a-9d964c19e635_310x162.png 424w, https://substackcdn.com/image/fetch/$s_!OPEA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a4c3030-e76a-425f-be6a-9d964c19e635_310x162.png 848w, https://substackcdn.com/image/fetch/$s_!OPEA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a4c3030-e76a-425f-be6a-9d964c19e635_310x162.png 1272w, https://substackcdn.com/image/fetch/$s_!OPEA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a4c3030-e76a-425f-be6a-9d964c19e635_310x162.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OPEA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a4c3030-e76a-425f-be6a-9d964c19e635_310x162.png" width="310" height="162" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7a4c3030-e76a-425f-be6a-9d964c19e635_310x162.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:162,&quot;width&quot;:310,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2927,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/172445644?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a4c3030-e76a-425f-be6a-9d964c19e635_310x162.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!OPEA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a4c3030-e76a-425f-be6a-9d964c19e635_310x162.png 424w, https://substackcdn.com/image/fetch/$s_!OPEA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a4c3030-e76a-425f-be6a-9d964c19e635_310x162.png 848w, https://substackcdn.com/image/fetch/$s_!OPEA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a4c3030-e76a-425f-be6a-9d964c19e635_310x162.png 1272w, https://substackcdn.com/image/fetch/$s_!OPEA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a4c3030-e76a-425f-be6a-9d964c19e635_310x162.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><em>Look no further than Educative.io&#8217;s course on <a href="https://www.educative.io/courses/grokking-the-system-design-interview">Grokking the System Design Interview</a>. You can use this <a href="https://www.educative.io/unlimited?aff=BYJl">link</a> to get an additional 10% off.</em></p><div><hr></div><h2>Automated verification</h2><p>They created an offline verification service that periodically:-</p><ol><li><p>Fetched values from the cache.</p></li><li><p>Verified the configuration values and checked for the expiry, correctness, database consistency etc.</p></li><li><p>In case of validation failures, it fetched the data from the database and replaced the cache value.</p></li></ol><p>The following diagram illustrates how the automated verification system worked.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!raUd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8afe3481-6226-4214-bb77-45b0f8993f88_2080x912.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!raUd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8afe3481-6226-4214-bb77-45b0f8993f88_2080x912.png 424w, https://substackcdn.com/image/fetch/$s_!raUd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8afe3481-6226-4214-bb77-45b0f8993f88_2080x912.png 848w, https://substackcdn.com/image/fetch/$s_!raUd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8afe3481-6226-4214-bb77-45b0f8993f88_2080x912.png 1272w, https://substackcdn.com/image/fetch/$s_!raUd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8afe3481-6226-4214-bb77-45b0f8993f88_2080x912.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!raUd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8afe3481-6226-4214-bb77-45b0f8993f88_2080x912.png" width="1456" height="638" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8afe3481-6226-4214-bb77-45b0f8993f88_2080x912.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:638,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:210556,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/172445644?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8afe3481-6226-4214-bb77-45b0f8993f88_2080x912.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!raUd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8afe3481-6226-4214-bb77-45b0f8993f88_2080x912.png 424w, https://substackcdn.com/image/fetch/$s_!raUd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8afe3481-6226-4214-bb77-45b0f8993f88_2080x912.png 848w, https://substackcdn.com/image/fetch/$s_!raUd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8afe3481-6226-4214-bb77-45b0f8993f88_2080x912.png 1272w, https://substackcdn.com/image/fetch/$s_!raUd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8afe3481-6226-4214-bb77-45b0f8993f88_2080x912.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Automated verification system</strong></figcaption></figure></div><p>This mechanism prevented simultaneous database calls, avoiding bottlenecks and keeping the system smooth.</p><p>However, if the service couldn&#8217;t fetch the value from the cache, it got the value from the database and replaced the cache value. This ensured safe fallback mechanism.</p><p>The system worked seamlessly and handled traffic at Facebook&#8217;s scale until the day of the outage.</p><p>Let&#8217;s now learn what exactly happened on the day of the outage</p><h2>Outage</h2><p>One of the teams changed the configuration value in the database. However, the new value was invalid (For eg:- malformed json or incorrect value).</p><p>While they had designed the system to robustly handle invalid cache values, it wasn&#8217;t built to handle invalid database values. So, here&#8217;s what happened later:-</p><ol><li><p>Automated verification detected inconsistency and fetched the database value.</p></li><li><p>Since the fetched value was invalid, it deleted the cache entry and replaced it.</p></li><li><p>When the services fetched the cached value, it resulted in a cache miss. Hence, they tried fetching the value from the database.</p></li><li><p>The database load spiked since multiple services simultaneously performed database calls.</p></li></ol><p>The following diagram summarises the outage:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pS9R!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66df92cf-f237-4e53-9d6f-faf4962eb3d0_2478x1088.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pS9R!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66df92cf-f237-4e53-9d6f-faf4962eb3d0_2478x1088.png 424w, https://substackcdn.com/image/fetch/$s_!pS9R!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66df92cf-f237-4e53-9d6f-faf4962eb3d0_2478x1088.png 848w, https://substackcdn.com/image/fetch/$s_!pS9R!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66df92cf-f237-4e53-9d6f-faf4962eb3d0_2478x1088.png 1272w, https://substackcdn.com/image/fetch/$s_!pS9R!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66df92cf-f237-4e53-9d6f-faf4962eb3d0_2478x1088.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pS9R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66df92cf-f237-4e53-9d6f-faf4962eb3d0_2478x1088.png" width="1456" height="639" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/66df92cf-f237-4e53-9d6f-faf4962eb3d0_2478x1088.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:639,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:283159,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/172445644?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66df92cf-f237-4e53-9d6f-faf4962eb3d0_2478x1088.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!pS9R!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66df92cf-f237-4e53-9d6f-faf4962eb3d0_2478x1088.png 424w, https://substackcdn.com/image/fetch/$s_!pS9R!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66df92cf-f237-4e53-9d6f-faf4962eb3d0_2478x1088.png 848w, https://substackcdn.com/image/fetch/$s_!pS9R!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66df92cf-f237-4e53-9d6f-faf4962eb3d0_2478x1088.png 1272w, https://substackcdn.com/image/fetch/$s_!pS9R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66df92cf-f237-4e53-9d6f-faf4962eb3d0_2478x1088.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Facebook&#8217;s outage</strong></figcaption></figure></div><h2>Outage mitigation</h2><p>Engineers first attempted a quick solution&#8212;<strong>correcting the database value</strong>.</p><p>But did this simple fix work? The answer is <strong>No</strong>. Let&#8217;s understand why.</p><p>Once the database value was fixed, here&#8217;s what happened:-</p><ol><li><p>It was already handling a huge load.</p></li><li><p>Few services fetched the correct value and fixed the cache.</p></li><li><p>However, due to the load, many services still couldn&#8217;t fetch the database value. They retried multiple times and it further increased the load.</p></li><li><p>The service interpreted database call failures as invalid values. As a result, they deleted the cache values again and ended up calling the database.</p></li></ol><p>The below diagram illustrates the vicious cycle that escalated the issue:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sNKh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F731f7d67-acbb-4e08-94b7-561385aabd48_2394x950.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sNKh!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F731f7d67-acbb-4e08-94b7-561385aabd48_2394x950.png 424w, https://substackcdn.com/image/fetch/$s_!sNKh!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F731f7d67-acbb-4e08-94b7-561385aabd48_2394x950.png 848w, https://substackcdn.com/image/fetch/$s_!sNKh!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F731f7d67-acbb-4e08-94b7-561385aabd48_2394x950.png 1272w, https://substackcdn.com/image/fetch/$s_!sNKh!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F731f7d67-acbb-4e08-94b7-561385aabd48_2394x950.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sNKh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F731f7d67-acbb-4e08-94b7-561385aabd48_2394x950.png" width="1456" height="578" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/731f7d67-acbb-4e08-94b7-561385aabd48_2394x950.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:578,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:231994,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/172445644?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F731f7d67-acbb-4e08-94b7-561385aabd48_2394x950.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!sNKh!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F731f7d67-acbb-4e08-94b7-561385aabd48_2394x950.png 424w, https://substackcdn.com/image/fetch/$s_!sNKh!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F731f7d67-acbb-4e08-94b7-561385aabd48_2394x950.png 848w, https://substackcdn.com/image/fetch/$s_!sNKh!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F731f7d67-acbb-4e08-94b7-561385aabd48_2394x950.png 1272w, https://substackcdn.com/image/fetch/$s_!sNKh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F731f7d67-acbb-4e08-94b7-561385aabd48_2394x950.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Issue escalation after mitigation</strong></figcaption></figure></div><p>The system was collapsing onto itself and couldn&#8217;t gracefully recover. As a result, the only solution was to turn off the user traffic to the website leading to a downtime of more than <strong>2.5 hours</strong>.</p><p>Massive outages of this scale are not caused due to a single component. Root cause analysis reveals gaps in the functioning of several components.</p><p>We will now dissect the root cause behind Facebook&#8217;s outage.</p><h2>Root cause analysis</h2><h3>Automated verification system</h3><p>The system didn&#8217;t differentiate between cached value and the database value. It deleted the cache entry due to invalid database value triggering a stream of database queries.</p><h3>Service error handling</h3><p>The service interpreted database timeouts and other errors as invalid values. As a result, it also deleted the valid entries from the cache further escalating the issue.</p><h3>Lack of rate-limiting</h3><p>There was no throttling mechanism to prevent a surge of database queries. This eventually led to the vicious cycle and the system couldn&#8217;t self-heal itself.</p><p>Now, that you understand the root cause of the outage, let&#8217;s understand mechanisms that could have prevented it.</p><h2>Preventive measures</h2><p>Though this outage happened <strong>15 years</strong> ago, its lessons remain relevant&#8212;any tech company could face a similar risk. </p><p>Following are some mechanisms to prevent such outages:-</p><ol><li><p><strong>Rate limiting</strong> - Limit the database calls to protect the database from a surge. This prevents database from being a bottleneck and reduces the blast radius of the issue.</p></li><li><p><strong>Retry mechanisms and jitter</strong> - Adding random delays, increasing delays after failures, etc help to smooth the overall load.</p></li><li><p><strong>Error handling mechanisms</strong> - Differentiating system issues such as timeouts differently and not mixing business concerns (treating it as invalid value) result in robust error handling.</p></li><li><p><strong>Configuration design</strong> - Instead of validating config values after reading, validation at the write time prevents such issues.</p></li><li><p><strong>Kill switches</strong> - Kill switches give more control to the engineers while operating a system. They are useful in handling worst case scenarios and reducing the outage&#8217;s overall impact.</p></li></ol><h2>Conclusion</h2><p>Facebook&#8217;s outage offers valuable lessons for the industry even today. In today&#8217;s fast paced world, a downtime of few minutes implies huge losses to the business.</p><p>While outages can&#8217;t be eliminated completely, their duration and customer impact can be reduced through preventive measures described in this article.</p><p>Adopting preventive mechanisms and best practices help:-</p><ol><li><p>Improve developer productivity.</p></li><li><p>Keep the customers happy.</p></li><li><p>Reduce the business impact due to future outages.</p></li></ol><p>What is the most interesting outage that you have worked on so far? What did you learn from it? Leave your thoughts in the comments below.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/facebook-2010-outage-cache-invalidation-analysis?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading Engineering At Scale! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/facebook-2010-outage-cache-invalidation-analysis?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/p/facebook-2010-outage-cache-invalidation-analysis?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p>Before you go:</p><ul><li><p>&#10084;&#65039; the story and follow the newsletter for more such articles</p></li><li><p>&#128276; Follow me: <a href="https://www.linkedin.com/in/animesh-gaitonde/">LinkedIn</a>, <a href="https://twitter.com/animesh3436">Twitter</a>, <a href="https://medium.com/@animeshgaitonde">Medium</a></p></li><li><p>Your support helps keep this newsletter free and fuels future content. Consider a small donation to show your appreciation here - <a href="https://www.paypal.com/ncp/payment/EUGP54EHQFDZC">Paypal Donate</a></p></li></ul><p><strong>Disclaimer</strong>: <em>The details in this post have been derived from the official blog shared online by the Facebook Engineering Team. Kudos to the Facebook Engineering Team for mitigating the outage and bringing up the website within a short duration. The links to the original blog post is included in the next section. We&#8217;ve attempted to explain the outage in simple words and the key lessons for the engineering audience. In case there are any inaccuracies, please highlight them in the comment section below and we will do our best to rectify the same.</em></p><h2>Reference</h2><ol><li><p><a href="https://engineering.fb.com/2010/09/23/uncategorized/more-details-on-today-s-outage/">Facebook&#8217;s 2010 outage</a></p></li></ol>]]></content:encoded></item><item><title><![CDATA[Library vs Service: Lessons from Netflix's Multi-Year Migration]]></title><description><![CDATA[In-depth framework to choose between a library and a service]]></description><link>https://engineeringatscale.substack.com/p/library-vs-service-architecture-netflix-case-study</link><guid isPermaLink="false">https://engineeringatscale.substack.com/p/library-vs-service-architecture-netflix-case-study</guid><dc:creator><![CDATA[Animesh Gaitonde]]></dc:creator><pubDate>Thu, 29 May 2025 16:05:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc542e8a9-0886-484d-8945-68ebc94f1425_1738x1342.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Should I choose a library or build a service? This is a question that puzzles many software engineers. A wrong decision can lead to months or even years of rewrites and increased costs.</p><p>Software teams constantly change, and a wrong decision can impact future team members&#8212;especially those with the least context. I have worked on both sides of the table &#8212; building a service by deprecating an old library and replacing a service with a lightweight library.</p><p>I worked at a mid-sized startup where microservices were a golden hammer. They built microservices for the smallest of the functionalities. The loosely coupled architecture did create a mess. I remember a colleague once joked, &#8220;They&#8217;ll probably create a service just for Java&#8217;s <code>toString()</code> function!&#8221; &#128513;</p><p>Finally, the company took a call to combine the related functionalities in a library. The rewrite frustrated the developers who always pondered - &#8220;<em>Why didn&#8217;t the previous team think of this?</em>&#8220; &#129300;</p><p>On the other hand, while working in one of the big tech teams, we ran into scalability challenges and bottlenecks with a legacy library. Our team members blamed the old library owners for the poor design.</p><p>One common pattern in both the anecdotes was - The old team members always became a scapegoat. &#128513;</p><p>How can we prevent this? How do we take better decision as software developers? How do we build software that outlives the team that built it?</p><p>This article will answer all of the above questions. It will walkthrough a case study of how Netflix substituted a library with a service. You will learn how to take critical decisions and future proof your tech choices.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/subscribe?"><span>Subscribe now</span></a></p><p>With that, let&#8217;s begin with the case study.</p><h2>Netflix Case Study - Platform for managing Membership plans</h2><p>Today, Netflix has presence in 190 countries and has a 300 million subscriber base. It offers a variety of plans tailored to devices, streaming quality, regions, and more.</p><p>But back in 2010, it only had presence in the US with just 12 million subscribers. It offered only three plans - Basic, Premium and Standard to the customers.</p><p>Let&#8217;s now understand the software behind the membership plans.</p><div><hr></div><p>Do you want to level-up your skills as a software developer? Do you aspire to crack interviews at top-tech companies and land a job? </p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gB21!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6ff1787-4694-4e44-9b32-03f28a730b63_310x162.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gB21!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6ff1787-4694-4e44-9b32-03f28a730b63_310x162.png 424w, https://substackcdn.com/image/fetch/$s_!gB21!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6ff1787-4694-4e44-9b32-03f28a730b63_310x162.png 848w, https://substackcdn.com/image/fetch/$s_!gB21!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6ff1787-4694-4e44-9b32-03f28a730b63_310x162.png 1272w, https://substackcdn.com/image/fetch/$s_!gB21!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6ff1787-4694-4e44-9b32-03f28a730b63_310x162.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gB21!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6ff1787-4694-4e44-9b32-03f28a730b63_310x162.png" width="310" height="162" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b6ff1787-4694-4e44-9b32-03f28a730b63_310x162.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:162,&quot;width&quot;:310,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2927,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/164416813?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6ff1787-4694-4e44-9b32-03f28a730b63_310x162.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!gB21!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6ff1787-4694-4e44-9b32-03f28a730b63_310x162.png 424w, https://substackcdn.com/image/fetch/$s_!gB21!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6ff1787-4694-4e44-9b32-03f28a730b63_310x162.png 848w, https://substackcdn.com/image/fetch/$s_!gB21!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6ff1787-4694-4e44-9b32-03f28a730b63_310x162.png 1272w, https://substackcdn.com/image/fetch/$s_!gB21!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6ff1787-4694-4e44-9b32-03f28a730b63_310x162.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>If yes, then <a href="https://www.educative.io/">Educative.io</a> is the best platform with handcrafted courses for developers and personalized by AI. Get additional 10% off by using this <a href="https://www.educative.io/unlimited?aff=BYJl">link</a>.</p><div><hr></div><h3>Membership plans library</h3><p>In 2010, Netflix had a monolith (<em>Membership service</em>) that was responsible for managing and tracking the user subscription plans. For modularity, they decided to build a library that would:</p><ol><li><p>Handle the business logic for evaluating the plans.</p></li><li><p>Store the plan metadata in various configuration files.</p></li></ol><p>The below diagram shows the basic data model for the different membership plans:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9FeN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21d48745-1e4a-4a6f-ad51-15f9a727d36c_1718x442.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9FeN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21d48745-1e4a-4a6f-ad51-15f9a727d36c_1718x442.png 424w, https://substackcdn.com/image/fetch/$s_!9FeN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21d48745-1e4a-4a6f-ad51-15f9a727d36c_1718x442.png 848w, https://substackcdn.com/image/fetch/$s_!9FeN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21d48745-1e4a-4a6f-ad51-15f9a727d36c_1718x442.png 1272w, https://substackcdn.com/image/fetch/$s_!9FeN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21d48745-1e4a-4a6f-ad51-15f9a727d36c_1718x442.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9FeN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21d48745-1e4a-4a6f-ad51-15f9a727d36c_1718x442.png" width="1456" height="375" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/21d48745-1e4a-4a6f-ad51-15f9a727d36c_1718x442.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:375,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:157223,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/164416813?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21d48745-1e4a-4a6f-ad51-15f9a727d36c_1718x442.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9FeN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21d48745-1e4a-4a6f-ad51-15f9a727d36c_1718x442.png 424w, https://substackcdn.com/image/fetch/$s_!9FeN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21d48745-1e4a-4a6f-ad51-15f9a727d36c_1718x442.png 848w, https://substackcdn.com/image/fetch/$s_!9FeN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21d48745-1e4a-4a6f-ad51-15f9a727d36c_1718x442.png 1272w, https://substackcdn.com/image/fetch/$s_!9FeN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21d48745-1e4a-4a6f-ad51-15f9a727d36c_1718x442.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Membership plan data models</strong></figcaption></figure></div><p>Stakeholders could easily modify the plans, release and deploy the library. The below diagram shows how the service read the plans from the library.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LPuw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6975205-4b0b-4874-a1fb-b6ef4f9b53fb_1984x732.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LPuw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6975205-4b0b-4874-a1fb-b6ef4f9b53fb_1984x732.png 424w, https://substackcdn.com/image/fetch/$s_!LPuw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6975205-4b0b-4874-a1fb-b6ef4f9b53fb_1984x732.png 848w, https://substackcdn.com/image/fetch/$s_!LPuw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6975205-4b0b-4874-a1fb-b6ef4f9b53fb_1984x732.png 1272w, https://substackcdn.com/image/fetch/$s_!LPuw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6975205-4b0b-4874-a1fb-b6ef4f9b53fb_1984x732.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LPuw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6975205-4b0b-4874-a1fb-b6ef4f9b53fb_1984x732.png" width="1456" height="537" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c6975205-4b0b-4874-a1fb-b6ef4f9b53fb_1984x732.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:537,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:121678,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/164416813?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6975205-4b0b-4874-a1fb-b6ef4f9b53fb_1984x732.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!LPuw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6975205-4b0b-4874-a1fb-b6ef4f9b53fb_1984x732.png 424w, https://substackcdn.com/image/fetch/$s_!LPuw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6975205-4b0b-4874-a1fb-b6ef4f9b53fb_1984x732.png 848w, https://substackcdn.com/image/fetch/$s_!LPuw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6975205-4b0b-4874-a1fb-b6ef4f9b53fb_1984x732.png 1272w, https://substackcdn.com/image/fetch/$s_!LPuw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6975205-4b0b-4874-a1fb-b6ef4f9b53fb_1984x732.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Membership service reading from the library</strong></figcaption></figure></div><p>Everything was simple until the company&#8217;s global expansion in the mid-2010.</p><h3>Global expansion</h3><p>It first launched in Canada followed by Latin America, United Kingdom, Australia, India, etc. With the expansion, there was a growth in the number of subscribers.</p><p>For scalability, the tech teams decided to split the monolith into multiple services. Each service served a different purpose such as <strong>Playback</strong>, <strong>Billing</strong>, <strong>Edge</strong> <strong>services</strong>, etc.</p><p>Its initial strategy of offering three basic plans wasn&#8217;t sufficient for the new regions. They needed better strategies to acquire customers.</p><p>The subscription plans grew in the following dimensions:-</p><ol><li><p><strong>Devices</strong> - Plans catered for specific devices such as Mobile, TV, etc.</p></li><li><p><strong>Quality of service</strong> - Different plans based on the resolution and audio quality.</p></li><li><p><strong>Regions</strong> - People&#8217;s buying choices led to unique plans for various regions.</p></li></ol><p>In addition, product team wanted to perform A/B tests on different subscription plans and evaluate the impact.</p><p>As the company grew, the original light-weight library now had complex rules and plan metadata. With the proliferation of microservices, the library was imported by every other service. Although the company grew rapidly, the library couldn&#8217;t keep pace with it. </p><p>The below diagram presents the membership plans data model after Netflix&#8217;s geographical expansion.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HrMC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec30956-1d36-4a1b-afa9-d6cbaaf1bffb_1936x1086.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HrMC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec30956-1d36-4a1b-afa9-d6cbaaf1bffb_1936x1086.png 424w, https://substackcdn.com/image/fetch/$s_!HrMC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec30956-1d36-4a1b-afa9-d6cbaaf1bffb_1936x1086.png 848w, https://substackcdn.com/image/fetch/$s_!HrMC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec30956-1d36-4a1b-afa9-d6cbaaf1bffb_1936x1086.png 1272w, https://substackcdn.com/image/fetch/$s_!HrMC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec30956-1d36-4a1b-afa9-d6cbaaf1bffb_1936x1086.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HrMC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec30956-1d36-4a1b-afa9-d6cbaaf1bffb_1936x1086.png" width="1456" height="817" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8ec30956-1d36-4a1b-afa9-d6cbaaf1bffb_1936x1086.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:817,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:249130,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/164416813?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec30956-1d36-4a1b-afa9-d6cbaaf1bffb_1936x1086.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!HrMC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec30956-1d36-4a1b-afa9-d6cbaaf1bffb_1936x1086.png 424w, https://substackcdn.com/image/fetch/$s_!HrMC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec30956-1d36-4a1b-afa9-d6cbaaf1bffb_1936x1086.png 848w, https://substackcdn.com/image/fetch/$s_!HrMC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec30956-1d36-4a1b-afa9-d6cbaaf1bffb_1936x1086.png 1272w, https://substackcdn.com/image/fetch/$s_!HrMC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ec30956-1d36-4a1b-afa9-d6cbaaf1bffb_1936x1086.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Membership plan data model after Netflix&#8217;s expansion</strong></figcaption></figure></div><p>Let&#8217;s now dive into the challenges that the team faced while managing the library.</p><h3> Library challenges</h3><p>The library owners faced the following challenges:-</p><ol><li><p><strong>Operational complexity</strong> - Plan changes required changes in metadata config and business logic. The development and testing took several days. Additionally, even simple changes took days to reach production.</p></li><li><p><strong>Reliability</strong> - Pricing consistency was critical for Netflix across devices and pages showing the subscription plans. With the library, two or more services could rely on different versions resulting in inconsistency in the shown plans.</p></li><li><p><strong>Manageability</strong> - It became difficult to manage thousands of different plans along with custom business logic.</p></li></ol><blockquote><p>One of the biggest challenges of using a library is maintaining version consistency across services. Netflix team also wrote a web crawler at scale for version correctness. </p></blockquote><p>The below diagram shows how different services and their instances use different library versions.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ylW7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2201cf22-9cfe-4085-8ebb-e76c2cae639f_1576x1070.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ylW7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2201cf22-9cfe-4085-8ebb-e76c2cae639f_1576x1070.png 424w, https://substackcdn.com/image/fetch/$s_!ylW7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2201cf22-9cfe-4085-8ebb-e76c2cae639f_1576x1070.png 848w, https://substackcdn.com/image/fetch/$s_!ylW7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2201cf22-9cfe-4085-8ebb-e76c2cae639f_1576x1070.png 1272w, https://substackcdn.com/image/fetch/$s_!ylW7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2201cf22-9cfe-4085-8ebb-e76c2cae639f_1576x1070.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ylW7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2201cf22-9cfe-4085-8ebb-e76c2cae639f_1576x1070.png" width="1456" height="989" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2201cf22-9cfe-4085-8ebb-e76c2cae639f_1576x1070.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:989,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:189870,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/164416813?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2201cf22-9cfe-4085-8ebb-e76c2cae639f_1576x1070.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!ylW7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2201cf22-9cfe-4085-8ebb-e76c2cae639f_1576x1070.png 424w, https://substackcdn.com/image/fetch/$s_!ylW7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2201cf22-9cfe-4085-8ebb-e76c2cae639f_1576x1070.png 848w, https://substackcdn.com/image/fetch/$s_!ylW7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2201cf22-9cfe-4085-8ebb-e76c2cae639f_1576x1070.png 1272w, https://substackcdn.com/image/fetch/$s_!ylW7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2201cf22-9cfe-4085-8ebb-e76c2cae639f_1576x1070.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Services and their instances running different library versions</strong></figcaption></figure></div><p>The tight-coupling due to the library resulted in less flexibility, increased blast radius, and long dev cycles.</p><p>We will now understand how Netflix tackled these challenges.</p><h3>Library deprecation</h3><p>To solve the pain-points, the team decided to centralize the logic in a service. The primary goal of the platform was to provide an API interface that abstracted the business rules and data.</p><p>Here&#8217;s how the library got refactored into a platform:-</p><ul><li><p><strong>Business rules</strong> - A rule engine was developed to manage the complex rules. Rules were written in the form of expressions instead of code.</p></li><li><p><strong>Persistence</strong> - The data was migrated from metadata configurations to a database layer for persistence. The database acted as a single source of truth for all the plans.</p></li><li><p><strong>Self-service UI</strong> - This layer enabled stakeholders to easily configure new plans, create and validate rules. This eliminated the need to make library code changes that took weeks of efforts.</p></li><li><p><strong>Service layer</strong> - It provided APIs different services to fetch the plans based on the context. For eg:- A service could pass region, device, userId in the context and it could return the plans after executing the business rules.</p></li></ul><p>The below diagram shows how rules were written in the library and then transformed into rule engine expressions.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!I5Yr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7996781d-74ca-4cd6-b6a5-ada84d60e354_2562x1084.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!I5Yr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7996781d-74ca-4cd6-b6a5-ada84d60e354_2562x1084.png 424w, https://substackcdn.com/image/fetch/$s_!I5Yr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7996781d-74ca-4cd6-b6a5-ada84d60e354_2562x1084.png 848w, https://substackcdn.com/image/fetch/$s_!I5Yr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7996781d-74ca-4cd6-b6a5-ada84d60e354_2562x1084.png 1272w, https://substackcdn.com/image/fetch/$s_!I5Yr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7996781d-74ca-4cd6-b6a5-ada84d60e354_2562x1084.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!I5Yr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7996781d-74ca-4cd6-b6a5-ada84d60e354_2562x1084.png" width="1456" height="616" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7996781d-74ca-4cd6-b6a5-ada84d60e354_2562x1084.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:616,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:300636,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/164416813?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7996781d-74ca-4cd6-b6a5-ada84d60e354_2562x1084.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!I5Yr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7996781d-74ca-4cd6-b6a5-ada84d60e354_2562x1084.png 424w, https://substackcdn.com/image/fetch/$s_!I5Yr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7996781d-74ca-4cd6-b6a5-ada84d60e354_2562x1084.png 848w, https://substackcdn.com/image/fetch/$s_!I5Yr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7996781d-74ca-4cd6-b6a5-ada84d60e354_2562x1084.png 1272w, https://substackcdn.com/image/fetch/$s_!I5Yr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7996781d-74ca-4cd6-b6a5-ada84d60e354_2562x1084.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Transformation of Library code into Rule engine expressions</strong></figcaption></figure></div><p>It can be seen from above, how easy it is to define the rules in the form of expressions than writing business logic every time a plan changes.</p><p>The following diagram shows the high-level architecture of the platform.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nijO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc542e8a9-0886-484d-8945-68ebc94f1425_1738x1342.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nijO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc542e8a9-0886-484d-8945-68ebc94f1425_1738x1342.png 424w, https://substackcdn.com/image/fetch/$s_!nijO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc542e8a9-0886-484d-8945-68ebc94f1425_1738x1342.png 848w, https://substackcdn.com/image/fetch/$s_!nijO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc542e8a9-0886-484d-8945-68ebc94f1425_1738x1342.png 1272w, https://substackcdn.com/image/fetch/$s_!nijO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc542e8a9-0886-484d-8945-68ebc94f1425_1738x1342.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nijO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc542e8a9-0886-484d-8945-68ebc94f1425_1738x1342.png" width="1456" height="1124" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c542e8a9-0886-484d-8945-68ebc94f1425_1738x1342.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1124,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:213816,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/164416813?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc542e8a9-0886-484d-8945-68ebc94f1425_1738x1342.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!nijO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc542e8a9-0886-484d-8945-68ebc94f1425_1738x1342.png 424w, https://substackcdn.com/image/fetch/$s_!nijO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc542e8a9-0886-484d-8945-68ebc94f1425_1738x1342.png 848w, https://substackcdn.com/image/fetch/$s_!nijO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc542e8a9-0886-484d-8945-68ebc94f1425_1738x1342.png 1272w, https://substackcdn.com/image/fetch/$s_!nijO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc542e8a9-0886-484d-8945-68ebc94f1425_1738x1342.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Membership plans platform</strong></figcaption></figure></div><p>The re-architecture was a multi-year effort and involved more than 20 different engineering teams. The new architecture could now scale and keep up with Netflix&#8217;s expansion in different regions.</p><p>While the effort was worth it, do you think Netflix made a wrong choice in developing a library first? &#129300; <br></p><h3>Was Netflix wrong?</h3><p>Now, that you understand Netflix&#8217;s current and old architecture, let&#8217;s assess whether Netflix made a wrong choice in 2010s.</p><p>Had Netflix built a Plan service platform instead of the library, it would have supported the company&#8217;s rapid growth. It would have given more flexibility to the product teams to experiment and iterate fast.</p><p>But what would have happened had Netflix not grown the way it grew in 2010s? &#129300;</p><p>Assuming that Netflix existed only in US with no business growth, the membership platform would have:-</p><ol><li><p>Increased the infrastructure costs.</p></li><li><p>Been an overkill for a simple use case.</p></li><li><p>Resulted in most of the functionality remaining unused.</p></li></ol><p>So, Netflix wasn&#8217;t wrong in choosing a library in the first place. But they didn&#8217;t tackle the library&#8217;s tech debt at the right moment which resulted in multi-year re-architecture.</p><blockquote><p>It&#8217;s very easy to criticize the previous software teams for the current challenges. But, we must respect the past engineering decisions assuming they were taken rationally with certain assumptions.</p></blockquote><p>Netflix could have avoided the multi-year migration effort by:-</p><ol><li><p>Identifying the issues with the library proactively.</p></li><li><p>Prioritising the tech debt and reducing operational burden.</p></li><li><p>Future-proofing the tech choice of library by easily evolving it into a service.</p></li></ol><p>A better approach would have been to understand the library pain-points after expanding in two or three regions. A futuristic view of growing requirements would have helped them tackle the problem effectively.</p><h2>Library vs Service</h2><p>While deciding between a library and a service, you can use the following table to weigh the pros and cons.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yvFR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e71852e-c128-480a-82b1-a8fba5487ab3_2572x1382.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yvFR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e71852e-c128-480a-82b1-a8fba5487ab3_2572x1382.png 424w, https://substackcdn.com/image/fetch/$s_!yvFR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e71852e-c128-480a-82b1-a8fba5487ab3_2572x1382.png 848w, https://substackcdn.com/image/fetch/$s_!yvFR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e71852e-c128-480a-82b1-a8fba5487ab3_2572x1382.png 1272w, https://substackcdn.com/image/fetch/$s_!yvFR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e71852e-c128-480a-82b1-a8fba5487ab3_2572x1382.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yvFR!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e71852e-c128-480a-82b1-a8fba5487ab3_2572x1382.png" width="1200" height="644.5054945054945" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2e71852e-c128-480a-82b1-a8fba5487ab3_2572x1382.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:782,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:369433,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/164416813?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e71852e-c128-480a-82b1-a8fba5487ab3_2572x1382.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yvFR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e71852e-c128-480a-82b1-a8fba5487ab3_2572x1382.png 424w, https://substackcdn.com/image/fetch/$s_!yvFR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e71852e-c128-480a-82b1-a8fba5487ab3_2572x1382.png 848w, https://substackcdn.com/image/fetch/$s_!yvFR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e71852e-c128-480a-82b1-a8fba5487ab3_2572x1382.png 1272w, https://substackcdn.com/image/fetch/$s_!yvFR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e71852e-c128-480a-82b1-a8fba5487ab3_2572x1382.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Library vs Service - pros/cons</strong></figcaption></figure></div><p>It&#8217;s essential to evaluate the effectiveness of either approaches in production. A proactive approach saves efforts and costs in future.</p><p> Here&#8217;s how you can evaluate the success of the solution:-</p><ol><li><p><strong>Consumer count</strong> - Service is suited for large number of consumers. If your library is being adopted by large number of consumers (<strong>&gt; 5</strong>), it&#8217;s sign to move the logic to a service.</p></li><li><p><strong>Frequency of changes</strong> - Library results in less flexibility. Hence, if the code or config is changed frequently (&gt; <strong>10 changes/month</strong>), it may indicate need for a service.</p></li><li><p><strong>Performance implications</strong> - If you have tight performance constraints, service may not be the right solution. For eg:- A <strong>10ms</strong> delay results in <strong>$100K</strong> loss. In such cases, you need to make trade-offs and adopt a library based approach.</p></li><li><p><strong>Blast radius</strong> - If changes impact multiple upstream consumers and affect critical business decisions (dollar value impact), then a centralized service is appropriate for the use case.</p></li></ol><p>The above metrics would help the teams decide when to pivot from one solution to another (library to service or other way round). Additionally, to future-proof technology choices, teams must build architecture that evolves seamlessly.</p><p>Let&#8217;s understand with the help of an example, how teams can design an evolvable architecture.</p><h3>Library to service migration</h3><p>If a team decides to develop a library, it must anticipate future business growth and challenges. They must ensure that the transition is smooth and doesn&#8217;t result in multi-year effort.</p><p>Here&#8217;s how the problem can be tackled:-</p><ul><li><p><strong>API facade - </strong>Introduce a facade that mimics the future service&#8217;s API.</p></li><li><p><strong>Client migration - </strong>Migrate the clients in a controlled manner to the internal API endpoints.</p></li><li><p><strong>Library logic in service </strong>- The service must run the same library logic.</p></li><li><p><strong>Fault tolerance</strong> <strong>- </strong>Include retries, monitoring and fallbacks to protect the clients.</p></li></ul><p>Let&#8217;s go through a code example to understand this in detail. We will take Netflix&#8217;s example of fetching the plans.</p><p>The below code is used to fetch the membership plans.</p><pre><code># plan_selector.py (the current library)

def get_available_plans(user_country: str, is_mobile_enabled: bool) -&gt; list:

    if user_country in ["IN", "TH"] and is_mobile_enabled:

        return ["Mobile", "Premium"]

    return ["Basic", "Standard", "Premium"]</code></pre><p>Now, we will create a facade module that would:</p><ul><li><p>Wrap the current library.</p></li><li><p>Mimic the API of the planned HTTP/gRPC service (inputs and outputs).</p></li><li><p>Allow switching between library and service backends in the future.</p></li></ul><pre><code># plan_facade.py

from plan_selector import get_available_plans
# from requests import post  # Future: for HTTP call to service

<strong>USE_REMOTE_SERVICE</strong> = False  # Toggle this when ready to switch

def fetch_plans(user_context: dict) -&gt; dict:
    """
    Mimics the API structure of the planned service.
    Input: { country: "IN", features: { mobile_enabled: true } }
    Output: { plans: [...] }
    """
    if <strong>USE_REMOTE_SERVICE</strong>:
        # Future call to the remote Plan service
        # response = post("http://plan-service/api/v1/plans", json=user_context)
        # return response.json()
        raise NotImplementedError("Remote service not yet implemented")
    else:
        # Local fallback using the library
        country = user_context.get("country")
        mobile_enabled = user_context.get("features", {}).get("mobile_enabled", False)
        plans = get_available_plans(country, mobile_enabled)
        return {"plans": plans}
</code></pre><p>This approach ensures a smooth transition from a library to a service.</p><blockquote><p>How would the same work if you want to replace a service with a library? Think about it and share your thoughts in the comments.</p></blockquote><h2>Conclusion</h2><p>Netflix&#8217;s case study teaches us that decisions are not inherently right or wrong. But what&#8217;s wrong is turning a blind eye to the tech debt and not thinking strategically.</p><p>Few companies may witness exponential growth while many others may not. However, this shouldn&#8217;t stop the developers from deciding between a library and a service.</p><p>A more pragmatic approach is to make your tech choice future-proof by pivoting at the right time. It&#8217;s critical to keep an eye on signals such as tech debt and operational burden.</p><p>For early-stage companies or teams, it makes sense to invest in a library. But develop layers of abstraction to easily convert it into a service. It&#8217;s important to be mindful of the growth and not fall into the trap of thinking tactically.</p><p>Have you worked on a refactor or a rewrite similar to Netflix? If yes, what did you learn from it? Leave your thoughts in the comments below.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/library-vs-service-architecture-netflix-case-study?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading Engineering At Scale! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/library-vs-service-architecture-netflix-case-study?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/p/library-vs-service-architecture-netflix-case-study?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p><strong>References</strong></p><ol><li><p><a href="https://netflixtechblog.com/building-a-rule-based-platform-to-manage-netflix-membership-skus-at-scale-e3c0f82aa7bc">Netflix Membership SKUs platform</a></p></li><li><p><a href="https://www.youtube.com/watch?v=fCQKek_J3lQ">Managing 238M memberships at Netflix</a></p></li></ol><p>Before you go:</p><ul><li><p>&#10084;&#65039; the story and follow the newsletter for more such articles</p></li><li><p>&#128276; Follow me: <a href="https://www.linkedin.com/in/animesh-gaitonde/">LinkedIn</a>, <a href="https://twitter.com/animesh3436">Twitter</a>, <a href="https://medium.com/@animeshgaitonde">Medium</a></p></li><li><p>Your support helps keep this newsletter free and fuels future content. Consider a small donation to show your appreciation here - <a href="https://www.paypal.com/ncp/payment/EUGP54EHQFDZC">Paypal Donate</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[How NGINX's Event-Driven Architecture Handles Million Concurrent Connections ?]]></title><description><![CDATA[Overview of NGNIX's Event Driven Non-Blocking I/O Architecture]]></description><link>https://engineeringatscale.substack.com/p/nginx-millions-connections-event-driven-architecture</link><guid isPermaLink="false">https://engineeringatscale.substack.com/p/nginx-millions-connections-event-driven-architecture</guid><dc:creator><![CDATA[Animesh Gaitonde]]></dc:creator><pubDate>Mon, 17 Mar 2025 13:25:44 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F753aa5a0-09ed-4597-b56b-88d242692d46_2626x1330.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Have you wondered how a single NGINX instance can handle millions of concurrent connections? &#129300; </p><p>The secret sauce behind NGINX&#8217;s scalability and performance is the event-driven non-blocking I/O architecture. It seamlessly handles growing traffic and efficiently utilizes the CPU and memory resources.</p><p>In the early 2000s, NGINX was one of the first web servers that was designed for scalability, performance and concurrent connections. The architecture has inspired many other web servers, reverse proxies such as Pingora, CDNs, and cloud load balancers.</p><p>In this article, we will learn how NGINX efficiently scales to handle millions of concurrent connections. We will explore different approaches and understand their limitations. We will then learn how NGINX architecture solves the scalability and performance challenges.</p><p>With that, let&#8217;s begin with some basics of web services and why we need NGINX.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/subscribe?"><span>Subscribe now</span></a></p><h2>What does NGINX do ?</h2><p>NGINX acts as an intermediary between the client and the web services. It handles the client requests and routes it to the backend web service.It is also known as a reverse proxy and can load balance the request among multiple backend servers.</p><p>Further, it performs all infra-related heavy lifting such as SSL termination, connection management, rate limiting, etc. The backend web services can efficiently scale since the infra logic is centralized in NGINX.</p><p>The following diagram shows the interaction between a client and the server using NGINX:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9JV5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ddcb19-e2a2-4294-9891-24b0ac33c03b_2214x1014.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9JV5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ddcb19-e2a2-4294-9891-24b0ac33c03b_2214x1014.png 424w, https://substackcdn.com/image/fetch/$s_!9JV5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ddcb19-e2a2-4294-9891-24b0ac33c03b_2214x1014.png 848w, https://substackcdn.com/image/fetch/$s_!9JV5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ddcb19-e2a2-4294-9891-24b0ac33c03b_2214x1014.png 1272w, https://substackcdn.com/image/fetch/$s_!9JV5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ddcb19-e2a2-4294-9891-24b0ac33c03b_2214x1014.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9JV5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ddcb19-e2a2-4294-9891-24b0ac33c03b_2214x1014.png" width="1456" height="667" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/42ddcb19-e2a2-4294-9891-24b0ac33c03b_2214x1014.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:667,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:187148,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/159125556?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ddcb19-e2a2-4294-9891-24b0ac33c03b_2214x1014.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9JV5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ddcb19-e2a2-4294-9891-24b0ac33c03b_2214x1014.png 424w, https://substackcdn.com/image/fetch/$s_!9JV5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ddcb19-e2a2-4294-9891-24b0ac33c03b_2214x1014.png 848w, https://substackcdn.com/image/fetch/$s_!9JV5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ddcb19-e2a2-4294-9891-24b0ac33c03b_2214x1014.png 1272w, https://substackcdn.com/image/fetch/$s_!9JV5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ddcb19-e2a2-4294-9891-24b0ac33c03b_2214x1014.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>How NGINX works ?</strong></figcaption></figure></div><p>While NGINX solves most of the problems with traditional web service architecture, it still needs to solve:</p><ol><li><p><strong>Concurrent connections</strong> - Large number of concurrent connections from clients.</p></li><li><p><strong>Performance</strong> - No performance degradation with user growth.</p></li><li><p><strong>Efficient resource utilization</strong> - Low memory usage and optimal CPU utilization.</p></li></ol><p>Before diving into the solution, let&#8217;s revisit connection management basics and understand the scalability bottlenecks.</p><h3>How are the connections handled ?</h3><p>When a web server starts, it calls the operating System and passes the port on which it listens. For e.g., Web servers would pass port 80 (http) or 443 (https) to listen.</p><p>When the client connects, the OS&#8217;s kernel stack performs a TCP handshake and establishes a connection. The OS assigns a file descriptor or a socket for each connection.</p><p>The below diagram illustrates the connection establishment between the client and the server:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zf4y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4ec6cad-7bdb-4015-9dda-f02f6993e3a2_1550x1420.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zf4y!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4ec6cad-7bdb-4015-9dda-f02f6993e3a2_1550x1420.png 424w, https://substackcdn.com/image/fetch/$s_!zf4y!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4ec6cad-7bdb-4015-9dda-f02f6993e3a2_1550x1420.png 848w, https://substackcdn.com/image/fetch/$s_!zf4y!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4ec6cad-7bdb-4015-9dda-f02f6993e3a2_1550x1420.png 1272w, https://substackcdn.com/image/fetch/$s_!zf4y!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4ec6cad-7bdb-4015-9dda-f02f6993e3a2_1550x1420.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zf4y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4ec6cad-7bdb-4015-9dda-f02f6993e3a2_1550x1420.png" width="1456" height="1334" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c4ec6cad-7bdb-4015-9dda-f02f6993e3a2_1550x1420.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1334,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:155926,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/159125556?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4ec6cad-7bdb-4015-9dda-f02f6993e3a2_1550x1420.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!zf4y!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4ec6cad-7bdb-4015-9dda-f02f6993e3a2_1550x1420.png 424w, https://substackcdn.com/image/fetch/$s_!zf4y!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4ec6cad-7bdb-4015-9dda-f02f6993e3a2_1550x1420.png 848w, https://substackcdn.com/image/fetch/$s_!zf4y!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4ec6cad-7bdb-4015-9dda-f02f6993e3a2_1550x1420.png 1272w, https://substackcdn.com/image/fetch/$s_!zf4y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4ec6cad-7bdb-4015-9dda-f02f6993e3a2_1550x1420.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Connection establishment between client-server</strong></figcaption></figure></div><p>By default, sending and receiving data over a network (<strong>Network I/O</strong>) is blocking. A thread or a process goes into waiting state while writing or reading data to/from the network.</p><p>Also, the network I/O is dependent on the client&#8217;s bandwidth. Data transfer may take a long time for slow clients.</p><p>The following diagram shows how a process waits until the complete data transfer:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Bf2g!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc03477-bb77-4fe2-8ef1-19a91ef20625_1504x1442.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Bf2g!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc03477-bb77-4fe2-8ef1-19a91ef20625_1504x1442.png 424w, https://substackcdn.com/image/fetch/$s_!Bf2g!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc03477-bb77-4fe2-8ef1-19a91ef20625_1504x1442.png 848w, https://substackcdn.com/image/fetch/$s_!Bf2g!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc03477-bb77-4fe2-8ef1-19a91ef20625_1504x1442.png 1272w, https://substackcdn.com/image/fetch/$s_!Bf2g!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc03477-bb77-4fe2-8ef1-19a91ef20625_1504x1442.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Bf2g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc03477-bb77-4fe2-8ef1-19a91ef20625_1504x1442.png" width="1456" height="1396" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9cc03477-bb77-4fe2-8ef1-19a91ef20625_1504x1442.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1396,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:157875,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/159125556?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc03477-bb77-4fe2-8ef1-19a91ef20625_1504x1442.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Bf2g!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc03477-bb77-4fe2-8ef1-19a91ef20625_1504x1442.png 424w, https://substackcdn.com/image/fetch/$s_!Bf2g!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc03477-bb77-4fe2-8ef1-19a91ef20625_1504x1442.png 848w, https://substackcdn.com/image/fetch/$s_!Bf2g!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc03477-bb77-4fe2-8ef1-19a91ef20625_1504x1442.png 1272w, https://substackcdn.com/image/fetch/$s_!Bf2g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc03477-bb77-4fe2-8ef1-19a91ef20625_1504x1442.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Process waiting for data transfer</strong></figcaption></figure></div><p>As a result, the server can&#8217;t accept new connections if it&#8217;s already processing request from a client. This hinders the system&#8217;s scalability and performance both.</p><p>There are several ways to tackle this problem and handle more connections. Let&#8217;s understand the different approaches and their limitations.</p><h2>Process-Per-Request Approach</h2><p>To overcome the network I/O bottleneck, the process can fork a new child process. The child process would then handle a new client connection.</p><p>Every connection would correspond to a new child process. Once the request/response cycle is completed, the child process would be killed.</p><p>The below diagram illustrates this process:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1gLY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47a71df5-3038-4efe-a9a5-a6add8714d2c_1518x1440.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1gLY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47a71df5-3038-4efe-a9a5-a6add8714d2c_1518x1440.png 424w, https://substackcdn.com/image/fetch/$s_!1gLY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47a71df5-3038-4efe-a9a5-a6add8714d2c_1518x1440.png 848w, https://substackcdn.com/image/fetch/$s_!1gLY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47a71df5-3038-4efe-a9a5-a6add8714d2c_1518x1440.png 1272w, https://substackcdn.com/image/fetch/$s_!1gLY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47a71df5-3038-4efe-a9a5-a6add8714d2c_1518x1440.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1gLY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47a71df5-3038-4efe-a9a5-a6add8714d2c_1518x1440.png" width="1456" height="1381" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/47a71df5-3038-4efe-a9a5-a6add8714d2c_1518x1440.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1381,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:184844,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/159125556?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47a71df5-3038-4efe-a9a5-a6add8714d2c_1518x1440.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!1gLY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47a71df5-3038-4efe-a9a5-a6add8714d2c_1518x1440.png 424w, https://substackcdn.com/image/fetch/$s_!1gLY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47a71df5-3038-4efe-a9a5-a6add8714d2c_1518x1440.png 848w, https://substackcdn.com/image/fetch/$s_!1gLY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47a71df5-3038-4efe-a9a5-a6add8714d2c_1518x1440.png 1272w, https://substackcdn.com/image/fetch/$s_!1gLY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47a71df5-3038-4efe-a9a5-a6add8714d2c_1518x1440.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Process-Per-Request Approach</strong></figcaption></figure></div><blockquote><p>Do you think this approach would scale to millions of users/connections ? Take a moment to think and then continue reading </p></blockquote><p>Let&#8217;s assume the server RAM size is <strong>32 GB</strong> and each process takes <strong>100 MB</strong>. So, then it can handle only <strong>320</strong> (<em>32 GB/ 100 MB</em>) <strong>connections</strong> in the best case.</p><p>Here are some downsides of this approach:</p><ol><li><p><strong>Scalability Issues</strong> - Number of connections depend on the hardware (RAM size). More connections would lead to out of memory issues.</p></li><li><p><strong>Performance Issues</strong> - Forking a child process is slow and would impact the performance.</p></li></ol><p>Can we do better? What if instead of forking a process, we launch a thread? Let&#8217;s explore this approach in the next section.</p><h2>Thread-Per-Request Approach</h2><p>In this approach, a thread is launched every time a client connection is established. Each request is handled independently by a different thread.</p><p>The below diagram shows how this model works:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2hxu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2483b50-18f5-4c96-9c23-ff7dc8cd00a8_1550x1420.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2hxu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2483b50-18f5-4c96-9c23-ff7dc8cd00a8_1550x1420.png 424w, https://substackcdn.com/image/fetch/$s_!2hxu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2483b50-18f5-4c96-9c23-ff7dc8cd00a8_1550x1420.png 848w, https://substackcdn.com/image/fetch/$s_!2hxu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2483b50-18f5-4c96-9c23-ff7dc8cd00a8_1550x1420.png 1272w, https://substackcdn.com/image/fetch/$s_!2hxu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2483b50-18f5-4c96-9c23-ff7dc8cd00a8_1550x1420.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2hxu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2483b50-18f5-4c96-9c23-ff7dc8cd00a8_1550x1420.png" width="1456" height="1334" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b2483b50-18f5-4c96-9c23-ff7dc8cd00a8_1550x1420.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1334,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:182016,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/159125556?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2483b50-18f5-4c96-9c23-ff7dc8cd00a8_1550x1420.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2hxu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2483b50-18f5-4c96-9c23-ff7dc8cd00a8_1550x1420.png 424w, https://substackcdn.com/image/fetch/$s_!2hxu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2483b50-18f5-4c96-9c23-ff7dc8cd00a8_1550x1420.png 848w, https://substackcdn.com/image/fetch/$s_!2hxu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2483b50-18f5-4c96-9c23-ff7dc8cd00a8_1550x1420.png 1272w, https://substackcdn.com/image/fetch/$s_!2hxu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2483b50-18f5-4c96-9c23-ff7dc8cd00a8_1550x1420.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Thread-Per-Request Approach</strong></figcaption></figure></div><p>Threads are lightweight and almost 1/10th size of a process. As a result, this is a significant improvement from the Process-Per-Request approach.</p><p>While this approach can handle more number of connections, it would still run into issues highlighted in the previous section.</p><p>A process can&#8217;t launch an infinite number of threads. The benefits of multi-threading diminish with large number of threads due to frequent CPU context switching.</p><p>We can still improve by using a thread pool and launching a fixed number of threads. For eg:- 500 threads in the process.</p><p>This improvement would result in efficient memory usage. However, if all the threads are busy, the new connections would wait in the request queue resulting in slowness.</p><p>Hence, this approach also doesn&#8217;t solve for scalability and performance. We can&#8217;t scale since the primary bottleneck is the time-consuming network I/O.</p><p>Is there a way to unblock the process or thread during the network I/O? Yes, and NGINX employs an intelligent tactic using its event-driven non-blocking I/O.</p><p>Let&#8217;s understand NGINX&#8217;s architecture in detail in the next section.</p><h2>NGINX Architecture</h2><p>NGINX uses a modular architecture and consists of several components such as:</p><ol><li><p><strong>Master process</strong> - It acts as the central controller and is responsible for starting, stopping, and launching the worker processes.</p></li><li><p><strong>Worker processes</strong> - These run the core NGINX logic and are responsible for connection handling, request forwarding, load balancing, etc.</p></li><li><p><strong>Cache loader</strong> - This process is responsible for loading the cached metadata in memory when Nginx boots up.</p></li><li><p><strong>Cache manager</strong> - It periodically checks the cache directory and frees up space by removing expired entries.</p></li><li><p><strong>Shared memory</strong> - The inter-process communication takes place via the shared memory. It&#8217;s also used for caching, and managing shared state like load balancing status.</p></li></ol><p>The following diagram shows the different components of NGINX architecture.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PbQQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F753aa5a0-09ed-4597-b56b-88d242692d46_2626x1330.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PbQQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F753aa5a0-09ed-4597-b56b-88d242692d46_2626x1330.png 424w, https://substackcdn.com/image/fetch/$s_!PbQQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F753aa5a0-09ed-4597-b56b-88d242692d46_2626x1330.png 848w, https://substackcdn.com/image/fetch/$s_!PbQQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F753aa5a0-09ed-4597-b56b-88d242692d46_2626x1330.png 1272w, https://substackcdn.com/image/fetch/$s_!PbQQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F753aa5a0-09ed-4597-b56b-88d242692d46_2626x1330.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PbQQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F753aa5a0-09ed-4597-b56b-88d242692d46_2626x1330.png" width="1456" height="737" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/753aa5a0-09ed-4597-b56b-88d242692d46_2626x1330.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:737,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:207648,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/159125556?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F753aa5a0-09ed-4597-b56b-88d242692d46_2626x1330.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!PbQQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F753aa5a0-09ed-4597-b56b-88d242692d46_2626x1330.png 424w, https://substackcdn.com/image/fetch/$s_!PbQQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F753aa5a0-09ed-4597-b56b-88d242692d46_2626x1330.png 848w, https://substackcdn.com/image/fetch/$s_!PbQQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F753aa5a0-09ed-4597-b56b-88d242692d46_2626x1330.png 1272w, https://substackcdn.com/image/fetch/$s_!PbQQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F753aa5a0-09ed-4597-b56b-88d242692d46_2626x1330.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>NGINX architecture</strong></figcaption></figure></div><p>Let&#8217;s now dive into the details of how NGINX can scale to million concurrent connections.</p><h3>Event-driven Non-blocking I/O</h3><p>In case of non-blocking I/O, the web server or the application doesn&#8217;t wait for the client&#8217;s data. Instead, the OS informs the application once the data is available.</p><p>This makes the process event-driven. Whenever the client&#8217;s data is available, the application would get interrupted and it would process the data. Otherwise, it would continue to do something else.</p><p>Further, the application doesn&#8217;t go into a waiting state. It can execute other tasks and efficiently utilize the CPU.</p><p>Internally, the application uses a system call called <strong>epoll</strong> or <strong>kqueue</strong> and then registers the sockets. The operating system uses a kernel data structure (<strong>Epoll instance</strong>) to keep track of the sockets that an application is interested in.</p><p>Once data is available in a subset of sockets, those sockets are moved into a ready list. The OS then informs the application about those sockets. Finally, the application then processes the data.</p><p>The below diagram illustrates this flow:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UqcG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b88a9b1-a149-45c0-88cd-84ee8257bc97_2364x1582.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UqcG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b88a9b1-a149-45c0-88cd-84ee8257bc97_2364x1582.png 424w, https://substackcdn.com/image/fetch/$s_!UqcG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b88a9b1-a149-45c0-88cd-84ee8257bc97_2364x1582.png 848w, https://substackcdn.com/image/fetch/$s_!UqcG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b88a9b1-a149-45c0-88cd-84ee8257bc97_2364x1582.png 1272w, https://substackcdn.com/image/fetch/$s_!UqcG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b88a9b1-a149-45c0-88cd-84ee8257bc97_2364x1582.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UqcG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b88a9b1-a149-45c0-88cd-84ee8257bc97_2364x1582.png" width="1456" height="974" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0b88a9b1-a149-45c0-88cd-84ee8257bc97_2364x1582.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:974,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:270034,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/159125556?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b88a9b1-a149-45c0-88cd-84ee8257bc97_2364x1582.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UqcG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b88a9b1-a149-45c0-88cd-84ee8257bc97_2364x1582.png 424w, https://substackcdn.com/image/fetch/$s_!UqcG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b88a9b1-a149-45c0-88cd-84ee8257bc97_2364x1582.png 848w, https://substackcdn.com/image/fetch/$s_!UqcG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b88a9b1-a149-45c0-88cd-84ee8257bc97_2364x1582.png 1272w, https://substackcdn.com/image/fetch/$s_!UqcG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b88a9b1-a149-45c0-88cd-84ee8257bc97_2364x1582.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Event-driven Non-blocking I/O using Epoll</strong></figcaption></figure></div><p>As seen from the above diagram, once data becomes available on <em>fd3</em>, and <em>fd4</em>, the process is notified by the OS.</p><p>Let&#8217;s now understand this in the context of a NGINX worker.</p><h3>NGINX worker</h3><p>Each NGINX worker is single-threaded and it runs an event loop. The event loop works like a while loop and checks for any activity on the socket or new connections.</p><p>Further, the NGINX worker is pinned to a CPU to avoid context switches. This eliminates the context switching overhead and improves the performance.</p><p>Here&#8217;s the pseudo code that explains what happens behind the scenes in a worker:</p><pre><code>while True:
    # Wait for events on the monitored sockets
    events = epoll_wait(epoll_fd, MAX_EVENTS, timeout=-1)  # Block indefinitely
    if events == -1:
        raise Exception("epoll_wait failed")

    # Process each event
    for event in events:
        fd = event.data.fd

        # Case 1: New connection on the server socket
        if fd == server_socket:
            # Accept the new connection
        # Case 2: Data available on a client socket
        elif event.events &amp; EPOLLIN:
            # Read data from the client socket
            data = client_socket.recv(BUFFER_SIZE)
            if not data:  # Client closed the connection
                epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_socket, None)
                client_socket.close()
                del client_sockets[client_socket]
            else:
                # Append data to the client's buffer
                client_sockets[client_socket]["buffer"] += data

                 # Process the request (takes ~100s of microseconds)
                 request = client_sockets[client_socket]["buffer"]
                 response = process_request(request)  # Assume this function exists

                 # Send the response
                 client_socket.sendall(response)

        # Case 3: Client socket ready for writing (if needed)
        elif event.events &amp; EPOLLOUT:
            # Handle writing data to the client (if applicable)
            pass</code></pre><p>With non-blocking sockets, the worker doesn&#8217;t need to wait till the data is completely sent to the client. It can quickly move onto the next connection and process the request. (<em>Case-1</em>)</p><p>In case the data is available on multiple sockets, it iterates on each and process the client request. (<em>Case-2</em>)</p><p>Since network I/O is non-blocking, the process doesn&#8217;t wait for the data transfer. And the worker uses CPU only for request parsing, filtering, and other compute operations.</p><p>Compute operations are less time-taking (in order of <strong>micro-seconds</strong>). As a result, a single worker can process <strong>100K</strong> requests every second concurrently.</p><p>Assuming that a single worker can handle <strong>100K</strong> connections, if it&#8217;s a 10-core CPU, the server can handle 1 million concurrent connections. (Example for illustration only, in real world, things might be different).</p><blockquote><p>Note: A server must have sufficient memory to serve <strong>1 million connections</strong> since each connection needs <strong>100KB-1MB</strong> memory. But the OS kernel can be tuned to reduce the connection&#8217;s memory.(there are trade-offs to this approach)</p></blockquote><p>The event-driven non-blocking I/O efficiently utilizes the CPU and doesn&#8217;t consume memory like Process-Per-Request or Thread-Per-Request approach.</p><h2>Conclusion</h2><p>A key challenge in building scalable web architecture is to handle simultaneous concurrent client connections. Also, the web service needs to handle concurrent requests and efficiently utilize CPU and memory resources.</p><p>NGINX uses the event-driven non-blocking I/O architecture and tackles the following challenges :-</p><ol><li><p><strong>Concurrent connections</strong> - It uses several workers to handle client connections. Non-blocking I/O allows it to accept new connections while already processing other connections.</p></li><li><p><strong>Performance</strong> - Each worker is single threaded and pinned to a CPU. This greatly improves the throughput and performance due to no context switches.</p></li><li><p><strong>Efficient resource utilization</strong> - Instead of launching new process or a thread for each connection, a single worker is able to manage multiple connections. The only overhead if a connection&#8217;s memory usage. Further, due to event-driven nature, the worker doesn&#8217;t go into waiting state frequently. This improves the CPU utilization. </p></li></ol><p>Before you leave, what do you think would happen if the server running NGINX crashed? Would NGINX become a single point of failure? &#129300;</p><p>Share your thoughts in the comments below.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/nginx-millions-connections-event-driven-architecture?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading Engineering At Scale! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/nginx-millions-connections-event-driven-architecture?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/p/nginx-millions-connections-event-driven-architecture?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p>Before you go:</p><ul><li><p>&#10084;&#65039; the story and follow the newsletter for more such articles</p></li><li><p>&#128276; Follow me: <a href="https://www.linkedin.com/in/animesh-gaitonde/">LinkedIn</a>, <a href="https://twitter.com/animesh3436">Twitter</a>, <a href="https://medium.com/@animeshgaitonde">Medium</a></p></li><li><p>Your support helps keep this newsletter free and fuels future content. Consider a small donation to show your appreciation here - <a href="https://www.paypal.com/ncp/payment/EUGP54EHQFDZC">Paypal Donate</a></p></li></ul><h2>References </h2><ol><li><p><a href="https://aosabook.org/en/v2/nginx.html">NGINX architecture</a></p></li><li><p><a href="https://github.com/nginx/nginx/blob/0759f088a532ec48170ca03d694cc103757a0f4c/src/event/modules/ngx_epoll_module.c">NGINX epoll module</a></p></li></ol>]]></content:encoded></item><item><title><![CDATA[Redis Persistence Dive Deep - Trade-offs Between Performance And Durability]]></title><description><![CDATA[Understanding AOF and RDB strategies, their trade-offs and applications]]></description><link>https://engineeringatscale.substack.com/p/redis-persistence-aof-rdb-crash-recovery</link><guid isPermaLink="false">https://engineeringatscale.substack.com/p/redis-persistence-aof-rdb-crash-recovery</guid><dc:creator><![CDATA[Animesh Gaitonde]]></dc:creator><pubDate>Sun, 02 Mar 2025 15:13:08 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!HeLD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003fc232-d5ce-4286-b368-1773e819e359_2478x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>What would happen to your data if your Redis instance crashed suddenly? Would all your data be lost, partially recoverable, or safe ?</p><p>Redis is widely known as an in-memory cache, but can it also serve as a durable storage system like a traditional database?</p><p>Like many developers, I initially assumed Redis was just a cache. But as I explored its persistence mechanisms, I realized it could offer more.</p><p>Performance and durability are two key considerations in designing Redis&#8217;s data persistence. If the system prioritizes performance, it must compromise on durability, and vice versa.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/subscribe?"><span>Subscribe now</span></a></p><p>In this article, we will dive deep into the different data persistence strategies of Redis. We will look at the pros/cons of each and their practical applications. </p><p>By the end of the article, you will gain sufficient technical depth to decide the right persistence strategy for your use case. You will also enhance your skills to succeed in your next system design interview.</p><p>With that, let&#8217;s first understand the need for data persistence.</p><h2>Why does Redis need data persistence ?</h2><p>Redis is an in-memory cache and stores all the data in the RAM. RAM is volatile, and if the server crashes or restarts, all the data is lost.</p><p>Assume that you are using Redis as a cache for a backend database. What would happen if it crashed mid-way while handling customer traffic ?</p><p>The following diagram illustrates the state of the application before and after Redis crash.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HeLD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003fc232-d5ce-4286-b368-1773e819e359_2478x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HeLD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003fc232-d5ce-4286-b368-1773e819e359_2478x1536.png 424w, https://substackcdn.com/image/fetch/$s_!HeLD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003fc232-d5ce-4286-b368-1773e819e359_2478x1536.png 848w, https://substackcdn.com/image/fetch/$s_!HeLD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003fc232-d5ce-4286-b368-1773e819e359_2478x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!HeLD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003fc232-d5ce-4286-b368-1773e819e359_2478x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HeLD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003fc232-d5ce-4286-b368-1773e819e359_2478x1536.png" width="1456" height="903" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/003fc232-d5ce-4286-b368-1773e819e359_2478x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:903,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:347748,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/158182042?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003fc232-d5ce-4286-b368-1773e819e359_2478x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!HeLD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003fc232-d5ce-4286-b368-1773e819e359_2478x1536.png 424w, https://substackcdn.com/image/fetch/$s_!HeLD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003fc232-d5ce-4286-b368-1773e819e359_2478x1536.png 848w, https://substackcdn.com/image/fetch/$s_!HeLD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003fc232-d5ce-4286-b368-1773e819e359_2478x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!HeLD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F003fc232-d5ce-4286-b368-1773e819e359_2478x1536.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>State of the system before and after Redis crash</strong></figcaption></figure></div><p>Here&#8217;s what would happen after a Redis crash:</p><ol><li><p><strong>High database load</strong> - All the cache requests would fallback on the database increasing its load. Often, this is known as the thundering herd problem.</p></li><li><p><strong>Slow queries</strong> - Since database fetches the data from the disk, the query latency would spike by <strong>100x</strong>.</p></li><li><p><strong>Reduced availability</strong> - Some slow queries might time out, leading to failed application requests and reduced system availability (e.g., from <strong>99.99%</strong> to <strong>95%</strong>).<strong>  </strong></p></li></ol><p>After the Redis server restarts, there would be a brief period where the data would be written to the cache, and eventually, the system would function as expected.</p><p>As we just saw, there is a possibility of complete data loss in case a Redis instance crashes. Additionally, this impacts the application's performance and results in a poor user or client experience.</p><p>So, is there a way to tackle this problem by permanently storing the data somewhere ? Yes, and Redis provides several strategies to solve this problem.</p><p>Let&#8217;s now take a look at the first strategy called <strong>Append-Only File (AOF)</strong> for persistence.</p><h2>Append-Only File (AOF)</h2><p>Redis clients interact with Redis by running different commands. For example: <em>SET key value</em>, <em>INCR key,</em> <em>LPUSH key value</em>, etc.</p><p>Redis is single-threaded by design and sequentially executes all the commands. The command execution modifies the in-memory data structures, and we end up with a particular state.</p><p>The <strong>Append-Only File</strong> (<strong>AOF</strong>) persistence strategy exploits this and stores all the commands in an append-only file. On server restarts, the AOF is read and all commands are sequentially executed to recover the previous state.</p><p>The following diagram illustrates how Redis logs commands in the AOF file.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OEse!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F509dba15-674f-473e-97e1-019b06c03ad0_2738x1244.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OEse!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F509dba15-674f-473e-97e1-019b06c03ad0_2738x1244.png 424w, https://substackcdn.com/image/fetch/$s_!OEse!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F509dba15-674f-473e-97e1-019b06c03ad0_2738x1244.png 848w, https://substackcdn.com/image/fetch/$s_!OEse!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F509dba15-674f-473e-97e1-019b06c03ad0_2738x1244.png 1272w, https://substackcdn.com/image/fetch/$s_!OEse!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F509dba15-674f-473e-97e1-019b06c03ad0_2738x1244.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OEse!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F509dba15-674f-473e-97e1-019b06c03ad0_2738x1244.png" width="1456" height="662" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/509dba15-674f-473e-97e1-019b06c03ad0_2738x1244.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:662,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:330947,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/158182042?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F509dba15-674f-473e-97e1-019b06c03ad0_2738x1244.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!OEse!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F509dba15-674f-473e-97e1-019b06c03ad0_2738x1244.png 424w, https://substackcdn.com/image/fetch/$s_!OEse!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F509dba15-674f-473e-97e1-019b06c03ad0_2738x1244.png 848w, https://substackcdn.com/image/fetch/$s_!OEse!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F509dba15-674f-473e-97e1-019b06c03ad0_2738x1244.png 1272w, https://substackcdn.com/image/fetch/$s_!OEse!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F509dba15-674f-473e-97e1-019b06c03ad0_2738x1244.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Working of Redis AOF</strong></figcaption></figure></div><p>The diagram below shows how Redis reconstructs the previous state by reading the AOF file. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3VWm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5071d727-3221-480e-8a57-b3b4914236e0_1946x1280.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3VWm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5071d727-3221-480e-8a57-b3b4914236e0_1946x1280.png 424w, https://substackcdn.com/image/fetch/$s_!3VWm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5071d727-3221-480e-8a57-b3b4914236e0_1946x1280.png 848w, https://substackcdn.com/image/fetch/$s_!3VWm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5071d727-3221-480e-8a57-b3b4914236e0_1946x1280.png 1272w, https://substackcdn.com/image/fetch/$s_!3VWm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5071d727-3221-480e-8a57-b3b4914236e0_1946x1280.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3VWm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5071d727-3221-480e-8a57-b3b4914236e0_1946x1280.png" width="1456" height="958" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5071d727-3221-480e-8a57-b3b4914236e0_1946x1280.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:958,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:239693,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/158182042?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5071d727-3221-480e-8a57-b3b4914236e0_1946x1280.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3VWm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5071d727-3221-480e-8a57-b3b4914236e0_1946x1280.png 424w, https://substackcdn.com/image/fetch/$s_!3VWm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5071d727-3221-480e-8a57-b3b4914236e0_1946x1280.png 848w, https://substackcdn.com/image/fetch/$s_!3VWm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5071d727-3221-480e-8a57-b3b4914236e0_1946x1280.png 1272w, https://substackcdn.com/image/fetch/$s_!3VWm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5071d727-3221-480e-8a57-b3b4914236e0_1946x1280.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Redis crash recovery process</strong></figcaption></figure></div><div><hr></div><blockquote><p>Why are commands added to the AOF after execution, not before? &#129300; &#129300; </p><p>Leave your thoughts in the comments</p></blockquote><div><hr></div><p>We just saw that we can completely shield Redis from data loss by using the AOF technique. But astute readers would have noticed that we are logging every command to disk and that might increase the I/O. This would eventually slow down Redis&#8217;s main thread.</p><p>Although the AOF technique can prevent complete data loss, it comes with an additional cost that impacts performance. Let&#8217;s now look at the pros/cons of this approach.</p><h3>Pros</h3><ol><li><p><strong>Data durability</strong> - It can reconstruct the previous state and result in 0 data loss.</p></li></ol><h3>Cons</h3><ol><li><p><strong>Performance</strong> - Since every command is written to a disk, there is an additional disk I/O. This impacts the performance of each command and might introduce an additional <strong>100-200 ms</strong> latency. This prevents clients from using Redis as a high-performance, in-memory cache.</p></li><li><p><strong>Slow starts </strong>- The AOF might contain billions of commands. Given the single-threaded nature and sequential execution, complete recovery may take anywhere between <strong>100 milliseconds</strong> to <strong>1-2 seconds</strong>.</p></li></ol><p>Logging every command to the disk impacts the performance. As a result, Redis provides multiple configuration options to tune performance and durability.</p><h3>Configuration options</h3><p>Redis allows tuning AOF behaviour with three configurations, each offering a trade-off between performance and durability.</p><p>Internally, Redis uses the <strong>fsync</strong> system call to flush executed commands to the AOF. It provides the following three options :-</p><ol><li><p><strong>appendfsync always</strong> - It logs all the executed commands to the AOF. It takes time but guarantees strong durability.</p></li><li><p><strong>appendfsync everysec </strong>- Executed commands are appended to a buffer, which is flushed to the AOF every second. In the worst case, Redis might lose one second of new data.</p></li><li><p><strong>appendfsync no</strong> - Instead of application flushing the data, the flushing is controlled by the Operating System. Depending on the kernel, the frequency could be anywhere between <strong>30 sec - 60 sec</strong>. </p></li></ol><p>The below matrix captures the three different options along with the impact on the system&#8217;s quality attributes.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-3AB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda41886f-4776-4147-be44-5aae7c982791_1710x648.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-3AB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda41886f-4776-4147-be44-5aae7c982791_1710x648.png 424w, https://substackcdn.com/image/fetch/$s_!-3AB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda41886f-4776-4147-be44-5aae7c982791_1710x648.png 848w, https://substackcdn.com/image/fetch/$s_!-3AB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda41886f-4776-4147-be44-5aae7c982791_1710x648.png 1272w, https://substackcdn.com/image/fetch/$s_!-3AB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda41886f-4776-4147-be44-5aae7c982791_1710x648.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-3AB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda41886f-4776-4147-be44-5aae7c982791_1710x648.png" width="1456" height="552" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/da41886f-4776-4147-be44-5aae7c982791_1710x648.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:552,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:80316,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/158182042?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda41886f-4776-4147-be44-5aae7c982791_1710x648.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-3AB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda41886f-4776-4147-be44-5aae7c982791_1710x648.png 424w, https://substackcdn.com/image/fetch/$s_!-3AB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda41886f-4776-4147-be44-5aae7c982791_1710x648.png 848w, https://substackcdn.com/image/fetch/$s_!-3AB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda41886f-4776-4147-be44-5aae7c982791_1710x648.png 1272w, https://substackcdn.com/image/fetch/$s_!-3AB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda41886f-4776-4147-be44-5aae7c982791_1710x648.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>fsync always</strong> vs <strong>fsync everysec</strong> vs <strong>fsync no</strong></figcaption></figure></div><p>While AOF minimizes data loss, it has a performance penalty. Thus, Redis provides another option known as RDB (Redis Database).</p><p>Let&#8217;s understand how RDB tries to overcome the downsides of AOF.</p><h2>Redis Database (RDB)</h2><p>Redis takes a snapshot of all the in-memory data and stores it in a binary file (<strong>.rdb </strong>suffix). In case of a crash, it reads and recovers the data from the rdb file.</p><p>It provides the commands <strong>SAVE</strong> and <strong>BGSAVE</strong> (background save) to take a snapshot. Here&#8217;s the difference between the two commands:</p><ol><li><p><strong>SAVE </strong>- It&#8217;s sequentially executed in Redis&#8217;s main thread. As a result, it impacts the cache&#8217;s performance due to additional I/O overhead.</p></li><li><p><strong>BGSAVE</strong> - It forks a new child process. The child process executes on a different CPU core and copies the data into the RDB file.</p></li></ol><p>Redis crash recovery process using RDB is illustrated in the following diagram.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TcDp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17189251-a7d3-4528-9d7a-0ac2928c297b_1964x1752.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TcDp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17189251-a7d3-4528-9d7a-0ac2928c297b_1964x1752.png 424w, https://substackcdn.com/image/fetch/$s_!TcDp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17189251-a7d3-4528-9d7a-0ac2928c297b_1964x1752.png 848w, https://substackcdn.com/image/fetch/$s_!TcDp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17189251-a7d3-4528-9d7a-0ac2928c297b_1964x1752.png 1272w, https://substackcdn.com/image/fetch/$s_!TcDp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17189251-a7d3-4528-9d7a-0ac2928c297b_1964x1752.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TcDp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17189251-a7d3-4528-9d7a-0ac2928c297b_1964x1752.png" width="1456" height="1299" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/17189251-a7d3-4528-9d7a-0ac2928c297b_1964x1752.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1299,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:390378,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/158182042?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17189251-a7d3-4528-9d7a-0ac2928c297b_1964x1752.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!TcDp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17189251-a7d3-4528-9d7a-0ac2928c297b_1964x1752.png 424w, https://substackcdn.com/image/fetch/$s_!TcDp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17189251-a7d3-4528-9d7a-0ac2928c297b_1964x1752.png 848w, https://substackcdn.com/image/fetch/$s_!TcDp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17189251-a7d3-4528-9d7a-0ac2928c297b_1964x1752.png 1272w, https://substackcdn.com/image/fetch/$s_!TcDp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17189251-a7d3-4528-9d7a-0ac2928c297b_1964x1752.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Crash recovery using RDB file</strong></figcaption></figure></div><div><hr></div><blockquote><p>What would happen if the memory is modified during snapshotting ? &#129300; &#129300; </p><p>Leave your thoughts in the comments</p></blockquote><div><hr></div><p>Now that you understand the basic working, let&#8217;s look at some pros/cons of this approach.</p><h3>Pros</h3><ol><li><p><strong>Performance</strong> - The snapshotting process can be executed on a different thread (using <strong>BGSAVE</strong>). As a result, it doesn&#8217;t impact the overall performance of Redis.</p></li><li><p><strong>Restart time</strong> - The RDB file data can be read quickly and restored. This reduces the restart time and overhead in data recovery. </p></li></ol><h3>Cons</h3><ol><li><p><strong>Data loss</strong> - It doesn&#8217;t guarantee 0% data loss. As a result, clients may get stale data or result in cache misses.</p></li><li><p><strong>Large datasets</strong> - Since fork() is used, the process can be time-consuming for large datasets. This may impact the client&#8217;s performance in case Redis stop serving the clients till the child process is successfully created.</p></li></ol><p>So far, we have seen that while AOF prioritizes data durability at the cost of performance, RDB sacrifices some durability in favor of better performance.</p><p>Given the trade-offs of AOF and RDB, is there a way to achieve a middle ground? Fortunately, Redis offers a hybrid approach: <strong>AOF + RDB</strong>.</p><p>We can combine RDB with AOF and strike the right balance between the two approaches. Let&#8217;s now understand how we can get best of both the worlds.</p><h2>AOF + RDB</h2><p>Redis provides a configuration option <strong>aof-use-rdb-preamble</strong>. If it is enabled, Redis takes periodic snapshots and stores the subsequent commands in the AOF file.</p><p>The diagram below illustrates the working of AOF + RDB.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lW9a!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0542714d-99f9-4642-b58e-98ea65f5be7a_2728x1028.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lW9a!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0542714d-99f9-4642-b58e-98ea65f5be7a_2728x1028.png 424w, https://substackcdn.com/image/fetch/$s_!lW9a!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0542714d-99f9-4642-b58e-98ea65f5be7a_2728x1028.png 848w, https://substackcdn.com/image/fetch/$s_!lW9a!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0542714d-99f9-4642-b58e-98ea65f5be7a_2728x1028.png 1272w, https://substackcdn.com/image/fetch/$s_!lW9a!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0542714d-99f9-4642-b58e-98ea65f5be7a_2728x1028.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lW9a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0542714d-99f9-4642-b58e-98ea65f5be7a_2728x1028.png" width="1456" height="549" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0542714d-99f9-4642-b58e-98ea65f5be7a_2728x1028.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:549,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:372628,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/158182042?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0542714d-99f9-4642-b58e-98ea65f5be7a_2728x1028.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lW9a!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0542714d-99f9-4642-b58e-98ea65f5be7a_2728x1028.png 424w, https://substackcdn.com/image/fetch/$s_!lW9a!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0542714d-99f9-4642-b58e-98ea65f5be7a_2728x1028.png 848w, https://substackcdn.com/image/fetch/$s_!lW9a!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0542714d-99f9-4642-b58e-98ea65f5be7a_2728x1028.png 1272w, https://substackcdn.com/image/fetch/$s_!lW9a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0542714d-99f9-4642-b58e-98ea65f5be7a_2728x1028.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Working of AOF + RDB</strong></figcaption></figure></div><p>Through snapshotting, it eliminates the need to execute all the commands from AOF and only uses the commands executed after snapshotting. This reduces the startup time and also AOF size.</p><p>Further, it minimizes the data loss by logging the executed commands in AOF. Unlike RDB, it doesn&#8217;t lose the commands executed after snapshotting.</p><p>The following are some pros/cons of this approach :-</p><h3>Pros</h3><ol><li><p><strong>Data durability</strong> - Data loss depends on the frequency of executing the <strong>fsync</strong>. Increasing the frequency would lead to less data loss but impact performance.</p></li><li><p><strong>Startup time</strong> - Since it reads the snapshot and then executes commands in AOF, less time is taken during startup as compared to AOF only approach.</p></li><li><p><strong>Performance</strong> - Performance is better since it depends on fsync frequency. Reducing the frequency improves performance (impacts durability).</p></li></ol><h3>Cons</h3><ol><li><p><strong>Complexity</strong> - Loading the rdb snapshot and then applying the AOF commands adds complexity to the process.</p></li></ol><p>Now that you have a good understanding of Redis persistence, let&#8217;s compare the different approaches and look at practical applications of each.</p><h2>AOF vs RDB vs AOF + RDB</h2><p>The following table summarizes the strengths and weaknesses of each of the three approaches.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Tqdf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe680ca2f-e02d-4d5d-a108-a82f2be6077a_1734x998.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Tqdf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe680ca2f-e02d-4d5d-a108-a82f2be6077a_1734x998.png 424w, https://substackcdn.com/image/fetch/$s_!Tqdf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe680ca2f-e02d-4d5d-a108-a82f2be6077a_1734x998.png 848w, https://substackcdn.com/image/fetch/$s_!Tqdf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe680ca2f-e02d-4d5d-a108-a82f2be6077a_1734x998.png 1272w, https://substackcdn.com/image/fetch/$s_!Tqdf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe680ca2f-e02d-4d5d-a108-a82f2be6077a_1734x998.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Tqdf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe680ca2f-e02d-4d5d-a108-a82f2be6077a_1734x998.png" width="1456" height="838" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e680ca2f-e02d-4d5d-a108-a82f2be6077a_1734x998.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:838,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:201487,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/158182042?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe680ca2f-e02d-4d5d-a108-a82f2be6077a_1734x998.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Tqdf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe680ca2f-e02d-4d5d-a108-a82f2be6077a_1734x998.png 424w, https://substackcdn.com/image/fetch/$s_!Tqdf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe680ca2f-e02d-4d5d-a108-a82f2be6077a_1734x998.png 848w, https://substackcdn.com/image/fetch/$s_!Tqdf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe680ca2f-e02d-4d5d-a108-a82f2be6077a_1734x998.png 1272w, https://substackcdn.com/image/fetch/$s_!Tqdf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe680ca2f-e02d-4d5d-a108-a82f2be6077a_1734x998.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Comparison matrix for AOF vs RDB vs AOF+ RDB approaches</strong></figcaption></figure></div><p>Let&#8217;s now look at the practical applications of each of the approaches.</p><h3>AOF</h3><p>AOF is best suited for applications that require strong durability guarantees. Following are some common use cases :-</p><ol><li><p><strong>Financial transactions</strong> - Banking systems, e-commerce payment services, etc.</p></li><li><p><strong>Chat applications</strong> - WhatsApp, Discord, Slack, etc.</p></li><li><p><strong>Stock market applications</strong> - Order books for stock market. Complete state can be reconstructed without data loss. </p></li></ol><h3>RDB</h3><p>RDB enables quick data recovery and minimal performance impact. Also, use cases that don&#8217;t require strong guarantees can opt for RDB. Here are some common practical examples :-</p><ol><li><p>Web application caching - CDN caching, API rate limiting, etc</p></li><li><p>Gaming leaderboards - Online leaderboards showing stats</p></li></ol><h3>AOF + RDB</h3><p>This approach strikes the right balance between performance and durability. Additionally, it speeds up the boot time resulting in better performance than AOF. It can be used for the below use cases :-</p><ol><li><p>Real-time analytics and fraud detection</p></li><li><p>E-commerce product inventory</p></li><li><p>Microservices communication</p></li></ol><h2>Conclusion</h2><p>Redis stores the data in-memory and risks data loss due to crash or restarts. It provides several approaches to prevent data loss and recover after crash.</p><p>The Append-Only File (AOF) uses a log file that contains list of commands executed by Redis sequentially. In case Redis restarts, it reads the file and executes all the commands to recover the full state.</p><p>AOF ensures 0% data loss but impacts the performance. To overcome this challenge, a data persistence technique called RDB (Redis Database) is used.</p><p>Redis takes a snapshot of its memory and stores it in a .rdb binary file. After crash recover, Redis recovers the old state by reading the binary file. However, the data durability is compromised since commands executed after the snapshot aren&#8217;t stored.</p><p>To overcome the performance and durability extremes of the two approaches, AOF and RDB can be combined. This helps balance the performance and durability trade-offs.</p><p>Now that you have understood the data persistence concepts, which technique would you use to <strong>convert Redis into a permanent database</strong> ? Leave your thoughts in the comments below.</p><p>Leave your answers to the above question in the comments below.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/instagram-video-upload-system-design?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&amp;token=eyJ1c2VyX2lkIjoxNDc3NjY4NywicG9zdF9pZCI6MTU1MTQyMzAwLCJpYXQiOjE3NDA5MjQ0MTgsImV4cCI6MTc0MzUxNjQxOCwiaXNzIjoicHViLTg0Njg5Iiwic3ViIjoicG9zdC1yZWFjdGlvbiJ9.BUJF0k1ETEAW5uNXUwAWM5M7bWhnyypp2L5RPo7I5BU&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading Engineering At Scale! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/redis-persistence-aof-rdb-crash-recovery?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/p/redis-persistence-aof-rdb-crash-recovery?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p>Before you go:</p><ul><li><p>&#10084;&#65039; the story and follow the newsletter for more such articles</p></li><li><p>&#128276; Follow me: <a href="https://www.linkedin.com/in/animesh-gaitonde/">LinkedIn</a>, <a href="https://twitter.com/animesh3436">Twitter</a>, <a href="https://medium.com/@animeshgaitonde">Medium</a></p></li><li><p>Your support helps keep this newsletter free and fuels future content. Consider a small donation to show your appreciation here - <a href="https://www.paypal.com/ncp/payment/EUGP54EHQFDZC">Paypal Donate</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[Scaling Distributed Systems with the Scatter-Gather Pattern]]></title><description><![CDATA[What is Scatter-Gather pattern ? How does it work and its applications]]></description><link>https://engineeringatscale.substack.com/p/scaling-distributed-systems-scatter-gather-pattern</link><guid isPermaLink="false">https://engineeringatscale.substack.com/p/scaling-distributed-systems-scatter-gather-pattern</guid><dc:creator><![CDATA[Animesh Gaitonde]]></dc:creator><pubDate>Sat, 15 Feb 2025 11:23:09 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F675b5867-1652-49ec-83e4-62746e6f6d65_1868x1502.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>E-commerce websites like Walmart show the product detail page within 2 seconds. The request is handled by multiple services running on hundreds of servers.</p><p>Similarly, social media products like Instagram, LinkedIn render newsfeed under 2 seconds. The newsfeed contains data such as posts, likes, comments, reposts, etc.</p><p>The above use cases fetch data from multiple services and then show them in a single view. They use a distributed design pattern known as <strong>Scatter-Gather</strong> to solve the problem.</p><p>In this article, we will understand what a Scatter-Gather pattern is. We will walk through some real-world examples of this pattern. Further, we will also explore the relevance of this pattern in designing distributed systems. </p><p>With that, let&#8217;s understand the problem we are trying to solve.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/subscribe?"><span>Subscribe now</span></a></p><h2>Problem Statement</h2><blockquote><p>Design product detail page for an e-commerce website. The backend takes the <strong>productId</strong> as the input and displays a product detail page. </p><p>Also, assume that the website supports millions of users and sells billions of products.</p></blockquote><p>The product detail page consists of the following :-</p><ol><li><p><strong>Product information</strong> - price, name of the product, description, etc.</p></li><li><p><strong>Promotions/Offers</strong> - Any relevant promotions that the seller is providing.</p></li><li><p><strong>Shipping details</strong> - By when the product would be delivered.</p></li><li><p><strong>Reviews</strong> - Reviews posted by other buyers.</p></li><li><p><strong>Warranty details</strong> - Nature of the warranty, duration, etc.</p></li></ol><p>Given the above requirements, let&#8217;s try to design a simple system that meets the requirements. </p><p>We can use a microservices-based architecture for the above website. The microservices would be assigned different responsibilities and expose APIs for fetching the data.</p><p>We would have a frontend server that would talk to the different microservices and get the data. Later, it would construct the page and feed all the data into it. Finally, the page would get rendered on the client device.</p><p>The below diagram shows the system architecture and the overall process. The frontend server calls the microservices sequentially and then sends the client response.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BYg3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74b8bdc9-8780-415d-8a16-93bd867ae755_1922x1518.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BYg3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74b8bdc9-8780-415d-8a16-93bd867ae755_1922x1518.png 424w, https://substackcdn.com/image/fetch/$s_!BYg3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74b8bdc9-8780-415d-8a16-93bd867ae755_1922x1518.png 848w, https://substackcdn.com/image/fetch/$s_!BYg3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74b8bdc9-8780-415d-8a16-93bd867ae755_1922x1518.png 1272w, https://substackcdn.com/image/fetch/$s_!BYg3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74b8bdc9-8780-415d-8a16-93bd867ae755_1922x1518.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BYg3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74b8bdc9-8780-415d-8a16-93bd867ae755_1922x1518.png" width="1456" height="1150" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/74b8bdc9-8780-415d-8a16-93bd867ae755_1922x1518.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1150,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:208811,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!BYg3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74b8bdc9-8780-415d-8a16-93bd867ae755_1922x1518.png 424w, https://substackcdn.com/image/fetch/$s_!BYg3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74b8bdc9-8780-415d-8a16-93bd867ae755_1922x1518.png 848w, https://substackcdn.com/image/fetch/$s_!BYg3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74b8bdc9-8780-415d-8a16-93bd867ae755_1922x1518.png 1272w, https://substackcdn.com/image/fetch/$s_!BYg3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74b8bdc9-8780-415d-8a16-93bd867ae755_1922x1518.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Rendering the product detail page on e-commerce website</strong></figcaption></figure></div><p>Do you see any downsides to the above approach? Take a moment to think and then continue reading.</p><p>Here are some downsides of the current approach :-</p><ol><li><p><strong>Latency</strong> - Grows linearly with the number of microservices. If each service takes 1 sec, then the page would take at least <strong>5 secs</strong> (<strong>5 services</strong>, so <strong>1 sec x 5</strong>) to load. If there are 50 services, then it would become <strong>50 secs</strong>.</p></li><li><p><strong>Efficiency</strong> - When the frontend server calls one service, it waits for the response and wastes CPU cycles. This amplifies with the increase in number of backend services.</p></li><li><p><strong>Fault-tolerance</strong> - The approach introduces dependency between multiple operations. In case a single API fails, it would cause the whole request to fail.</p></li></ol><p>To overcome the above limitations, we use the <strong>Scatter-Gather pattern</strong>. Let&#8217;s understand the concept in detail and how it can solve the current problem.</p><h2>Scatter-Gather pattern</h2><p>As the name suggests, the pattern achieves the following :-</p><ol><li><p><strong>Scatter</strong> - Scatters the requests across multiple backend servers in parallel.</p></li><li><p><strong>Gather</strong> - Gathers or aggregates the data received from the same servers.</p></li></ol><p>The below diagram provides a simple explanation of Scatter-Gather pattern.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vmQ5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4499d56b-cde2-4bdf-a839-1a84c0d14abd_3064x1102.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vmQ5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4499d56b-cde2-4bdf-a839-1a84c0d14abd_3064x1102.png 424w, https://substackcdn.com/image/fetch/$s_!vmQ5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4499d56b-cde2-4bdf-a839-1a84c0d14abd_3064x1102.png 848w, https://substackcdn.com/image/fetch/$s_!vmQ5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4499d56b-cde2-4bdf-a839-1a84c0d14abd_3064x1102.png 1272w, https://substackcdn.com/image/fetch/$s_!vmQ5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4499d56b-cde2-4bdf-a839-1a84c0d14abd_3064x1102.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vmQ5!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4499d56b-cde2-4bdf-a839-1a84c0d14abd_3064x1102.png" width="1200" height="431.86813186813185" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4499d56b-cde2-4bdf-a839-1a84c0d14abd_3064x1102.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:524,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:253988,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vmQ5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4499d56b-cde2-4bdf-a839-1a84c0d14abd_3064x1102.png 424w, https://substackcdn.com/image/fetch/$s_!vmQ5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4499d56b-cde2-4bdf-a839-1a84c0d14abd_3064x1102.png 848w, https://substackcdn.com/image/fetch/$s_!vmQ5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4499d56b-cde2-4bdf-a839-1a84c0d14abd_3064x1102.png 1272w, https://substackcdn.com/image/fetch/$s_!vmQ5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4499d56b-cde2-4bdf-a839-1a84c0d14abd_3064x1102.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Scatter-Gather pattern</strong></figcaption></figure></div><p>Let&#8217;s see how we can apply this pattern to the problem in the previous section.</p><p>We will make the following changes in the previous design :-</p><ol><li><p><strong>Parallel processing</strong> - Instead of sending the request sequentially, it would be sent in parallel to all the backend servers.</p></li><li><p><strong>Aggregation</strong> - The frontend server would wait for the response from all the servers. Once received, it would aggregate and construct the client response.</p></li></ol><p>The following diagram shows how scatter-gather can be leveraged to solve the problem.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!S7UV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F675b5867-1652-49ec-83e4-62746e6f6d65_1868x1502.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!S7UV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F675b5867-1652-49ec-83e4-62746e6f6d65_1868x1502.png 424w, https://substackcdn.com/image/fetch/$s_!S7UV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F675b5867-1652-49ec-83e4-62746e6f6d65_1868x1502.png 848w, https://substackcdn.com/image/fetch/$s_!S7UV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F675b5867-1652-49ec-83e4-62746e6f6d65_1868x1502.png 1272w, https://substackcdn.com/image/fetch/$s_!S7UV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F675b5867-1652-49ec-83e4-62746e6f6d65_1868x1502.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!S7UV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F675b5867-1652-49ec-83e4-62746e6f6d65_1868x1502.png" width="1456" height="1171" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/675b5867-1652-49ec-83e4-62746e6f6d65_1868x1502.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1171,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:207896,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!S7UV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F675b5867-1652-49ec-83e4-62746e6f6d65_1868x1502.png 424w, https://substackcdn.com/image/fetch/$s_!S7UV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F675b5867-1652-49ec-83e4-62746e6f6d65_1868x1502.png 848w, https://substackcdn.com/image/fetch/$s_!S7UV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F675b5867-1652-49ec-83e4-62746e6f6d65_1868x1502.png 1272w, https://substackcdn.com/image/fetch/$s_!S7UV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F675b5867-1652-49ec-83e4-62746e6f6d65_1868x1502.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>E-commerce product page using Scatter-Gather</strong></figcaption></figure></div><p>As seen in the above diagram, the product detail page is fetched in 3 steps. The second step fans out parallel requests to multiple backend services.</p><p>Here&#8217;s how we overcame the limitations of the previous solution through Scatter-Gather:</p><ol><li><p><strong>Latency</strong> - Since the requests are sent in parallel, it wouldn&#8217;t linearly grow with the server growth. If there are 50 services, we would still get the response within 1 sec (<strong>on average</strong>).</p></li><li><p><strong>Efficiency</strong> - Through parallelism, we no longer waste CPU cycles waiting for the backend response. This improves the overall throughput.</p></li><li><p><strong>Fault-tolerance</strong> - Failures can be handled independently and there is no tight dependency between the services. Also, individual API retries don&#8217;t add up to the overall latency due to parallel processing.</p></li></ol><p>Now that you understand the concept of Scatter-Gather, let&#8217;s see a few real-world applications of this pattern.</p><h2>Real-world Application - DynamoDB</h2><p>AWS DynamoDB stores the data internally on multiple storage servers through sharding. It uses Consistent-Hashing to determine the server to store the data on.</p><p>When the client requests multiple keys that reside on different storage servers, DynamoDB uses Scatter-Gather for serving the data.</p><p>The below diagram illustrates an example of how DynamoDB organizes its data and leverages Scatter-Gather.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EjD6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67f4382f-54ad-4497-bc5e-1e54be1ae8db_1902x1268.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EjD6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67f4382f-54ad-4497-bc5e-1e54be1ae8db_1902x1268.png 424w, https://substackcdn.com/image/fetch/$s_!EjD6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67f4382f-54ad-4497-bc5e-1e54be1ae8db_1902x1268.png 848w, https://substackcdn.com/image/fetch/$s_!EjD6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67f4382f-54ad-4497-bc5e-1e54be1ae8db_1902x1268.png 1272w, https://substackcdn.com/image/fetch/$s_!EjD6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67f4382f-54ad-4497-bc5e-1e54be1ae8db_1902x1268.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EjD6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67f4382f-54ad-4497-bc5e-1e54be1ae8db_1902x1268.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/67f4382f-54ad-4497-bc5e-1e54be1ae8db_1902x1268.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:242729,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!EjD6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67f4382f-54ad-4497-bc5e-1e54be1ae8db_1902x1268.png 424w, https://substackcdn.com/image/fetch/$s_!EjD6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67f4382f-54ad-4497-bc5e-1e54be1ae8db_1902x1268.png 848w, https://substackcdn.com/image/fetch/$s_!EjD6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67f4382f-54ad-4497-bc5e-1e54be1ae8db_1902x1268.png 1272w, https://substackcdn.com/image/fetch/$s_!EjD6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67f4382f-54ad-4497-bc5e-1e54be1ae8db_1902x1268.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>DynamoDB - Leveraging Scatter-Gather</strong></figcaption></figure></div><p>Let&#8217;s assume that the client searches for three keys - <em><strong>id1</strong></em>, <em><strong>id2</strong></em> and <em><strong>id3</strong></em>. Here&#8217;s how DynamoDB uses Scatter-Gather behind the scenes :-</p><ol><li><p>DynamoDB front-end server parses the input consisting of the three keys.</p></li><li><p>The front-end server hashes each of the keys.</p></li><li><p>It determines the corresponding backend server for the key. (<strong>id1</strong> - <em>server1</em>, <strong>id2</strong> - <em>server2</em>, <strong>id3</strong> - <em>server3</em>)</p></li><li><p>It sends a parallel request to each of the servers and performs a lookup.</p></li><li><p>Finally, the three servers send the data corresponding to the keys.</p></li><li><p>The front-end server aggregates the data and sends it in the response.</p></li></ol><p>A similar pattern is used by other NoSQL databases such as Cassandra, MongoDB, Elasticsearch, etc.</p><h2>Challenges in implementing Scatter-Gather</h2><p>While Scatter-Gather pattern helps in building and scaling large-scale systems, it has its own set of challenges. Here are some challenges in implementing the pattern :-</p><ul><li><p><strong>Failure handling</strong> - It&#8217;s essential to handle the failures gracefully. Since multiple services are involved, hardware failures, deployments, etc are common. These must be overcome through redundancy and replication.</p></li><li><p><strong>Data accuracy</strong> - Backend services might use different data sources and present inaccurate data. It&#8217;s essential to resolve such discrepancies before sending the client response.</p></li><li><p><strong>Number of backend servers</strong> - We can&#8217;t infinitely increase the backend servers. Each request incurs a network call, parsing operations, and additional overhead. With more backend servers, the additional overhead reduces the benefits of parallel processing. So, we need to choose the backend servers wisely.</p></li><li><p><strong>Incomplete data</strong> - A backend service might fail to return data. In such cases, the system must use a fallback mechanism for the incomplete data. For eg:- In case of an e-commerce product, it can show default promotions if the Promotion service fails.</p></li><li><p><strong>Latency</strong> - The overall latency is influenced by the slowest backend server. It&#8217;s essential to define an upper bound on the latency (SLA) so that it doesn&#8217;t impact the user experience.</p></li></ul><h2>Conclusion</h2><p>Scatter-Gather pattern is one of the building blocks of modern distributed systems. Its applications range from <strong>distributed databases</strong> to <strong>social media feeds</strong> and <strong>e-commerce websites</strong>.</p><p>With parallel processing and aggregation, it helps solve :-</p><ol><li><p>Faster response times through reduced latency.</p></li><li><p>Efficient horizontal scaling.</p></li><li><p>Graceful handling of partial failures.</p></li><li><p>High-throughput processing for large-scale applications.</p></li></ol><p>However, <strong>Scatter-Gather comes with trade-offs</strong>&#8212;its added complexity is only justified when performance gains outweigh implementation challenges. For simpler cases, such as retrieving data for multiple users, a single API call may be sufficient.</p><p>Have you used Scatter-Gather before? What challenges did you face? Let&#8217;s discuss in the comments!!</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/scaling-distributed-systems-scatter-gather-pattern?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading Engineering At Scale! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/scaling-distributed-systems-scatter-gather-pattern?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/p/scaling-distributed-systems-scatter-gather-pattern?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p>Before you go:</p><ul><li><p>&#10084;&#65039; the story and follow the newsletter for more such articles</p></li><li><p>&#128276; Follow me: <a href="https://www.linkedin.com/in/animesh-gaitonde/">LinkedIn</a>, <a href="https://twitter.com/animesh3436">Twitter</a>, <a href="https://medium.com/@animeshgaitonde">Medium</a></p></li><li><p>Your support helps keep this newsletter free and fuels future content. Consider a small donation to show your appreciation here - <a href="https://www.paypal.com/ncp/payment/EUGP54EHQFDZC">Paypal Donate</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[Designing Instagram's Video Uploads: Optimizing for Low Latency and scalability]]></title><description><![CDATA[System Design, Architecture, and Trade-offs in Building a Video Upload Service]]></description><link>https://engineeringatscale.substack.com/p/instagram-video-upload-system-design</link><guid isPermaLink="false">https://engineeringatscale.substack.com/p/instagram-video-upload-system-design</guid><dc:creator><![CDATA[Animesh Gaitonde]]></dc:creator><pubDate>Mon, 20 Jan 2025 04:56:41 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc302e0a-69cd-4847-a531-29367dd1df38_2752x1192.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Have you wondered how Instagram handles millions of video uploads daily ?</p><p>How does it make the uploaded video available for consumption within seconds ?</p><p>Instagram Engineers have built a robust and scalable Video Upload Service that abstracts the complexity of video upload and processing. </p><p>In this article, we will to design and architect one such service. We will tackle the problem starting with a simple solution. We will identify the bottlenecks, iterate and optimize the solution.</p><p>By the end, you will learn the core challenges and tradeoffs done while building a reliable, scalable and an efficient video upload service. You&#8217;ll gain key skills to tackle a similar problem in your next system design interview.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/subscribe?"><span>Subscribe now</span></a></p><p>With that, let&#8217;s revisit our fundamental video processing concepts that were discussed in the <a href="https://engineeringatscale.substack.com/p/unraveling-the-internals-of-video">last edition of this newsletter</a>.</p><div><hr></div><h2>Boost Your Skills with Educative (Plus an Extra 10% Discount!)</h2><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZXi2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0506b31e-b56e-4917-8ae0-d44360b0fe79_318x159.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZXi2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0506b31e-b56e-4917-8ae0-d44360b0fe79_318x159.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ZXi2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0506b31e-b56e-4917-8ae0-d44360b0fe79_318x159.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ZXi2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0506b31e-b56e-4917-8ae0-d44360b0fe79_318x159.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ZXi2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0506b31e-b56e-4917-8ae0-d44360b0fe79_318x159.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZXi2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0506b31e-b56e-4917-8ae0-d44360b0fe79_318x159.jpeg" width="318" height="159" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0506b31e-b56e-4917-8ae0-d44360b0fe79_318x159.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:159,&quot;width&quot;:318,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:5214,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/155142300?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0506b31e-b56e-4917-8ae0-d44360b0fe79_318x159.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ZXi2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0506b31e-b56e-4917-8ae0-d44360b0fe79_318x159.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ZXi2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0506b31e-b56e-4917-8ae0-d44360b0fe79_318x159.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ZXi2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0506b31e-b56e-4917-8ae0-d44360b0fe79_318x159.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ZXi2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0506b31e-b56e-4917-8ae0-d44360b0fe79_318x159.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Ace your coding interviews with Educative&#8217;s proven prep paths used by engineers at <strong>Google</strong>, <strong>Amazon</strong>, and <strong>Meta</strong>.<br>Get an exclusive <strong>10% discount</strong> when you sign up through this <strong><a href="https://www.educative.io/unlimited?aff=BYJl">link</a></strong>.<br>No setup, no distractions &#8212; just structured learning, real problems, and smart solutions.</p><div><hr></div><h2>Video processing fundamentals</h2><p>Videos go through six phases before they are available for user consumption. The below diagram illustrates the process. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JCvx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1d6ee4d-9164-467e-a94f-26fa0ba8bd23_3286x1250.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JCvx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1d6ee4d-9164-467e-a94f-26fa0ba8bd23_3286x1250.png 424w, https://substackcdn.com/image/fetch/$s_!JCvx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1d6ee4d-9164-467e-a94f-26fa0ba8bd23_3286x1250.png 848w, https://substackcdn.com/image/fetch/$s_!JCvx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1d6ee4d-9164-467e-a94f-26fa0ba8bd23_3286x1250.png 1272w, https://substackcdn.com/image/fetch/$s_!JCvx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1d6ee4d-9164-467e-a94f-26fa0ba8bd23_3286x1250.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JCvx!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1d6ee4d-9164-467e-a94f-26fa0ba8bd23_3286x1250.png" width="1200" height="456.5934065934066" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d1d6ee4d-9164-467e-a94f-26fa0ba8bd23_3286x1250.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:554,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:234162,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!JCvx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1d6ee4d-9164-467e-a94f-26fa0ba8bd23_3286x1250.png 424w, https://substackcdn.com/image/fetch/$s_!JCvx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1d6ee4d-9164-467e-a94f-26fa0ba8bd23_3286x1250.png 848w, https://substackcdn.com/image/fetch/$s_!JCvx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1d6ee4d-9164-467e-a94f-26fa0ba8bd23_3286x1250.png 1272w, https://substackcdn.com/image/fetch/$s_!JCvx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1d6ee4d-9164-467e-a94f-26fa0ba8bd23_3286x1250.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Video upload and processing steps</strong></figcaption></figure></div><p>Video viewers use different applications and devices for playing videos. Similarly, their network bandwidth also varies.</p><p>Hence, it&#8217;s essential to convert a video into several formats and also vary the bitrate for compatibility. For eg:- A <strong>1080p</strong> video may not render as expected on slow internet connection. So, it must be converted into a format like <strong>240p</strong> or <strong>144p</strong>.</p><p>In the video processing step, the system re-encodes the video into multiple formats. Besides, the step also performs operations such as watermarking, thumbnail generation, encryption, etc.</p><p>As seen from the above diagram, the video processing step can be modelled as a <strong>Directed Acyclic Graph</strong> (<strong>DAG</strong>). Each node in the DAG represents an operation and the vertices indicate data flow.</p><p>Now that you know the basics, let&#8217;s design a service that uploads and processes videos.</p><h2>Problem Statement</h2><blockquote><p>Design a scalable, efficient and a reliable video upload and processing service</p></blockquote><p>Let&#8217;s break down the problem statement into functional and non-functional requirements. </p><h3>Functional Requirements</h3><ol><li><p>Users must be able to upload the videos</p></li><li><p>The system must process and generate multiple video formats. It must include functionalities such as watermarking, encryption, etc.</p></li><li><p>Users must be able to upload the videos through channels like messages, stories, and posts.</p></li></ol><p>Let&#8217;s define the non-functional requirements in the context of each functional requirement.</p><h3>Non-functional Requirements</h3><ol><li><p>System must <strong>scale</strong> to handle millions of concurrent uploads.</p></li><li><p>Upload and processing p90 <strong>latency</strong> must be within 10 secs. (It would make the experience interactive)</p></li><li><p>It must be <strong>fault-tolerant</strong> and <strong>reliably</strong> recover from any failures.</p></li></ol><p>Given clear requirements, we will now come up with a simple design that meets them.</p><h2>Approach 1 - Synchronous solution</h2><p>In this approach, the client uploads the video and it gets stored in a blob storage. The video then gets processed by the backend <strong>Video Processing Service</strong>.</p><p>The following diagram shows the end to end process.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DHaJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3447eafc-f313-4461-bdf3-c9ccb08d4898_1678x844.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DHaJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3447eafc-f313-4461-bdf3-c9ccb08d4898_1678x844.png 424w, https://substackcdn.com/image/fetch/$s_!DHaJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3447eafc-f313-4461-bdf3-c9ccb08d4898_1678x844.png 848w, https://substackcdn.com/image/fetch/$s_!DHaJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3447eafc-f313-4461-bdf3-c9ccb08d4898_1678x844.png 1272w, https://substackcdn.com/image/fetch/$s_!DHaJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3447eafc-f313-4461-bdf3-c9ccb08d4898_1678x844.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DHaJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3447eafc-f313-4461-bdf3-c9ccb08d4898_1678x844.png" width="1456" height="732" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3447eafc-f313-4461-bdf3-c9ccb08d4898_1678x844.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:732,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:137500,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!DHaJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3447eafc-f313-4461-bdf3-c9ccb08d4898_1678x844.png 424w, https://substackcdn.com/image/fetch/$s_!DHaJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3447eafc-f313-4461-bdf3-c9ccb08d4898_1678x844.png 848w, https://substackcdn.com/image/fetch/$s_!DHaJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3447eafc-f313-4461-bdf3-c9ccb08d4898_1678x844.png 1272w, https://substackcdn.com/image/fetch/$s_!DHaJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3447eafc-f313-4461-bdf3-c9ccb08d4898_1678x844.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Synchronous solution</strong></figcaption></figure></div><p>While the solution is easy to understand and simple to manager, would it scale ?</p><p>Before reading further, take a pause to think where it would fail to meet the our goals. </p><p>Here&#8217;s why the solution wouldn&#8217;t scale :-</p><ol><li><p><strong>Reliability &amp; Fault tolerance</strong> - In case of video processing failure, the client would have to restart the whole process. Even if one of the operation (for eg:- watermarking) fails, the whole step needs to be retried. This compromises the service reliability.</p></li><li><p><strong>Latency</strong> - Video processing time is proportional to the length of the video. Due to sequential processing, large video files would take a long time. It would take hours if not minutes for few large files (more than <strong>200 MB</strong>). </p></li><li><p><strong>Scalability </strong>- Given the sequential nature, a given server would be able to handle only limited number of requests. Increasing the instances would result in higher costs.</p></li><li><p><strong>Efficiency</strong> - The solution performs compute-heavy video transcoding operations in sequence. It doesn&#8217;t exploit parallel processing which makes it inefficient.</p></li></ol><p>Since we now know the downsides of the synchronous solution, let&#8217;s think of improving this one step at a time.</p><h2>Approach 2 - Asynchronous solution</h2><p>We can improve the solution in the previous section by making the backend video processing asynchronous. </p><p>The compute-heavy video transcoding can be decoupled from the uploading and pre-processing steps (video file validation, repairing malformed files, etc). This decoupling would allow both the layers to scale independently and robustly handle failures.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ar4k!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74496c5e-8983-4b1a-adfb-4ce3ce321dc5_2498x1144.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ar4k!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74496c5e-8983-4b1a-adfb-4ce3ce321dc5_2498x1144.png 424w, https://substackcdn.com/image/fetch/$s_!ar4k!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74496c5e-8983-4b1a-adfb-4ce3ce321dc5_2498x1144.png 848w, https://substackcdn.com/image/fetch/$s_!ar4k!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74496c5e-8983-4b1a-adfb-4ce3ce321dc5_2498x1144.png 1272w, https://substackcdn.com/image/fetch/$s_!ar4k!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74496c5e-8983-4b1a-adfb-4ce3ce321dc5_2498x1144.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ar4k!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74496c5e-8983-4b1a-adfb-4ce3ce321dc5_2498x1144.png" width="1456" height="667" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/74496c5e-8983-4b1a-adfb-4ce3ce321dc5_2498x1144.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:667,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:261628,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ar4k!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74496c5e-8983-4b1a-adfb-4ce3ce321dc5_2498x1144.png 424w, https://substackcdn.com/image/fetch/$s_!ar4k!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74496c5e-8983-4b1a-adfb-4ce3ce321dc5_2498x1144.png 848w, https://substackcdn.com/image/fetch/$s_!ar4k!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74496c5e-8983-4b1a-adfb-4ce3ce321dc5_2498x1144.png 1272w, https://substackcdn.com/image/fetch/$s_!ar4k!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74496c5e-8983-4b1a-adfb-4ce3ce321dc5_2498x1144.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Asynchronous solution using Scheduler &amp; workers</strong></figcaption></figure></div><p>The above diagram shows the new architecture. Let&#8217;s dive into the key changes introduced in the design.</p><p>Here&#8217;s how the video transcoding can be handled :-</p><ol><li><p><strong>Scheduler</strong> - Scheduler would be responsible for orchestrating the video processing step (<strong>DAG</strong>). It would manage and co-ordinate the work of several worker instances.</p></li><li><p><strong>Workers</strong> - These server instances would perform operations such as transcoding, watermarking, etc. They would be independent and inform the scheduler on completion of task.</p></li></ol><p>The communication between Scheduler and Worker would take place via <strong>message queue</strong>.</p><p>This solution addresses the primary bottlenecks of the previous solution as follows :-</p><ol><li><p><strong>Reliability &amp; Fault-tolerance</strong> - The whole video upload process doesn&#8217;t need to be retried in case of failures. Individual processing operations can be retried either by scheduler or worker.</p></li><li><p><strong>Scalability</strong> - The async process with workers make it easy to scale the processing step. Similarly, the upload &amp; pre-processing steps can be scaled independently.</p></li><li><p><strong>Efficiency</strong> - Unlike the previous approach, two or more transcoding operations can be performed on multiple worker machines in parallel.</p></li></ol><p>While this approach introduces excellent improvements, it comes with the following downsides -</p><ul><li><p><strong>Latency</strong> - The overall latency doesn&#8217;t significantly improve since it&#8217;s dependent on successful completion of all the individual processing steps.</p></li><li><p><strong>Critical operations</strong> -  The scheduler doesn&#8217;t identify and prioritize critical operations and non-critical operations (like video analytics). This further impacts the latency.</p></li></ul><p>Let&#8217;s see how we can make this solution better. </p><h3>Optimizations</h3><p>We can further improve the process by :-</p><ol><li><p><strong>Latency</strong> - The video can be made available once the highest resolution is available. Hence, the system doesn&#8217;t need to wait for all the resolutions to be available.</p></li><li><p><strong>Critical operations</strong> - The Scheduler can have two different queues for the asks - critical and non-critical. Latency sensitive tasks can be added in the critical queue while others can go in the non-critical one.</p></li></ol><p>Although the above solution reduces the latency to an extent but the clients on slow networks wouldn&#8217;t be able to load high resolution videos. This would compromise the experience for clients with limited bandwidth.</p><p>This is an acceptable tradeoff since we expect all the resolutions to be available within couple of minutes. And the percentage of people with poor internet connection is less (&lt; 10%).</p><p>Can you further improve the design and optimize it ? Before proceeding to the next section, take a moment to identify ways to tackle the problem.</p><h2>Approach 3 - Asynchronous processing with Segmented video upload</h2><p>In the previous two approaches, the video processing starts once the file upload completes. The longer the upload time, higher would be the overall latency. </p><p>Instead of waiting for the full file to be uploaded, what if we upload segments of the file ? Would that reduce the overall latency ? </p><p>The answer to the above question is <strong>Yes</strong>. The video file can be divided into a sequence of continuous segments known as <strong>Group of Pictures</strong> (<strong>GOP</strong>). Clients can upload the segments in parallel.</p><p>Further, each GOP segment can be encoded and processed independently. So, they can be processed in parallel and eventually stitched into a complete video.</p><p>We have reduced the overall latency using two techniques :-</p><ol><li><p>Overlapping upload and processing through segmentation.</p></li><li><p>Parallel processing of individual segments.</p></li></ol><p>The below diagram shows the overall architecture which meets our functional and non-functional requirements.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iG0t!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc302e0a-69cd-4847-a531-29367dd1df38_2752x1192.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iG0t!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc302e0a-69cd-4847-a531-29367dd1df38_2752x1192.png 424w, https://substackcdn.com/image/fetch/$s_!iG0t!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc302e0a-69cd-4847-a531-29367dd1df38_2752x1192.png 848w, https://substackcdn.com/image/fetch/$s_!iG0t!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc302e0a-69cd-4847-a531-29367dd1df38_2752x1192.png 1272w, https://substackcdn.com/image/fetch/$s_!iG0t!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc302e0a-69cd-4847-a531-29367dd1df38_2752x1192.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iG0t!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc302e0a-69cd-4847-a531-29367dd1df38_2752x1192.png" width="1200" height="520.054945054945" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cc302e0a-69cd-4847-a531-29367dd1df38_2752x1192.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:631,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:347788,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!iG0t!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc302e0a-69cd-4847-a531-29367dd1df38_2752x1192.png 424w, https://substackcdn.com/image/fetch/$s_!iG0t!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc302e0a-69cd-4847-a531-29367dd1df38_2752x1192.png 848w, https://substackcdn.com/image/fetch/$s_!iG0t!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc302e0a-69cd-4847-a531-29367dd1df38_2752x1192.png 1272w, https://substackcdn.com/image/fetch/$s_!iG0t!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc302e0a-69cd-4847-a531-29367dd1df38_2752x1192.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Video upload and processing architecture</strong></figcaption></figure></div><p>Let&#8217;s now understand few tradeoffs of the final solution.</p><h3>Tradeoffs</h3><h4>Stitching step</h4><p>The final stitching step that combines all the segments together adds complexity to the pipeline. However, the benefits of parallel processing outweigh the downsides of stitching step.</p><h4>Small video files</h4><p>For small video files ( &lt; 10 MB), there isn&#8217;t an additional advantage of segmented upload and parallel processing. Since it&#8217;s an overkill, such files can be separately processed through a separate pipeline.</p><h4>Segment size</h4><p>Compression algorithms exploit temporal locality of large segments and lead to better compressions. Higher segment sizes result in less number of segments and reduce the degree of parallelism. </p><p>Hence, the segment size needs to be adjusted based on the expected video quality. Higher quality videos (reels, stories) can use more segment size. While use cases like videos shared via messages can use less segment size.</p><h4>Client-side bandwidth constraints</h4><p>In certain cases, the clients may have poor connectivity. In such cases, the video processing can be done on the client side (provided it&#8217;s supported by client devices). Client-side processing reduces the file size and helps with faster video uploads.</p><h2>Conclusion</h2><p>In this article, we learnt the system design and  architecture of a Video upload service. We started with a naive solution and iteratively improved by identifying the bottlenecks.</p><p>Here&#8217;s a quick summary of how to build a scalable, reliable and a robust video upload service :-</p><ol><li><p><strong>Segmented upload</strong> - Break the video into segments and upload each segment. Further, upload and process each segment in parallel.</p></li><li><p><strong>Parallelism</strong> - Use parallelism to execute the compute-heavy operations.</p></li><li><p><strong>Critical vs Non-critical operations</strong> - Segregate critical and non-critical operations. Prioritize the critical operations while scaling the system.</p></li><li><p><strong>Fault-tolerance</strong> - Ensure that the system robustly recovers from failures in individual steps through retries.</p></li></ol><p>Before you leave, take this question as an exercise - </p><div class="pullquote"><p>What would happen if the Video upload service receives a surge of video uploads (<strong>10x traffic</strong> due to some event) ? How would the system scale ?</p></div><p>Leave your answers to the above question in the comments below.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/instagram-video-upload-system-design?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading Engineering At Scale! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/instagram-video-upload-system-design?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/p/instagram-video-upload-system-design?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p>Before you go:</p><ul><li><p>&#10084;&#65039; the story and follow the newsletter for more such articles</p></li><li><p>&#128276; Follow me: <a href="https://www.linkedin.com/in/animesh-gaitonde/">LinkedIn</a>, <a href="https://twitter.com/animesh3436">Twitter</a>, <a href="https://medium.com/@animeshgaitonde">Medium</a></p></li><li><p>Your support helps keep this newsletter free and fuels future content. Consider a small donation to show your appreciation here - <a href="https://www.paypal.com/ncp/payment/EUGP54EHQFDZC">Paypal Donate</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[Zerodha's Innovative Hack: Scaling Reporting with 7 Million PostgreSQL Tables]]></title><description><![CDATA[How Zerodha scaled its reporting layer through a PostgrSQL hack ?]]></description><link>https://engineeringatscale.substack.com/p/zerodha-seven-million-postgresql-tables</link><guid isPermaLink="false">https://engineeringatscale.substack.com/p/zerodha-seven-million-postgresql-tables</guid><dc:creator><![CDATA[Animesh Gaitonde]]></dc:creator><pubDate>Thu, 09 Jan 2025 04:33:50 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74a959cb-1661-4d0a-9cc9-a8a45a045c38_2478x1114.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Zerodha created 7 million PostgreSQL tables to scale its reporting architecture. Yes, you heard it right. It&#8217;s <strong>7 million tables  </strong>and not <strong>7 million table records</strong>.</p><p>In this article, we will understand in detail the challenges and Zerodha&#8217;s innovative approach to tackle the problem.</p><blockquote><h3><strong>Sidenote: What is Zerodha ?</strong> </h3><p>Zerodha is India&#8217;s largest stockbroker. It&#8217;s the first discount broker and has a vision to make trading/investing for retail investors. </p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/subscribe?"><span>Subscribe now</span></a></p><h2>Use cases</h2><p>Zerodha users purchase different securities such as stocks, ETFs, Mutual Funds, Futures, Options, etc. The platform must generate reports for different user queries like :-</p><ol><li><p>Profit and loss for the past day/month/year.</p></li><li><p>Transactions done over a given period.</p></li><li><p>Tax summary for the past financial year</p></li><li><p>Summary of dividends, bonus shares, stock splits, etc</p></li></ol><p>Zerodha offers its users a platform known as <strong>Console</strong> to view the different reports. Let&#8217;s now understand how the platform was built originally.</p><h2>Old architecture</h2><p>Zerodha used a variety of databases such as PostgreSQL, MySQL, and ClickHouse to manage the user data. In the old architecture, the backend web server executed queries on the database and returned the results to the clients.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zr-7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc131fcb-c04c-437a-ba58-6ee0281ba58f_1936x682.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zr-7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc131fcb-c04c-437a-ba58-6ee0281ba58f_1936x682.png 424w, https://substackcdn.com/image/fetch/$s_!zr-7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc131fcb-c04c-437a-ba58-6ee0281ba58f_1936x682.png 848w, https://substackcdn.com/image/fetch/$s_!zr-7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc131fcb-c04c-437a-ba58-6ee0281ba58f_1936x682.png 1272w, https://substackcdn.com/image/fetch/$s_!zr-7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc131fcb-c04c-437a-ba58-6ee0281ba58f_1936x682.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zr-7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc131fcb-c04c-437a-ba58-6ee0281ba58f_1936x682.png" width="1456" height="513" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cc131fcb-c04c-437a-ba58-6ee0281ba58f_1936x682.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:513,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:113885,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zr-7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc131fcb-c04c-437a-ba58-6ee0281ba58f_1936x682.png 424w, https://substackcdn.com/image/fetch/$s_!zr-7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc131fcb-c04c-437a-ba58-6ee0281ba58f_1936x682.png 848w, https://substackcdn.com/image/fetch/$s_!zr-7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc131fcb-c04c-437a-ba58-6ee0281ba58f_1936x682.png 1272w, https://substackcdn.com/image/fetch/$s_!zr-7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc131fcb-c04c-437a-ba58-6ee0281ba58f_1936x682.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Old architecture</strong></figcaption></figure></div><p>The above architecture couldn&#8217;t scale with the growth in user and transaction volume. Here&#8217;s why the platform couldn&#8217;t scale :- </p><ul><li><p>Database table stored more than a billion records.</p></li><li><p>Cross-table joins slowed the query execution.</p></li><li><p>Users had different query patterns each having a different execution time.</p></li></ul><p>As a result, users experienced timeouts or slow processing. This resulted in a poor user experience and wouldn&#8217;t scale in the long-term.</p><p>The problem amplified during the tax filing period where <strong>millions of users</strong> simultaneously tried downloading last year&#8217;s report. </p><p>To overcome the inefficiencies of synchronous processing, Zerodha decided to move to an async model. We will now see the working of async model.</p><h2>Async workflow</h2><p>In the async model, the users submitted their request. The platform acknowledged their request and the users came back after couple of mins, secs to find their result.</p><p>This model overcame the limitations of the synchronous approach. It resulted in huge improvements in the user experience.</p><p>The async model made sense as every user query had different execution time depending on the use case. 99% users wanted to view transactions done in last year, while remaining 1% were interested in 10 year old transactions.</p><p>User query patterns vary. Many users are interested in seeing the transactions done in the past 1 year. A handful of users are interested in viewing last 10 years transactions.</p><p>Here&#8217;s how the async model worked :-</p><ol><li><p>Clients submitted their requests to the backend.</p></li><li><p>The backend queued the request as a job.</p></li><li><p>The jobs were executed by running database queries.</p></li><li><p>Clients polled for the job&#8217;s status.</p></li><li><p>On job completion, the users downloaded the result in the form of reports.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MR8D!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8868c0d6-666a-4a47-95f2-08ad5f9b37c0_2692x654.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MR8D!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8868c0d6-666a-4a47-95f2-08ad5f9b37c0_2692x654.png 424w, https://substackcdn.com/image/fetch/$s_!MR8D!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8868c0d6-666a-4a47-95f2-08ad5f9b37c0_2692x654.png 848w, https://substackcdn.com/image/fetch/$s_!MR8D!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8868c0d6-666a-4a47-95f2-08ad5f9b37c0_2692x654.png 1272w, https://substackcdn.com/image/fetch/$s_!MR8D!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8868c0d6-666a-4a47-95f2-08ad5f9b37c0_2692x654.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MR8D!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8868c0d6-666a-4a47-95f2-08ad5f9b37c0_2692x654.png" width="1456" height="354" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8868c0d6-666a-4a47-95f2-08ad5f9b37c0_2692x654.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:354,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:166193,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!MR8D!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8868c0d6-666a-4a47-95f2-08ad5f9b37c0_2692x654.png 424w, https://substackcdn.com/image/fetch/$s_!MR8D!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8868c0d6-666a-4a47-95f2-08ad5f9b37c0_2692x654.png 848w, https://substackcdn.com/image/fetch/$s_!MR8D!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8868c0d6-666a-4a47-95f2-08ad5f9b37c0_2692x654.png 1272w, https://substackcdn.com/image/fetch/$s_!MR8D!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8868c0d6-666a-4a47-95f2-08ad5f9b37c0_2692x654.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption"><strong>Async workflow</strong></figcaption></figure></div><p>Zerodha discovered a hack in PostgreSQL to further optimize the process. This hack worked in tandem with asynchronous workflow to scale the system.</p><p>Let&#8217;s now understand the new architecture in detail.</p><h2>New architecture</h2><p>The new architecture consisted of two flows :-</p><ol><li><p><strong>Async flow</strong> - In this flow, user requests were executed by running database queries. On successful execution, the results were stored in an <strong>ephemeral</strong> PostgreSQL database.</p></li><li><p><strong>Sync flow</strong> - On completion of async flow, the ephemeral PostgreSQL database was queried to fetch the reports.</p></li></ol><p>In the async flow, a middleware named Dungbeetle was introduced. This middleware handled the user requests and modelled it as a job.</p><p>Dungbeetle managed the job&#8217;s lifecycle and moved the results of the database queries to the PostgreSQL instance also called the result cache.</p><p>Every query result was mapped to a database table. Running millions of such queries resulted in more than <strong>7 million</strong> tables daily. And PostgreSQL supports creation of million tables.</p><p>The below diagram shows the new scaleable reporting architecture.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!i_52!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74a959cb-1661-4d0a-9cc9-a8a45a045c38_2478x1114.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!i_52!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74a959cb-1661-4d0a-9cc9-a8a45a045c38_2478x1114.png 424w, https://substackcdn.com/image/fetch/$s_!i_52!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74a959cb-1661-4d0a-9cc9-a8a45a045c38_2478x1114.png 848w, https://substackcdn.com/image/fetch/$s_!i_52!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74a959cb-1661-4d0a-9cc9-a8a45a045c38_2478x1114.png 1272w, https://substackcdn.com/image/fetch/$s_!i_52!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74a959cb-1661-4d0a-9cc9-a8a45a045c38_2478x1114.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!i_52!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74a959cb-1661-4d0a-9cc9-a8a45a045c38_2478x1114.png" width="1456" height="655" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/74a959cb-1661-4d0a-9cc9-a8a45a045c38_2478x1114.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:655,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:227116,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!i_52!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74a959cb-1661-4d0a-9cc9-a8a45a045c38_2478x1114.png 424w, https://substackcdn.com/image/fetch/$s_!i_52!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74a959cb-1661-4d0a-9cc9-a8a45a045c38_2478x1114.png 848w, https://substackcdn.com/image/fetch/$s_!i_52!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74a959cb-1661-4d0a-9cc9-a8a45a045c38_2478x1114.png 1272w, https://substackcdn.com/image/fetch/$s_!i_52!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74a959cb-1661-4d0a-9cc9-a8a45a045c38_2478x1114.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Zerodha&#8217;s new reporting architecture</strong></figcaption></figure></div><p>The ephemeral database was purged daily and it only stored the temporary results. Further, since this result cache had handful of records (~<strong>1000-5000</strong>), users could easily perform filter, and sort operations.</p><p>Zerodha&#8217;s CTO Kailash Nadh mentioned that the solution started out as a hack but has turned into an abuse.</p><blockquote><p>There&#8217;s a thin line between a clever software hack and an outrageous abuse.</p></blockquote><p>Would the solution scale if Zerodha witnesses a 10x user growth in future ? In my opinion, it may not. </p><p>Increasing the table count would reach a plateau at some point. And eventually slow the query execution after hitting a limit. </p><p>So, let&#8217;s see what alternatives can be considered here.</p><h2>Alternative solutions</h2><p>Here are few alternatives to the million table solution :-</p><h3>Columnar database like Amazon Redshift/Apache Druid</h3><p>These databases are optimized for analytical queries. Following are few advantages of this solution :-</p><ol><li><p>Supports long running large-scale analytical queries.</p></li><li><p>High compression and faster query performance on large datasets.</p></li><li><p>Eliminates the need for millions of tables.</p></li></ol><p>However, the team would have to invest in a separate data pipeline to move the data from transactional or online systems.</p><h3>Pre-compute and object storage</h3><p>The reports can be generated asynchronously and stored in an object store like AWS S3. Here&#8217;s how it would benefit :-</p><ol><li><p>Highly scalable, cost-effective storage for large volumes of reports.</p></li><li><p>Users can download the reports without hitting the database.</p></li></ol><p>But, users won&#8217;t be able to perform operations such as filtering or sorting on the result set.</p><h2>Conclusion</h2><p>Zerodha started with a basic architecture for user report generation. The solution couldn&#8217;t scale with the growth in users and transaction volume.</p><p>The architecture was based on synchronous processing and couldn&#8217;t handle peak workloads such as report generation during tax filing.</p><p>The synchronous architecture was replaced with an async one to make the process more robust. In the async flow, the middleware executed the database queries and moved the data to an ephemeral PostgreSQL database.</p><p>Since every query result was mapped to a new database, it lead to creation of more than <strong>7 million tables</strong>. Although it was a hack, but the solution scaled for millions of users.</p><p>Can you think of any other alternative solutions to solve the problem ? Post your thoughts in the comments below.</p><p>You can refer <a href="https://www.youtube.com/watch?v=4TE1xErXwGc">this</a> talk by Zerodha&#8217;s CTO for more details on the innovative solution.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/zerodha-seven-million-postgresql-tables?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/p/zerodha-seven-million-postgresql-tables?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p>Before you go:</p><ul><li><p>&#10084;&#65039; the story and follow the newsletter for more such articles</p></li><li><p>&#128276; Follow me: <a href="https://www.linkedin.com/in/animesh-gaitonde/">LinkedIn</a>, <a href="https://twitter.com/animesh3436">Twitter</a>, <a href="https://medium.com/@animeshgaitonde">Medium</a></p></li><li><p>Your support helps keep this newsletter free and fuels future content. Consider a small donation to show your appreciation here - <a href="https://www.paypal.com/ncp/payment/EUGP54EHQFDZC">Paypal Donate</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[Unraveling the Internals of Video Streaming services]]></title><description><![CDATA[A comprehensive guide to key concepts, terminologies and working of Video Streaming apps]]></description><link>https://engineeringatscale.substack.com/p/unraveling-the-internals-of-video</link><guid isPermaLink="false">https://engineeringatscale.substack.com/p/unraveling-the-internals-of-video</guid><dc:creator><![CDATA[Animesh Gaitonde]]></dc:creator><pubDate>Sun, 22 Dec 2024 12:35:54 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!-Xdd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4db326-4431-41e2-b877-a548045a3b36_1420x1202.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-Xdd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4db326-4431-41e2-b877-a548045a3b36_1420x1202.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-Xdd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4db326-4431-41e2-b877-a548045a3b36_1420x1202.png 424w, https://substackcdn.com/image/fetch/$s_!-Xdd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4db326-4431-41e2-b877-a548045a3b36_1420x1202.png 848w, https://substackcdn.com/image/fetch/$s_!-Xdd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4db326-4431-41e2-b877-a548045a3b36_1420x1202.png 1272w, https://substackcdn.com/image/fetch/$s_!-Xdd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4db326-4431-41e2-b877-a548045a3b36_1420x1202.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-Xdd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4db326-4431-41e2-b877-a548045a3b36_1420x1202.png" width="1420" height="1202" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dd4db326-4431-41e2-b877-a548045a3b36_1420x1202.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1202,&quot;width&quot;:1420,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:401642,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-Xdd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4db326-4431-41e2-b877-a548045a3b36_1420x1202.png 424w, https://substackcdn.com/image/fetch/$s_!-Xdd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4db326-4431-41e2-b877-a548045a3b36_1420x1202.png 848w, https://substackcdn.com/image/fetch/$s_!-Xdd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4db326-4431-41e2-b877-a548045a3b36_1420x1202.png 1272w, https://substackcdn.com/image/fetch/$s_!-Xdd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4db326-4431-41e2-b877-a548045a3b36_1420x1202.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Video Streaming Concepts</strong></figcaption></figure></div><p>The video streaming industry has grown rapidly over the last decade and now makes up 82.5% of global internet traffic. It&#8217;s not surprising that we spend the majority of our time watching Instagram reels or Youtube shorts.</p><p>Recently, tech companies have started asking video streaming design problems in system design interviews. Candidates often struggle due to a lack of experience in this area.</p><p>The best way to learn about video streaming is to build a strong foundation, understand the complex process, and go over real-world case studies.</p><p>This article simplifies complex concepts with examples and illustrations. Whether you're preparing for system design interviews or learning about video streaming, it covers key terms and the basics of video processing.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/subscribe?"><span>Subscribe now</span></a></p><p>Let&#8217;s start our journey by learning the core concepts!</p><h2>Core Concepts</h2><p>While recording a video, camera clicks a stream of pictures in quick succession. So, a video file is just a continuous sequence of images. </p><p>When you play a video, it displays the clicked pictures and our human brain perceives it as a motion picture.</p><h3>Frame</h3><p>In the context of a video, the clicked picture or an image is known as a <strong>frame</strong>. A camera generally clicks 30-60 frames per second.</p><p>The higher the number of frames, the better the video quality. Lower frames per second hinder the smoothness of a video.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!I62B!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61af4df4-ff9b-4d82-89e5-0e6ea449b4ca_2560x1420.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!I62B!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61af4df4-ff9b-4d82-89e5-0e6ea449b4ca_2560x1420.png 424w, https://substackcdn.com/image/fetch/$s_!I62B!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61af4df4-ff9b-4d82-89e5-0e6ea449b4ca_2560x1420.png 848w, https://substackcdn.com/image/fetch/$s_!I62B!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61af4df4-ff9b-4d82-89e5-0e6ea449b4ca_2560x1420.png 1272w, https://substackcdn.com/image/fetch/$s_!I62B!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61af4df4-ff9b-4d82-89e5-0e6ea449b4ca_2560x1420.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!I62B!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61af4df4-ff9b-4d82-89e5-0e6ea449b4ca_2560x1420.png" width="1456" height="808" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/61af4df4-ff9b-4d82-89e5-0e6ea449b4ca_2560x1420.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:808,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:4514344,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!I62B!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61af4df4-ff9b-4d82-89e5-0e6ea449b4ca_2560x1420.png 424w, https://substackcdn.com/image/fetch/$s_!I62B!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61af4df4-ff9b-4d82-89e5-0e6ea449b4ca_2560x1420.png 848w, https://substackcdn.com/image/fetch/$s_!I62B!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61af4df4-ff9b-4d82-89e5-0e6ea449b4ca_2560x1420.png 1272w, https://substackcdn.com/image/fetch/$s_!I62B!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61af4df4-ff9b-4d82-89e5-0e6ea449b4ca_2560x1420.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Image from - https://invideo.io/blog/video-frame-rates-guide/</strong></figcaption></figure></div><h3>Pixel</h3><p>Each frame can be broken down into atomic units of equal size known as a pixel. A pixel is a square-like portion that can encode the colour of an image.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SpDP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe4e5bd2-b5fb-4b39-ad8c-a60847d5c314_664x596.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SpDP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe4e5bd2-b5fb-4b39-ad8c-a60847d5c314_664x596.png 424w, https://substackcdn.com/image/fetch/$s_!SpDP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe4e5bd2-b5fb-4b39-ad8c-a60847d5c314_664x596.png 848w, https://substackcdn.com/image/fetch/$s_!SpDP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe4e5bd2-b5fb-4b39-ad8c-a60847d5c314_664x596.png 1272w, https://substackcdn.com/image/fetch/$s_!SpDP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe4e5bd2-b5fb-4b39-ad8c-a60847d5c314_664x596.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!SpDP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe4e5bd2-b5fb-4b39-ad8c-a60847d5c314_664x596.png" width="664" height="596" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/be4e5bd2-b5fb-4b39-ad8c-a60847d5c314_664x596.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:596,&quot;width&quot;:664,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:407069,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!SpDP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe4e5bd2-b5fb-4b39-ad8c-a60847d5c314_664x596.png 424w, https://substackcdn.com/image/fetch/$s_!SpDP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe4e5bd2-b5fb-4b39-ad8c-a60847d5c314_664x596.png 848w, https://substackcdn.com/image/fetch/$s_!SpDP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe4e5bd2-b5fb-4b39-ad8c-a60847d5c314_664x596.png 1272w, https://substackcdn.com/image/fetch/$s_!SpDP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe4e5bd2-b5fb-4b39-ad8c-a60847d5c314_664x596.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Pixel illustrated</strong></figcaption></figure></div><p>A pixel&#8217;s colour can be computed by mixing R (Red), Green (G) and Blue (B) colours. In computing, each of R, G, and B is known as a channel.</p><p>A channel can be allocated certain bits to encode the colour information. For eg:- Normal videos use 8 bits for R, G, and B resulting in <strong>24 bits/pixel</strong>. Higher definition videos use 16 bits for each channel (<strong>48 bits/pixel</strong>).</p><h3>Bitrate</h3><p>Bitrate is the amount of data used to encode a video stream per unit time. It&#8217;s measured in <strong>bits/sec </strong>or<strong> kilobits/sec </strong>or<strong> megabits/sec</strong>.</p><p>Bitrate determines the overall video quality and the file size. Files using higher bitrate result in better quality and larger file size.</p><p>As seen in the previous section, each pixel is represented using a set of bits. In case each pixel uses more bits, then the video would require higher bitrate.</p><p>Certain video scenes such as action sequences require a higher bitrate than still scenes such as scenery. </p><h3>Resolution</h3><p>Video resolution is the count of distinct pixels that constitute a video. A higher resolution video would have more pixels as compared to a low resolution one.</p><p>Video resolution is expressed as width &#215; height in pixels. A SD (<strong>480p</strong>) video has <strong>640&#215;480 pixels</strong>, while an HD (<strong>720p</strong>) has <strong>1280&#215;720 pixels</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5LUn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc82d4ffd-b465-4a5f-931d-34e18f2c2591_1238x1014.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5LUn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc82d4ffd-b465-4a5f-931d-34e18f2c2591_1238x1014.png 424w, https://substackcdn.com/image/fetch/$s_!5LUn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc82d4ffd-b465-4a5f-931d-34e18f2c2591_1238x1014.png 848w, https://substackcdn.com/image/fetch/$s_!5LUn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc82d4ffd-b465-4a5f-931d-34e18f2c2591_1238x1014.png 1272w, https://substackcdn.com/image/fetch/$s_!5LUn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc82d4ffd-b465-4a5f-931d-34e18f2c2591_1238x1014.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5LUn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc82d4ffd-b465-4a5f-931d-34e18f2c2591_1238x1014.png" width="1238" height="1014" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c82d4ffd-b465-4a5f-931d-34e18f2c2591_1238x1014.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1014,&quot;width&quot;:1238,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1216166,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5LUn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc82d4ffd-b465-4a5f-931d-34e18f2c2591_1238x1014.png 424w, https://substackcdn.com/image/fetch/$s_!5LUn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc82d4ffd-b465-4a5f-931d-34e18f2c2591_1238x1014.png 848w, https://substackcdn.com/image/fetch/$s_!5LUn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc82d4ffd-b465-4a5f-931d-34e18f2c2591_1238x1014.png 1272w, https://substackcdn.com/image/fetch/$s_!5LUn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc82d4ffd-b465-4a5f-931d-34e18f2c2591_1238x1014.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Effects of changing video resolution</strong></figcaption></figure></div><p>Now that you are familiar with basic concepts, can you guess what would be the size of a short HD video file of 10 seconds ? &#129300; </p><p>Let&#8217;s do some quick calculations and compute the size.</p><ul><li><p>Frames - 30 per second</p></li><li><p>Resolution of each frame - 720 p or 1280*720 pixels = 921600 pixels</p></li><li><p>Size of each pixel = 24 bits </p></li><li><p>Total size of each frame = Resolution of each frame X Size of each pixel</p><ul><li><p>921600 x 24</p></li><li><p><strong>22118400</strong> bits</p></li></ul></li><li><p>Size of 1 second video = Frames per second X Size of each frame</p><ul><li><p>30 * 22118400</p></li><li><p>663552000</p></li></ul></li><li><p>Size of 10 second video = 10 * Size of 1 second video</p><ul><li><p>10 * 663552000</p></li><li><p>6635520000 or <strong>663.552 Mb</strong> </p></li></ul></li></ul><p>663 Mb is too big for a 10 second video &#129327;</p><p>Have you come across such a big file while recording a small video ? </p><p>The answer is no. But, how does your device generate small video files of 1-5 Mb for a 10 sec video ? The magic lies in a process known as video encoding.</p><h3>Video Encoding</h3><p>Video encoding converts a raw video file into a format that&#8217;s optimized for storage, transmission and playback. The encoding process also ensures that video quality is not degraded.</p><p>Video encoders/decoders are also known as <strong>Codec</strong>(En<strong>co</strong>der-<strong>Dec</strong>oder). Some popular codecs are: H.264, H.265 (HEVC), VP9, AV1, MPEG-2, and MPEG-4.</p><p>A raw video files goes through the following steps during encoding :-</p><ol><li><p><strong>Frame-by-Frame Analysis </strong>- The encoder goes through each frame and identifies the redundancies within each frame.</p></li><li><p><strong>Temporal Compression</strong> - It removes the redundancies or repeated frames through compression. </p></li><li><p><strong>Bitrate control</strong> - The encoder adjusts the bitrate depending on the frame complexity.</p></li><li><p><strong>Compression</strong> - The encoder runs a complex compression algorithm that might either discard some data or completely retain the data during compression.</p></li><li><p><strong>Output</strong> - The final output file contains the video, audio and other metadata.</p></li></ol><h3>Video decoding </h3><p>Video decoding is the reverse process of encoding. The decoder extracts all the frames from the encoded file and plays the video. </p><p>Decoding happens in real-time as you play a video. Both encoding and decoding are CPU-intensive operations. </p><p>A video file is more than just a sequence of images. It must also contain audio, subtitles, thumbnails, watermark, etc. How are these things merged in a single file ? &#129300;</p><p>Let&#8217;s understand this in the next subsection</p><h3>Video Container</h3><p> The video file, audio, subtitles and metadata are packaged in a file known as video container. The container is a wrapper that allows the playback software to synchronise the different files for a smooth playback.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4PQy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb41e084c-bccb-4f4e-8e5c-7405b28b1c1c_386x484.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4PQy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb41e084c-bccb-4f4e-8e5c-7405b28b1c1c_386x484.png 424w, https://substackcdn.com/image/fetch/$s_!4PQy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb41e084c-bccb-4f4e-8e5c-7405b28b1c1c_386x484.png 848w, https://substackcdn.com/image/fetch/$s_!4PQy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb41e084c-bccb-4f4e-8e5c-7405b28b1c1c_386x484.png 1272w, https://substackcdn.com/image/fetch/$s_!4PQy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb41e084c-bccb-4f4e-8e5c-7405b28b1c1c_386x484.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4PQy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb41e084c-bccb-4f4e-8e5c-7405b28b1c1c_386x484.png" width="386" height="484" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b41e084c-bccb-4f4e-8e5c-7405b28b1c1c_386x484.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:484,&quot;width&quot;:386,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:45144,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4PQy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb41e084c-bccb-4f4e-8e5c-7405b28b1c1c_386x484.png 424w, https://substackcdn.com/image/fetch/$s_!4PQy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb41e084c-bccb-4f4e-8e5c-7405b28b1c1c_386x484.png 848w, https://substackcdn.com/image/fetch/$s_!4PQy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb41e084c-bccb-4f4e-8e5c-7405b28b1c1c_386x484.png 1272w, https://substackcdn.com/image/fetch/$s_!4PQy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb41e084c-bccb-4f4e-8e5c-7405b28b1c1c_386x484.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Video Container (MP4, AVI, MKV)</strong></figcaption></figure></div><p>Video containers have different file formats such as <strong>MP4</strong>, <strong>MKV</strong>, <strong>AVI</strong>, <strong>MOV</strong>, etc.</p><p>If I use QuickTime Player on Mac to record a video, it gets stored in the form of a <strong>.mov</strong> file. This file is specific to a Mac and it won&#8217;t run on non-Mac devices.</p><p>How do video streaming websites ensure that different devices play the video file without any additional software installation ? &#129300;</p><p>We will now look at Video transcoding that helps streaming websites achieve this.</p><h3>Video Transcoding</h3><p>Let&#8217;s assume that I record a video using QuickTime Player in .mov format and I upload it to Youtube. Youtube recognises that the format is incompatible with other desktop, mobile or TV devices. </p><p>The end-user devices might be expecting a MP4 file for playback. Hence, Youtube&#8217;s system must first convert the file from <strong>.mov</strong> to <strong>.mp4</strong> format.</p><p>This process of converting a video from one format to another format is known as Transcoding. A video goes through the following sequence of steps in transcoding :-</p><ol><li><p>Decode the source video</p></li><li><p>Decompress the decoded video</p></li><li><p>Perform transcoding through the following series of steps:</p><ol><li><p>Change bitrate if required</p></li><li><p>Modify the Frames per second</p></li><li><p>Change the resolution (1080p to 720p)</p></li><li><p>Encode and compress the video in a different format (.mp4 or .avi)</p></li></ol></li><li><p>Output the transcoded video and store it in a permanent storage</p></li></ol><p>Once the transcoding steps complete, the video then becomes ready for streaming. Transcoding happens asynchronously and user is notified after its completion.</p><p>Now that you are familiar with basic concepts of video streaming, let&#8217;s understand what challenges video streaming services face.</p><h2>Video streaming challenges</h2><p>A few seconds of entertainment for users comes at the expense of hours of engineering efforts. Streaming companies strive to continuously innovate and provide a smooth user experience.</p><p>Here are few common challenges that companies like Youtube, Netflix, Meta face :-</p><ol><li><p><strong>User experience</strong> - It&#8217;s essential to provide a seamless user experience without any glitch to millions of users simultaneously.</p></li><li><p><strong>Performance</strong> - Upload and download latency are key indicators or success criteria for any streaming service. No user would wait for minutes for a video to stream.</p></li><li><p><strong>Scalability</strong> - Applications such as Facebook or Instagram Live allow celebrity users to connect with millions of users simultaneously. Handling millions of connections and delivering real-time experience is a hard problem.</p></li><li><p><strong>End-user devices </strong>- Streaming services have to support a multitude of devices. Every device has its own OS, hardware and constraints. Companies have to ensure compatibility with all the end-user devices.</p></li></ol><p>In my next article, I will discuss few real-world case studies and how each company has tackled different set of challenges.</p><p>Let&#8217;s summarise and revisit the concepts that you have learnt so far.</p><h2>Conclusion</h2><p>A video captured by a camera is a sequence of images. Each image is known as a <strong>frame</strong> and it captures 30-60 frames per second.</p><p>A frame is a collection of identical square shaped units called as <strong>pixel</strong>. A pixel contains the colour information for the portion of the image it represents.</p><p>A video has a resolution standard that defines how many pixels it uses. Higher resolution (<strong>High definition 1280p</strong>) captures more granular details and leads to better picture quality.</p><p>Bitrate determines the amount of data used to represent a pixel. Bitrate needs to be adjusted based on the frames and the video resolution.</p><p>A raw video file is large in size and goes through encoding and compression that reduces the file size. <strong>Encoding</strong> optimizes a video file for transmission and playback.</p><p>Streaming companies use a process called <strong>Transcoding</strong> that converts one video file format into another. This ensures file compatibility with different devices. The process also adjusts the bitrate and the resolution.</p><p>Should Transcoding be a synchronous process given that it&#8217;s compute-heavy or should it be asynchronous ? Leave your thoughts in the comments below.  </p><p>Stay tuned for the next article where we&#8217;ll understand the technologies powering the streaming services.</p><p>Before you go:</p><ul><li><p>&#10084;&#65039; the story and follow the newsletter for more such articles</p></li><li><p>&#128276; Follow me: <a href="https://www.linkedin.com/in/animesh-gaitonde/">LinkedIn</a>, <a href="https://twitter.com/animesh3436">Twitter</a>, <a href="https://medium.com/@animeshgaitonde">Medium</a></p></li><li><p>Your support helps keep this newsletter free and fuels future content. Consider a small donation to show your appreciation here - <a href="https://www.paypal.com/ncp/payment/EUGP54EHQFDZC">Paypal Donate</a></p></li></ul><div class="poll-embed" data-attrs="{&quot;id&quot;:249360}" data-component-name="PollToDOM"></div><p></p>]]></content:encoded></item><item><title><![CDATA[TAO - Meta's scalable architecture powering world's largest social graph]]></title><description><![CDATA[Meta (formerly Facebook) has more than 2 billion Daily Active Users (DAU).]]></description><link>https://engineeringatscale.substack.com/p/tao-metas-scalable-architecture-powering</link><guid isPermaLink="false">https://engineeringatscale.substack.com/p/tao-metas-scalable-architecture-powering</guid><dc:creator><![CDATA[Animesh Gaitonde]]></dc:creator><pubDate>Sat, 09 Nov 2024 10:56:37 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41c5b1d-01b7-47af-a4c1-d3b798abfc26_2578x1328.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Meta (formerly Facebook) has more than 2 billion <strong>Daily Active Users</strong> (<strong>DAU</strong>). The platform generates millions of posts, images, videos, etc everyday.</p><p>The system needs to generate the content for every active user. Every user&#8217;s content is unique due to restrictions and privacy checks.</p><p>Friendships, checkins, comments, reactions etc result in a dynamic social graph. The platform must handle the large scale and deliver the user content within fraction of seconds.</p><p>Meta developed <strong>TAO</strong> - a geographically distributed graph data abstraction to power the largest social graph. TAO is optimized to handle Facebook&#8217;s billions of reads and millions of write requests daily.</p><p>In this article, we will go over Facebook&#8217;s original architecture and its limitations. We will then walkthrough how the architecture evolved into TAO. We will learn how TAO&#8217;s architecture solved the problem through its robust design. And conclude by going over TAO&#8217;s performance on production workloads.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/subscribe?"><span>Subscribe now</span></a></p><h2>Problem Statement</h2><p>Imagine a Facebook user named Jimmy checkins into a hotel and tags his friends Bob and Jim. This post lands into his friend&#8217;s feed. Later, several friends would like the post and few would comment.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!p_Ur!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8ba5256-eba0-406f-9bc1-8e7bff646836_1584x1584.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!p_Ur!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8ba5256-eba0-406f-9bc1-8e7bff646836_1584x1584.png 424w, https://substackcdn.com/image/fetch/$s_!p_Ur!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8ba5256-eba0-406f-9bc1-8e7bff646836_1584x1584.png 848w, https://substackcdn.com/image/fetch/$s_!p_Ur!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8ba5256-eba0-406f-9bc1-8e7bff646836_1584x1584.png 1272w, https://substackcdn.com/image/fetch/$s_!p_Ur!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8ba5256-eba0-406f-9bc1-8e7bff646836_1584x1584.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!p_Ur!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8ba5256-eba0-406f-9bc1-8e7bff646836_1584x1584.png" width="1456" height="1456" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b8ba5256-eba0-406f-9bc1-8e7bff646836_1584x1584.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1456,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3550951,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!p_Ur!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8ba5256-eba0-406f-9bc1-8e7bff646836_1584x1584.png 424w, https://substackcdn.com/image/fetch/$s_!p_Ur!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8ba5256-eba0-406f-9bc1-8e7bff646836_1584x1584.png 848w, https://substackcdn.com/image/fetch/$s_!p_Ur!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8ba5256-eba0-406f-9bc1-8e7bff646836_1584x1584.png 1272w, https://substackcdn.com/image/fetch/$s_!p_Ur!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8ba5256-eba0-406f-9bc1-8e7bff646836_1584x1584.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Sample Facebook post. Generated by <a href="https://www.meta.ai/">meta.ai</a></figcaption></figure></div><p>This would go on for a couple of hours or days until Jimmy creates another post in near future.</p><p><em>Did you notice what just happened ? </em></p><p><strong>In short</strong> - A user created a post, it got some traction and engagement. The view of the post kept changing as the reactions and comments kept flowing. In a few days, the engagement faded and user created another post. And the cycle continued.</p><p>One more observation is that the post&#8217;s view differs for every user. For eg:- If the post is public, a non-friend user may not be able to comment. Similarly, due to restrictions one or more friends might not comment or share.</p><p>A single post data looks like a graph of inter-connected nodes. If you extend it to all Facebook users, it becomes a social graph. The social graph is dynamic as it changes every second due to user&#8217;s engagement on the post.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!L5nt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65bf36fb-3973-4778-b1a4-d1fd1886e6ee_1956x1414.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!L5nt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65bf36fb-3973-4778-b1a4-d1fd1886e6ee_1956x1414.png 424w, https://substackcdn.com/image/fetch/$s_!L5nt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65bf36fb-3973-4778-b1a4-d1fd1886e6ee_1956x1414.png 848w, https://substackcdn.com/image/fetch/$s_!L5nt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65bf36fb-3973-4778-b1a4-d1fd1886e6ee_1956x1414.png 1272w, https://substackcdn.com/image/fetch/$s_!L5nt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65bf36fb-3973-4778-b1a4-d1fd1886e6ee_1956x1414.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!L5nt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65bf36fb-3973-4778-b1a4-d1fd1886e6ee_1956x1414.png" width="1456" height="1053" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/65bf36fb-3973-4778-b1a4-d1fd1886e6ee_1956x1414.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1053,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:191538,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!L5nt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65bf36fb-3973-4778-b1a4-d1fd1886e6ee_1956x1414.png 424w, https://substackcdn.com/image/fetch/$s_!L5nt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65bf36fb-3973-4778-b1a4-d1fd1886e6ee_1956x1414.png 848w, https://substackcdn.com/image/fetch/$s_!L5nt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65bf36fb-3973-4778-b1a4-d1fd1886e6ee_1956x1414.png 1272w, https://substackcdn.com/image/fetch/$s_!L5nt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65bf36fb-3973-4778-b1a4-d1fd1886e6ee_1956x1414.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Facebook post - graph of user, post, comments, shares and reactions</strong></figcaption></figure></div><p>To summarize, this is the core problem that Facebook needs to solve :</p><blockquote><p><strong>Problem</strong> - <em>Generate customized user content by applying privacy checks and filters on ever changing social graph. Moreover, develop a resilient, fault-tolerant and a performant system to handle increasing load from billion users.</em></p></blockquote><p>Let&#8217;s now go over the original architecture that solved this problem.</p><h2>Original Architecture</h2><p>In the beginning, Facebook adopted a PHP-MySQL stack to render the social graph. They used Memecache as a look-aside cache to accelerate the performance.</p><p>Here&#8217;s how the architecture looked like :</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kGIs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa13997ba-948c-4595-a974-b16cd61e49f0_2318x1414.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kGIs!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa13997ba-948c-4595-a974-b16cd61e49f0_2318x1414.png 424w, https://substackcdn.com/image/fetch/$s_!kGIs!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa13997ba-948c-4595-a974-b16cd61e49f0_2318x1414.png 848w, https://substackcdn.com/image/fetch/$s_!kGIs!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa13997ba-948c-4595-a974-b16cd61e49f0_2318x1414.png 1272w, https://substackcdn.com/image/fetch/$s_!kGIs!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa13997ba-948c-4595-a974-b16cd61e49f0_2318x1414.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kGIs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa13997ba-948c-4595-a974-b16cd61e49f0_2318x1414.png" width="1456" height="888" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a13997ba-948c-4595-a974-b16cd61e49f0_2318x1414.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:888,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:247136,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kGIs!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa13997ba-948c-4595-a974-b16cd61e49f0_2318x1414.png 424w, https://substackcdn.com/image/fetch/$s_!kGIs!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa13997ba-948c-4595-a974-b16cd61e49f0_2318x1414.png 848w, https://substackcdn.com/image/fetch/$s_!kGIs!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa13997ba-948c-4595-a974-b16cd61e49f0_2318x1414.png 1272w, https://substackcdn.com/image/fetch/$s_!kGIs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa13997ba-948c-4595-a974-b16cd61e49f0_2318x1414.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Facebook&#8217;s original architecture</strong></figcaption></figure></div><p>The WebApp layer was an aggregation layer. It fetched the data from different upstream services for likes, comments, shares, post data etc. Each service used Memcache to speed up reads.</p><p>Before reading further, take a moment to think <em>what could be the potential downsides of this approach</em> ?</p><p>The original architecture had the following limitations :-</p><ol><li><p><strong>Distributed control logic</strong> - The logic was spread across different services which increased failure modes. For eg:- <strong><a href="https://en.wikipedia.org/wiki/Thundering_herd_problem">Thundering Herd</a></strong> on MySQL in case of a cache miss.</p></li><li><p><strong>Inefficient access pattern</strong> - The queries need to fetch the list of different associations (comments, reactions, etc). Also, it must handle concurrent updates to a cached list.</p></li><li><p><strong>Expensive read-after-write consistency</strong> - For high availability, the system used asynchronous master/slave replication. Invalidating cache in replica was challenging. As a result, it was expensive to achieve read-after-write or strong consistency.</p></li></ol><p>Now, that you understand the original architecture and its limitations, let&#8217;s now focus on how Meta solved it.</p><h2>TAO - Graph Data abstraction</h2><p>TAO was developed as a service which would expose a graph to the clients. For eg:- Given a post&#8217;s identifier, it would aggregate and return all the data to the WebApp layer.</p><p>It didn&#8217;t allow the clients to directly access the MySQL database. Clients would use TAO&#8217;s APIs to fetch data they needed.</p><p>TAO provided the following two data models :-</p><ol><li><p><strong>Object</strong> - An object represented data entity such as a user, post, or a comment. Each object was uniquely identified by a 64-bit field.</p></li><li><p><strong>Associations </strong>- An association was either a relationship between two objects or action taken by one object on another. Each association had a type indicating relationship like <em>LikedBy</em>, <em>FriendOf</em>, <em>PostedBy</em>, <em>etc</em>.</p></li></ol><h3>APIs</h3><ol><li><p><strong>Object APIs</strong> - These APIs were used to create, update and fetch the object data.</p></li><li><p><strong>Association APIs</strong> - These APIs were useful for defining relationship between the objects. Further, they provided several variations such as :-</p><ol><li><p><strong>assoc_get</strong> - Fetch all associations between two objects.</p></li><li><p><strong>assoc_count</strong> - Count of associations. Useful to get count of comments or likes.</p></li><li><p><strong>assoc_range</strong> - To fetch a range of associations using pagination.</p></li><li><p><strong>assoc_tim_range</strong> - Fetch associations within the time constraints</p></li></ol></li></ol><p>Let&#8217;s now understand the internal architecture that powered these APIs and data models.</p><h2>TAO Architecture</h2><p>TAO&#8217;s design used a layered architecture approach. Each layer had a different responsibility i.e caching or data storage.</p><p>TAO used replication for high availability and failover. Further, it scaled geographically by maintaining a copy of social graph in every region.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-MiE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41c5b1d-01b7-47af-a4c1-d3b798abfc26_2578x1328.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-MiE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41c5b1d-01b7-47af-a4c1-d3b798abfc26_2578x1328.png 424w, https://substackcdn.com/image/fetch/$s_!-MiE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41c5b1d-01b7-47af-a4c1-d3b798abfc26_2578x1328.png 848w, https://substackcdn.com/image/fetch/$s_!-MiE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41c5b1d-01b7-47af-a4c1-d3b798abfc26_2578x1328.png 1272w, https://substackcdn.com/image/fetch/$s_!-MiE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41c5b1d-01b7-47af-a4c1-d3b798abfc26_2578x1328.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-MiE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41c5b1d-01b7-47af-a4c1-d3b798abfc26_2578x1328.png" width="1456" height="750" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f41c5b1d-01b7-47af-a4c1-d3b798abfc26_2578x1328.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:750,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:326588,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-MiE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41c5b1d-01b7-47af-a4c1-d3b798abfc26_2578x1328.png 424w, https://substackcdn.com/image/fetch/$s_!-MiE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41c5b1d-01b7-47af-a4c1-d3b798abfc26_2578x1328.png 848w, https://substackcdn.com/image/fetch/$s_!-MiE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41c5b1d-01b7-47af-a4c1-d3b798abfc26_2578x1328.png 1272w, https://substackcdn.com/image/fetch/$s_!-MiE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41c5b1d-01b7-47af-a4c1-d3b798abfc26_2578x1328.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>TAO architecture</strong></figcaption></figure></div><p>Let&#8217;s go over each layer and understand the design decision.</p><h3>Storage layer</h3><p>TAO stored the object and association data in MySQL servers. The data was sharded by using consistent hashing.</p><p>Every TAO API mapped to a SQL query at the lowest level. It leveraged MySQL&#8217;s indexes to speed up lookup of range queries for association APIs.</p><h4>Design decisions</h4><ol><li><p><strong>MySQL</strong> - Although a NoSQL database like LevelDB could have worked, MySQL was chosen for non-user-facing functions like bulk imports, replica creation, async replication, and atomic transactions.</p></li><li><p><strong>Consistent hashing</strong> - This ensured uniform load distribution and simplified request routing.</p></li></ol><h3>Caching layer</h3><p>The caching layer served the TAO&#8217;s APIs. Every server in this layer cached the data from the storage layer using <strong>LRU </strong>(Least Recently Used) policy.</p><p>Every server hosted cached data for multiple shards. In other words, each database shard mapped to a single cache server.</p><p>The caching servers communicated with each other and understood the semantics of the data. For eg:- if the association count was 0, then caching server wouldn&#8217;t query the associations.</p><p>The cache layer was further divided into two :</p><ol><li><p><strong>Leader tier </strong>- Servers in this tier handled all database interactions.</p></li><li><p><strong>Follower tier</strong> - Clients interacted with this tier. In case of cache misses, requests were forwarded to the leader tier.</p></li></ol><p>There was a single leader tier and several follower tiers. Additional follower tiers could be added to handle the increasing load.</p><h4>Design decisions</h4><p><strong>Single Tier vs Leader-Follower tiers</strong> - A single large tier is prone to hot spots. The Leader-Follower architecture spreads the load evenly.</p><h3>Replication</h3><p>TAO used multi-region asynchronous replication. Data was replicated from a master region to a slave region, maintaining cache consistency through invalidation messages.</p><h4>Write flow</h4><p>Followers directed writes to leaders. If a leader was a slave, writes were redirected to the master&#8217;s leader. Data was updated synchronously across tiers, emitting invalidation messages for cache consistency.</p><p>The below diagram illustrates how a follower tier in Slave handles a write.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yFeW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F385b5a1d-0ea7-4422-8ffb-bed38dd486ee_2622x1034.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yFeW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F385b5a1d-0ea7-4422-8ffb-bed38dd486ee_2622x1034.png 424w, https://substackcdn.com/image/fetch/$s_!yFeW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F385b5a1d-0ea7-4422-8ffb-bed38dd486ee_2622x1034.png 848w, https://substackcdn.com/image/fetch/$s_!yFeW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F385b5a1d-0ea7-4422-8ffb-bed38dd486ee_2622x1034.png 1272w, https://substackcdn.com/image/fetch/$s_!yFeW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F385b5a1d-0ea7-4422-8ffb-bed38dd486ee_2622x1034.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yFeW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F385b5a1d-0ea7-4422-8ffb-bed38dd486ee_2622x1034.png" width="1456" height="574" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/385b5a1d-0ea7-4422-8ffb-bed38dd486ee_2622x1034.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:574,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:284030,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yFeW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F385b5a1d-0ea7-4422-8ffb-bed38dd486ee_2622x1034.png 424w, https://substackcdn.com/image/fetch/$s_!yFeW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F385b5a1d-0ea7-4422-8ffb-bed38dd486ee_2622x1034.png 848w, https://substackcdn.com/image/fetch/$s_!yFeW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F385b5a1d-0ea7-4422-8ffb-bed38dd486ee_2622x1034.png 1272w, https://substackcdn.com/image/fetch/$s_!yFeW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F385b5a1d-0ea7-4422-8ffb-bed38dd486ee_2622x1034.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Write flow illustration</strong></figcaption></figure></div><h4>Read flow</h4><p>Reads were performed on followers in a region, ensuring data was served locally for performance.</p><p>The below diagram shows how reads are served locally in the same region.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gKgB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2543865-19d8-4e86-8ea6-050e234d1074_2622x1034.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gKgB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2543865-19d8-4e86-8ea6-050e234d1074_2622x1034.png 424w, https://substackcdn.com/image/fetch/$s_!gKgB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2543865-19d8-4e86-8ea6-050e234d1074_2622x1034.png 848w, https://substackcdn.com/image/fetch/$s_!gKgB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2543865-19d8-4e86-8ea6-050e234d1074_2622x1034.png 1272w, https://substackcdn.com/image/fetch/$s_!gKgB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2543865-19d8-4e86-8ea6-050e234d1074_2622x1034.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gKgB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2543865-19d8-4e86-8ea6-050e234d1074_2622x1034.png" width="1456" height="574" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b2543865-19d8-4e86-8ea6-050e234d1074_2622x1034.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:574,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:275210,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!gKgB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2543865-19d8-4e86-8ea6-050e234d1074_2622x1034.png 424w, https://substackcdn.com/image/fetch/$s_!gKgB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2543865-19d8-4e86-8ea6-050e234d1074_2622x1034.png 848w, https://substackcdn.com/image/fetch/$s_!gKgB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2543865-19d8-4e86-8ea6-050e234d1074_2622x1034.png 1272w, https://substackcdn.com/image/fetch/$s_!gKgB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2543865-19d8-4e86-8ea6-050e234d1074_2622x1034.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Read flow illustration</strong></figcaption></figure></div><h4>Design decisions</h4><p><strong>Cache invalidation</strong> - To ensure cache consistency in master-slave region, invalidation messages were sent along with the replication stream. Caching servers used the invalidation messages for evicting or updating the entries. </p><h2>Bottlenecks, Optimizations and Failovers</h2><h3>Hot spots </h3><p>It was common for a  post to become viral. As a result, a given shard would receive a large number of requests. This would make the shard a hot spot.</p><h4><strong>Solution </strong>- </h4><ol><li><p><strong>Shard cloning</strong> - The shard was cloned and replicated on several servers in a follower tier. This technique rebalanced the load.</p></li><li><p><strong>Client caching</strong> - The server returned the access rate for the object. In case the rate exceeded a pre-defined threshold, the client cached the data. This reduced the load on the servers.</p></li></ol><h3>High-degree objects</h3><p>A limit of 6000 was imposed on the association list response returned by TAO. However, many objects had more than 6000 associations. For eg:- celebrities getting millions of comments.</p><p>Further, it was common for many objects to have 0 associations. And TAO would get assoc_get requests.</p><p>In case of a cache miss, this would result in large number of database queries.</p><h4>Solution - </h4><ol><li><p><strong>Association count</strong> - In case the count is 0, the query would directly return instead of checking the other objects in the database.</p></li><li><p><strong>Application semantics</strong> - They leveraged the data such as creation time of the objects and the associations and limited the search of associations.</p></li></ol><h3>Consistency</h3><p>TAO provided read-after-write consistency in the absence of failures. This was applicable for any client writing to and reading from the same follower tier.</p><p>The design preferred availability over strong consistency. In case of failures, the data was eventually consistent.</p><p>Hence, the clients had to tolerate some amount of data staleness. This was a fair trade-off given the load that the system had to serve.</p><h4>Strong consistency</h4><p>TAO provided strong consistency to a subset of APIs such as authentication. These APIs were marked as critical, guaranteed strong consistency at the cost of increased latency.</p><h3>Failovers</h3><p>TAO had to handle several failure scenarios such as :</p><ol><li><p><strong>Master database failure</strong> - Slave&#8217;s database was elected as the new master. All the cache-misses and writes were directed to the newly elected master.</p></li><li><p><strong>Leader failures</strong> - Followers sent the reads to the database. While writes were sent to a random leader in the tier.</p></li><li><p><strong>Follower failures</strong> - Every follower tier had a backup. In case of server timeouts, the clients sent request to the backup tier. </p></li></ol><h2>Performance</h2><p>Here&#8217;s how TAO performed on Facebook&#8217;s production workload :- </p><ol><li><p><strong>Availability</strong> - <strong>4.9 * 10^-6</strong> queries failed over a period of <strong>90 days</strong>.</p></li><li><p><strong>Hit rate</strong> - The overall hit rate was <strong>96.4%</strong> for read queries.</p></li><li><p><strong>Failover</strong> - Slave was promoted to master <strong>0.25%</strong> times due to database failures, upgrades or maintenance. </p></li><li><p><strong>Replication lag</strong> - <strong>p99</strong> for slave database lag was <strong>3 seconds</strong>. </p></li></ol><h2>Conclusion</h2><p>Meta faced a challenging problem while customized content for each user using its dynamic social graph. Initially, they used PHP stack, fetched data from MySQL and used Memcache as a look-aside cache.</p><p>Meta developed TAO as a graph data abstraction layer. It solved several downsides of original look-aside cache architecture.</p><p>Through its layered architecture, it scaled to handled billions of reads and millions of writes. Further, it favoured high availability over strong consistency.</p><p>TAO solved common problems in distributed systems such as hot spots, thundering herd and automatic failover. They adopted robust mechanisms like shard cloning and caching to build a resilient system.</p><p>If you have reached here, then here are few points to ponder :-</p><ul><li><p>Do you think a graph database like Neo4j would have worked instead of TAO ?</p></li><li><p>How do other social media websites like LinkedIn, Twitter, Threads, etc manage graph data ?</p></li></ul><p>Share your thoughts on the above points in the comments.</p><p><strong>Reference</strong> - <a href="https://www.usenix.org/system/files/conference/atc13/atc13-bronson.pdf">Facebook TAO</a></p><p>Before you go:</p><ul><li><p>&#10084;&#65039; the story and follow the newsletter for more such articles</p></li><li><p>&#128276; Follow me: <a href="https://www.linkedin.com/in/animesh-gaitonde/">LinkedIn</a>, <a href="https://twitter.com/animesh3436">Twitter</a>, <a href="https://medium.com/@animeshgaitonde">Medium</a></p></li><li><p>Your support helps keep this newsletter free and fuels future content. Consider a small donation to show your appreciation here - <a href="https://www.paypal.com/ncp/payment/EUGP54EHQFDZC">Paypal Donate</a></p></li></ul><p></p>]]></content:encoded></item><item><title><![CDATA[Unleashing the power of Change Data Capture (CDC) for Real-Time Data Syncing]]></title><description><![CDATA[CDC - Working, Application and Challenges]]></description><link>https://engineeringatscale.substack.com/p/unleashing-the-power-of-change-data-capture-for-real-time-data-syncing</link><guid isPermaLink="false">https://engineeringatscale.substack.com/p/unleashing-the-power-of-change-data-capture-for-real-time-data-syncing</guid><dc:creator><![CDATA[Animesh Gaitonde]]></dc:creator><pubDate>Mon, 21 Oct 2024 04:40:26 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab2f6d51-1ee3-4016-b1f9-13f21f3c0e30_2456x1280.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Modern internet solutions offer a multitude of features for end customers. Generally, these features are built using complex microservices architectures and leverage several storage solutions.</p><p>There is no one size fits all solution for data storage. End customers data could be stored in a relational database but a text-search feature would need the same data in Elasticsearch. Similarly, an analytics dashboard would expect the same data to reside in a data warehouse.</p><p>A few years ago, I faced a challenge where my team needed data attributes from a system owned by another team. Direct API integration added complexity due to multiple consumers, and a pub-sub setup would have led to redundant effort, as many teams used similar datastores and would have had to duplicate work. This is when I came across <strong>Change Data Capture</strong> (<strong>CDC</strong>) to solve this.</p><p>Companies find it challenging to keep the data in one system and store it in different forms in other storage systems. Traditionally, companies used batch processing to <strong>Extract, Transform &amp; Load</strong> (<strong>ETL</strong>) the data in different systems.</p><p>Batch processing resulted in delays in data propagation and heavy use of compute. To solve this, companies devised Change Data Capture (CDC) to keep different data sources in sync in real-time.</p><p>This article will cover the following :-</p><ol><li><p>What is CDC ?</p></li><li><p>How does CDC work ?</p></li><li><p>Types of CDC and their pros/cons</p></li><li><p>Applications of CDC</p></li><li><p>Real-world examples of CDC</p></li></ol><p>With that, let&#8217;s begin and understand what is CDC and why is it required.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/subscribe?"><span>Subscribe now</span></a></p><h2>What is CDC ?</h2><p>Let&#8217;s take an example of a food-delivery system. Assume that it stores the data for its restaurants in a relational database. And captures the location, user ratings, top rated dish, etc. </p><p>The customer using the app would have the following features :-</p><ol><li><p>Search restaurant by name.</p></li><li><p>Find nearby restaurants.</p></li><li><p>View the average rating of the restaurant.</p></li><li><p>Check the restaurant profile</p></li></ol><p>Now, to meet the above use cases, we would need the following storage solutions :-</p><ol><li><p>Search by name - Elasticsearch with <strong>text index</strong>.</p></li><li><p>Nearby restaurants - Elasticsearch/Postgres with <strong>Geospatial Index</strong> (<strong>GIS</strong>)</p></li><li><p>Average rating - <strong>Data lake</strong> like Redshift</p></li><li><p>Restaurant profile - Database like Postgres/MySQL</p></li></ol><p>Initially, we would store the restaurant&#8217;s profile in a database like Postgres/MySQL. However, would need the same data in Elasticsearch and Redshift. </p><p>Whenever there is any change to the restaurant&#8217;s profile i.e update in the ratings, the same has to be communicated to other systems (Redshift). Similarly, any change in the name or location, would imply updating the data in Elasticsearch.</p><blockquote><p><strong>Change Data Capture</strong> (<strong>CDC</strong>) is the process of capturing data changes in one system and propagating it to different systems in real/near-real time. It&#8217;s a technique which ensures different data sources are in sync.</p></blockquote><p>CDC overcomes the downsides of writing the data to multiple data stores. And also the additional burden of running compute-heavy offline jobs to sync the data.</p><p>The following diagram illustrates this process. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!n2wT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff23b958d-fc9e-4b22-9b96-a52830f4fe2a_2620x1496.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!n2wT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff23b958d-fc9e-4b22-9b96-a52830f4fe2a_2620x1496.png 424w, https://substackcdn.com/image/fetch/$s_!n2wT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff23b958d-fc9e-4b22-9b96-a52830f4fe2a_2620x1496.png 848w, https://substackcdn.com/image/fetch/$s_!n2wT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff23b958d-fc9e-4b22-9b96-a52830f4fe2a_2620x1496.png 1272w, https://substackcdn.com/image/fetch/$s_!n2wT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff23b958d-fc9e-4b22-9b96-a52830f4fe2a_2620x1496.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!n2wT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff23b958d-fc9e-4b22-9b96-a52830f4fe2a_2620x1496.png" width="1456" height="831" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f23b958d-fc9e-4b22-9b96-a52830f4fe2a_2620x1496.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:831,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:292054,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!n2wT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff23b958d-fc9e-4b22-9b96-a52830f4fe2a_2620x1496.png 424w, https://substackcdn.com/image/fetch/$s_!n2wT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff23b958d-fc9e-4b22-9b96-a52830f4fe2a_2620x1496.png 848w, https://substackcdn.com/image/fetch/$s_!n2wT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff23b958d-fc9e-4b22-9b96-a52830f4fe2a_2620x1496.png 1272w, https://substackcdn.com/image/fetch/$s_!n2wT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff23b958d-fc9e-4b22-9b96-a52830f4fe2a_2620x1496.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Food delivery Backend</strong></figcaption></figure></div><p></p><p>Now, that you understand the concept of CDC, we will look at the working of CDC.</p><h2>How does CDC work ? </h2><p>Most of the databases provide a mechanism to record all the changes made to the database tables. For example, MySQL records all the changes in <strong>binary log</strong> (<strong>binlog</strong>). Similarly, PostgreSQL uses <strong>Write-Ahead Log</strong> (<strong>WAL</strong>) to capture modifications. </p><p>CDC tools read &amp; parse the database logs, convert it to events and add it to a message broker or event bus like <strong>Kafka</strong>. Further, consumers consume the events and write it to destination datastore.</p><p>The following diagram illustrates the working of CDC:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fUz2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65adea54-570e-4264-bed7-6b2ca3d0e8df_2456x1280.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fUz2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65adea54-570e-4264-bed7-6b2ca3d0e8df_2456x1280.png 424w, https://substackcdn.com/image/fetch/$s_!fUz2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65adea54-570e-4264-bed7-6b2ca3d0e8df_2456x1280.png 848w, https://substackcdn.com/image/fetch/$s_!fUz2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65adea54-570e-4264-bed7-6b2ca3d0e8df_2456x1280.png 1272w, https://substackcdn.com/image/fetch/$s_!fUz2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65adea54-570e-4264-bed7-6b2ca3d0e8df_2456x1280.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fUz2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65adea54-570e-4264-bed7-6b2ca3d0e8df_2456x1280.png" width="1456" height="759" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/65adea54-570e-4264-bed7-6b2ca3d0e8df_2456x1280.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:759,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:268816,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fUz2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65adea54-570e-4264-bed7-6b2ca3d0e8df_2456x1280.png 424w, https://substackcdn.com/image/fetch/$s_!fUz2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65adea54-570e-4264-bed7-6b2ca3d0e8df_2456x1280.png 848w, https://substackcdn.com/image/fetch/$s_!fUz2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65adea54-570e-4264-bed7-6b2ca3d0e8df_2456x1280.png 1272w, https://substackcdn.com/image/fetch/$s_!fUz2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65adea54-570e-4264-bed7-6b2ca3d0e8df_2456x1280.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Working of CDC</strong></figcaption></figure></div><p>Generally, CDC tools add a table&#8217;s event to a Kafka partition. The Kafka partition guarantees strict ordering of all the events. Further, it provides strong durability guarantees and prevents data loss.</p><p>The consumer receives the events in the same manner as the source database. This ensures data completeness and accuracy. The data is then transformed by the consumers and then dumped in the destination database.</p><p>There are several different mechanisms to implement CDC and propagate the changes. In the next section, we will look at the different types of CDC and their pros/cons.</p><h2>Types of CDC</h2><h3>Log-based CDC</h3><p>The example in the previous section described the working of a log-based CDC. This method is highly efficient since it tracks the low-level logs that databases already maintain for durability and crash recovery.</p><h4>Pros</h4><ul><li><p>No performance impact on the database.</p></li><li><p>High accuracy and consistency.</p></li><li><p>Works seamlessly for databases that support transaction logging for durability</p></li></ul><h4>Cons</h4><ul><li><p>Logs can consume significant disk space.</p></li><li><p>Complexity in parsing logs</p></li></ul><h3>Trigger-based CDC</h3><p>This CDC relies on database triggers to detect and capture changes. Database triggers are configured to take an action (logging a change) on the occurrence of certain events. The events are captured in an audit table and then sent to downstream systems.</p><h4>Pros</h4><ul><li><p>Simple to implement in any database supporting triggers.</p></li><li><p>Can be used if the database doesn&#8217;t support logging like WAL or binlog.</p></li></ul><h4>Cons</h4><ul><li><p>Impact performance in case there are large number of triggers.</p></li><li><p>Complexity in managing triggers</p></li></ul><h3>Polling-based CDC</h3><p>This technique periodically queries the database to detect changes by comparing current values to a previous state. This is done by looking for new rows, modified timestamps, or version numbers.</p><h4>Pros</h4><ul><li><p>No dependency on transaction logs or triggers. So, works for databases that don&#8217;t support either.</p></li><li><p>Simple to setup when other methods are not available.</p></li></ul><h4>Cons</h4><ul><li><p>Inefficient since it requires constant querying.</p></li><li><p>Lacks real-time experience and results in delays.</p></li><li><p>Difficult to detect deletes without maintaining a full copy of data.</p></li></ul><p>Out of the different options available, Log-based CDC is considered to be most efficient. And also guarantees high degree of data freshness.</p><p>Now, that you are familiar with different CDC techniques, let&#8217;s look at few use cases of CDC.</p><h2>Applications of CDC</h2><h3>Cache Invalidation</h3><p>In certain cases, microservices have to explicitly invalidate cache entries and also remove the records from the database. This often impacts the performance as the service needs to perform dual-writes.</p><p>This can be solved through CDC by first removing the record from the database and evicting cache entry asynchronously. The below diagram illustrates the process.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!F6NV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40fe9b0e-171a-47f8-ad70-6bd770720784_1772x660.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!F6NV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40fe9b0e-171a-47f8-ad70-6bd770720784_1772x660.png 424w, https://substackcdn.com/image/fetch/$s_!F6NV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40fe9b0e-171a-47f8-ad70-6bd770720784_1772x660.png 848w, https://substackcdn.com/image/fetch/$s_!F6NV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40fe9b0e-171a-47f8-ad70-6bd770720784_1772x660.png 1272w, https://substackcdn.com/image/fetch/$s_!F6NV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40fe9b0e-171a-47f8-ad70-6bd770720784_1772x660.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!F6NV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40fe9b0e-171a-47f8-ad70-6bd770720784_1772x660.png" width="1456" height="542" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/40fe9b0e-171a-47f8-ad70-6bd770720784_1772x660.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:542,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:134848,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!F6NV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40fe9b0e-171a-47f8-ad70-6bd770720784_1772x660.png 424w, https://substackcdn.com/image/fetch/$s_!F6NV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40fe9b0e-171a-47f8-ad70-6bd770720784_1772x660.png 848w, https://substackcdn.com/image/fetch/$s_!F6NV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40fe9b0e-171a-47f8-ad70-6bd770720784_1772x660.png 1272w, https://substackcdn.com/image/fetch/$s_!F6NV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40fe9b0e-171a-47f8-ad70-6bd770720784_1772x660.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Cache invalidation through CDC</strong></figcaption></figure></div><p>This ensures that the application caches are in sync and don&#8217;t store stale data. </p><h3>Data replication</h3><p>Companies need to backup existing databases for fault tolerance and scalability. Since a full copy of data can be constructed through CDC, it&#8217;s used for different data replication use cases.</p><h3>Search Indexing</h3><p>CDC is a good fit for building Search indices since it supports in-order delivery of the mutations. It can keep the primary datastore and the Search indices in sync providing a real-time experience.</p><p>In case of a food delivery app, if a restaurant menu item changes, the same updates can flow through the Search indexing pipeline via CDC. Further, it would update the Search indices so that users could see the latest updates.</p><h3>Real-time Analytics</h3><p>CDC can be used to capture and stream the changes in analytics platform. It enables near real-time synchronization between transactional systems and data warehouses or data lakes.</p><p>This helps minimizes data latency and allows businesses to make timely, data-driven decisions, powering use cases like live dashboards, fraud detection, and personalized user experiences.</p><p>We will now look at some CDC solutions developed by industry leaders and the challenges faced in building CDC serices/tools.</p><h2>Real-world examples of CDC</h2><p>Tech companies like Uber, Airbnb, Netflix, etc transport petabytes of data every day. It&#8217;s common for these companies to use CDC to keep datastores in sync and provide real-time experience to users.</p><p>There are few common challenges that the companies have faced while building CDC solutions. Following are some challenges that influenced the development of CDC tools :</p><ol><li><p><strong>Scalability </strong>- The solution must scale to handle increasing volume of data. The performance shouldn&#8217;t get impacted due to spiky load.</p></li><li><p><strong>Data freshness </strong>- Propagation delays aren&#8217;t tolerated for users expecting a real or near real-time experience. A delay of a few seconds may be acceptable, but delays extending to hours are not.</p></li><li><p><strong>Extensibility </strong>- The system should be extensible for handling different data sources such as MySQL, PostgreSQL, Cassandra, etc. Onboarding a new data source should be plug-and-play.</p></li><li><p><strong>Data integrity </strong>- The solution must ensure no data corruption and guarantee delivery of data mutations within the SLA.</p></li><li><p><strong>Fault tolerance </strong>- The system must be resilient to failure.</p></li></ol><p>Let&#8217;s now look at few solutions developed by tech companies.</p><h3>SpinalTap</h3><p>SpinalTap is a Airbnb&#8217;s CDC system and integral part of its infrastructure. It was designed to be a general purpose solution to abstracts the change capture workflow, and easily extend to other dependencies such as event bus, consumers and data sources.</p><p>It&#8217;s used for a variety of in-house use cases like Search indexing of reviews, inbox and support tickets. Besides, it&#8217;s adopted for big data processing, cache invalidation and also signaling between services.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VPxS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e25b548-ff4b-471e-952c-cf7a080ea56c_1414x304.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VPxS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e25b548-ff4b-471e-952c-cf7a080ea56c_1414x304.png 424w, https://substackcdn.com/image/fetch/$s_!VPxS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e25b548-ff4b-471e-952c-cf7a080ea56c_1414x304.png 848w, https://substackcdn.com/image/fetch/$s_!VPxS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e25b548-ff4b-471e-952c-cf7a080ea56c_1414x304.png 1272w, https://substackcdn.com/image/fetch/$s_!VPxS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e25b548-ff4b-471e-952c-cf7a080ea56c_1414x304.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VPxS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e25b548-ff4b-471e-952c-cf7a080ea56c_1414x304.png" width="1414" height="304" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6e25b548-ff4b-471e-952c-cf7a080ea56c_1414x304.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:304,&quot;width&quot;:1414,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:95648,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VPxS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e25b548-ff4b-471e-952c-cf7a080ea56c_1414x304.png 424w, https://substackcdn.com/image/fetch/$s_!VPxS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e25b548-ff4b-471e-952c-cf7a080ea56c_1414x304.png 848w, https://substackcdn.com/image/fetch/$s_!VPxS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e25b548-ff4b-471e-952c-cf7a080ea56c_1414x304.png 1272w, https://substackcdn.com/image/fetch/$s_!VPxS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e25b548-ff4b-471e-952c-cf7a080ea56c_1414x304.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption"><a href="https://medium.com/airbnb-engineering/capturing-data-evolution-in-a-service-oriented-architecture-72f7c643ee6f">Airbnb SpinalTap architecture</a></figcaption></figure></div><p>It&#8217;s an open source project and you can find the source <a href="https://github.com/airbnb/SpinalTap">here</a>.</p><h3>DBEvents</h3><p>DBEvents is Uber&#8217;s framework to standardize data ingestion into Apache Hadoop Data lake. It was designed to solve three key business requirements - data freshness, quality and efficiency.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YjvB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec21c25b-4e94-47f5-9462-17864cc5d68d_1426x1044.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YjvB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec21c25b-4e94-47f5-9462-17864cc5d68d_1426x1044.png 424w, https://substackcdn.com/image/fetch/$s_!YjvB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec21c25b-4e94-47f5-9462-17864cc5d68d_1426x1044.png 848w, https://substackcdn.com/image/fetch/$s_!YjvB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec21c25b-4e94-47f5-9462-17864cc5d68d_1426x1044.png 1272w, https://substackcdn.com/image/fetch/$s_!YjvB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec21c25b-4e94-47f5-9462-17864cc5d68d_1426x1044.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YjvB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec21c25b-4e94-47f5-9462-17864cc5d68d_1426x1044.png" width="1426" height="1044" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ec21c25b-4e94-47f5-9462-17864cc5d68d_1426x1044.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1044,&quot;width&quot;:1426,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:639503,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!YjvB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec21c25b-4e94-47f5-9462-17864cc5d68d_1426x1044.png 424w, https://substackcdn.com/image/fetch/$s_!YjvB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec21c25b-4e94-47f5-9462-17864cc5d68d_1426x1044.png 848w, https://substackcdn.com/image/fetch/$s_!YjvB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec21c25b-4e94-47f5-9462-17864cc5d68d_1426x1044.png 1272w, https://substackcdn.com/image/fetch/$s_!YjvB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec21c25b-4e94-47f5-9462-17864cc5d68d_1426x1044.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://www.uber.com/en-IN/blog/dbevents-ingestion-framework/">DBEvents architecture</a></figcaption></figure></div><p> </p><h3>Debezium</h3><p>Debezium is an open-source project for CDC. It is built on top of Apache Kafka and provides Kafka connect compatible connectors. </p><p>It leverages Kafka&#8217;s streaming platform to ingest data mutations completely. It guarantees fault tolerance and ensures zero data loss.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!X2tD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F608fa774-f14f-4dd9-baf0-bbac596a7061_2402x514.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!X2tD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F608fa774-f14f-4dd9-baf0-bbac596a7061_2402x514.png 424w, https://substackcdn.com/image/fetch/$s_!X2tD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F608fa774-f14f-4dd9-baf0-bbac596a7061_2402x514.png 848w, https://substackcdn.com/image/fetch/$s_!X2tD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F608fa774-f14f-4dd9-baf0-bbac596a7061_2402x514.png 1272w, https://substackcdn.com/image/fetch/$s_!X2tD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F608fa774-f14f-4dd9-baf0-bbac596a7061_2402x514.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!X2tD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F608fa774-f14f-4dd9-baf0-bbac596a7061_2402x514.png" width="1456" height="312" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/608fa774-f14f-4dd9-baf0-bbac596a7061_2402x514.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:312,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:262519,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!X2tD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F608fa774-f14f-4dd9-baf0-bbac596a7061_2402x514.png 424w, https://substackcdn.com/image/fetch/$s_!X2tD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F608fa774-f14f-4dd9-baf0-bbac596a7061_2402x514.png 848w, https://substackcdn.com/image/fetch/$s_!X2tD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F608fa774-f14f-4dd9-baf0-bbac596a7061_2402x514.png 1272w, https://substackcdn.com/image/fetch/$s_!X2tD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F608fa774-f14f-4dd9-baf0-bbac596a7061_2402x514.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption"><a href="https://debezium.io/documentation/reference/3.0/architecture.html">Debezium architecture</a></figcaption></figure></div><h2>Conclusion</h2><p><strong>Change Data Capture</strong> (<strong>CDC</strong>) is the process of capturing data changes in one system and applying it in different downstream services. The process ensures data consistency across several systems.</p><p>Most of the databases like MySQL, PostgreSQL use logs to capture data modifications. CDC tools read the logs, parse it and dump the events in a distributed commit log like Kafka or Event Bus.</p><p>Kafka guarantees ordering and durability of all the events. The consumers then read the events and replay it in the destination datastores. </p><p>Since the destination receives the events in the same order as the source, full replica of the data can be constructed.</p><p>CDC tools are employed for use cases such as cache invalidation, search indexing, data replication and real-time analytics.</p><p>Companies have devised several CDC solutions and open-sourced them. Some common requirements of CDC solutions are - Scalability, Data Freshness, Data Integrity, Extensibility and Fault tolerance.</p><p>The best way to become an expert in CDC is to get some hands-on experience with an open-source tool. You can play around with Debezium and also go through its codebase.</p><p>Also, why do you think different companies have designed different CDC solutions ? Wouldn&#8217;t it make sense to have a common solution across all the companies ? &#129300; &#129300;</p><p>Leave your thoughts in the comments below.</p><p>Before you go:</p><ul><li><p>&#10084;&#65039; the story and follow the newsletter for more such articles</p></li><li><p>&#128276; Follow me: <a href="https://www.linkedin.com/in/animesh-gaitonde/">LinkedIn</a>, <a href="https://twitter.com/animesh3436">Twitter</a>, <a href="https://medium.com/@animeshgaitonde">Medium</a></p></li><li><p>Your support helps keep this newsletter free and fuels future content. Consider a small donation to show your appreciation here - <a href="https://www.paypal.com/ncp/payment/EUGP54EHQFDZC">Paypal Donate</a></p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/unleashing-the-power-of-change-data-capture-for-real-time-data-syncing?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/p/unleashing-the-power-of-change-data-capture-for-real-time-data-syncing?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p>]]></content:encoded></item><item><title><![CDATA[Master System Design Interviews: A 6-Step Framework for Success]]></title><description><![CDATA[Structured approach to nail your next System Design Interview]]></description><link>https://engineeringatscale.substack.com/p/system-design-interview-success-six-step-framework</link><guid isPermaLink="false">https://engineeringatscale.substack.com/p/system-design-interview-success-six-step-framework</guid><dc:creator><![CDATA[Animesh Gaitonde]]></dc:creator><pubDate>Sun, 13 Oct 2024 17:28:32 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!uXiJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b36f4-d53a-4854-a798-5c0e475969f2_1784x1534.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Introduction</h2><p>In my first system design interview, I thought it was just about drawing boxes and arrows. I didn't prepare well, leading to a rejection. After a year of failures and learning, I passed Meta's interview in 2020. </p><p>Each rejection taught me something new. I improved my technical skills and gained confidence. Eventually, I successfully cracked interviews at Microsoft, Amazon, Meta, Atlassian, and Airbnb.</p><p>This journey improved both my system design and interviewing skills. Looking back, I realized the mistakes that caused my rejections. And I developed a framework to handle complex system design interview problems. Using a structured approach in the 1-hour interview helped me succeed. This method also helped my friends get jobs at top tech companies.</p><p>In this article, I'll share a six-step approach to ace any system design interview. You'll learn common mistakes and how to divide the hour into six steps. I'll explain what to focus on in each step to create a complete design.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/subscribe?"><span>Subscribe now</span></a></p><p>Also, if you want to get better at system design, refer the following links :-</p><ol><li><p><a href="https://www.systemdesignhandbook.com/">System design handbook</a></p></li><li><p><a href="https://www.educative.io/courses/grokking-the-system-design-interview">Educative.io - Grokking the system design interview</a></p></li><li><p><a href="https://www.educative.io/learn-to-code">Educative.io - Learn to code</a></p></li></ol><p>If you want to improve at system design and join top companies, let's begin. We'll look at typical candidate mistakes.</p><h2>Common Mistakes</h2><ol><li><p><strong>Poor time management</strong>: Spending too long on one aspect, neglecting others.</p></li><li><p><strong>Lack of prioritization</strong>: Failing to focus on key features the interviewer wants, given the time constraint.</p></li><li><p><strong>Shallow analysis</strong>: Not diving deep enough to justify choices or discuss alternatives, preventing interviewers from assessing technical depth.</p></li><li><p><strong>Lack of initiative</strong>: Relying too much on interviewer guidance instead of working independently.</p></li><li><p><strong>Overlooking bottlenecks</strong>: Not addressing how the system handles heavy loads or traffic spikes.</p></li></ol><p>Now that you know the common reasons for rejection, we&#8217;ll now see how to tackle them through a structured framework.</p><h2>System design interview framework</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uXiJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b36f4-d53a-4854-a798-5c0e475969f2_1784x1534.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uXiJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b36f4-d53a-4854-a798-5c0e475969f2_1784x1534.png 424w, https://substackcdn.com/image/fetch/$s_!uXiJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b36f4-d53a-4854-a798-5c0e475969f2_1784x1534.png 848w, https://substackcdn.com/image/fetch/$s_!uXiJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b36f4-d53a-4854-a798-5c0e475969f2_1784x1534.png 1272w, https://substackcdn.com/image/fetch/$s_!uXiJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b36f4-d53a-4854-a798-5c0e475969f2_1784x1534.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uXiJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b36f4-d53a-4854-a798-5c0e475969f2_1784x1534.png" width="1456" height="1252" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/571b36f4-d53a-4854-a798-5c0e475969f2_1784x1534.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1252,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:420593,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uXiJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b36f4-d53a-4854-a798-5c0e475969f2_1784x1534.png 424w, https://substackcdn.com/image/fetch/$s_!uXiJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b36f4-d53a-4854-a798-5c0e475969f2_1784x1534.png 848w, https://substackcdn.com/image/fetch/$s_!uXiJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b36f4-d53a-4854-a798-5c0e475969f2_1784x1534.png 1272w, https://substackcdn.com/image/fetch/$s_!uXiJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b36f4-d53a-4854-a798-5c0e475969f2_1784x1534.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Six-step framework to crack system design interviews</strong></figcaption></figure></div><p>We&#8217;ll see each of the steps, what should be tackled and how much time you must allocate.</p><p>The interviews start with a one or a two liner problem statement. For eg: &#8220;<em>Design a distributed job scheduler for a large enterprise</em>&#8221;. </p><p>In most cases, you would be familiar with the constructs of the problem. However, you must discuss with your interviewer and understand the problem if you don&#8217;t have enough context about it. For eg: If you haven&#8217;t heard of a job scheduler, ask questions about it and its working.</p><h3>Functional Requirements - 5 mins</h3><p>After understanding the problem, focus on functional requirements:</p><ol><li><p>List all actions the system must perform.</p></li><li><p>Prioritize the top 3 core features to design during the interview.</p></li><li><p>Make reasonable assumptions (e.g., existing user registration for Instagram's newsfeed).</p></li><li><p>Keep complex elements out of scope (e.g., treat recommendation systems as a black box).</p></li><li><p>Discuss with the interviewer about any additional constraints they want to add.</p></li></ol><p>Clarify details with your interviewer, as they often want to see how you handle constraints.</p><h3>Non-functional requirements - 5 min</h3><p>After listing the functional requirements, you must list down how the system must achieve its objectives. These things would form the non-functional requirements.</p><p>You can refer to the below diagram for different non-functional requirements. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oodT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a02caf0-1d75-4b9b-b331-65031a66a47b_2086x786.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oodT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a02caf0-1d75-4b9b-b331-65031a66a47b_2086x786.png 424w, https://substackcdn.com/image/fetch/$s_!oodT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a02caf0-1d75-4b9b-b331-65031a66a47b_2086x786.png 848w, https://substackcdn.com/image/fetch/$s_!oodT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a02caf0-1d75-4b9b-b331-65031a66a47b_2086x786.png 1272w, https://substackcdn.com/image/fetch/$s_!oodT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a02caf0-1d75-4b9b-b331-65031a66a47b_2086x786.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oodT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a02caf0-1d75-4b9b-b331-65031a66a47b_2086x786.png" width="1456" height="549" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0a02caf0-1d75-4b9b-b331-65031a66a47b_2086x786.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:549,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:149687,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!oodT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a02caf0-1d75-4b9b-b331-65031a66a47b_2086x786.png 424w, https://substackcdn.com/image/fetch/$s_!oodT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a02caf0-1d75-4b9b-b331-65031a66a47b_2086x786.png 848w, https://substackcdn.com/image/fetch/$s_!oodT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a02caf0-1d75-4b9b-b331-65031a66a47b_2086x786.png 1272w, https://substackcdn.com/image/fetch/$s_!oodT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a02caf0-1d75-4b9b-b331-65031a66a47b_2086x786.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Common non-functional requirements</strong></figcaption></figure></div><p>You must ensure that any non-functional requirement is given in the context of a functional requirement and not the system as a whole. For eg: You can have eventual consistency in newsfeed but not in user's registration. Hence, while stating it's important not to state that the system as a whole is eventually consistent.</p><p>Moreover, don't keep the non-functional requirements vague. You can make some guesstimates and quantify it. For eg: State that the <em><strong>latency must be less than 200 ms</strong></em> instead of just stating <em><strong>latency should be low</strong></em>. </p><h3>Capacity estimation (Optional) - 2 min</h3><p>In many system design books and courses, capacity estimation is covered, and I've noticed candidates often spend time calculating storage, throughput, and hardware needs.</p><p>I've been there myself, making incorrect calculations or wasting time during interviews. In my experience, this only shows calculation skills and doesn&#8217;t add much value to the discussion.</p><p>Now, I ask upfront if the interviewer wants to focus on capacity estimation. Nine out of ten times, they&#8217;re fine without it. It's important to clarify this early on.</p><p>That said, some design decisions do depend on calculations. For example, designing a live video system with emoji reactions would be write-heavy, so calculating <strong>requests per second</strong> (<strong>RPS</strong>) helps select the right storage system.</p><h3>Core Actors, APIs and flows - 10 mins</h3><p>Once you clearly understand what the system needs to achieve, the next step is to identify the core actors in your system. These are the key entities in your design. For example, in Tinder, the core entities would be Users, Swipes, Matches, etc.</p><p>This doesn't need to be exhaustive since you may not know all the required data. Just make a bullet list of the identified entities.</p><p>Next, identify the APIs your clients or services will use for communication. Note all the request/response interactions. Whether synchronous or asynchronous, these will clarify how entities in the system interact.</p><p>If working with an offline system, identify workflows with multiple steps. For example, in a job scheduler, you'd need to fetch jobs, schedule them, monitor, and trigger alarms. Note these workflows and the sequence of steps involved.</p><h3>High-level architecture - 15 mins</h3><p>In this step, you must walk through each functional requirement and sketch the flow from the client to the backend database. Draw the relevant entities and highlight the different flows.</p><p>Explain how the APIs would work and highlight cross-cutting concerns like rate-limiting, encryption, etc solved by components such as API Gateway. </p><p>You don&#8217;t have to be 100% correct in this as you can further iterate, and improve your design in the dive deep section. You have to actively communicate and explain each flow to your interviewer.</p><p>Here&#8217;s a sample high-level architecture for the design of Tinder along with its functional requirements.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wLkc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25279443-cf58-48b2-86f6-98122156302a_2482x1184.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wLkc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25279443-cf58-48b2-86f6-98122156302a_2482x1184.png 424w, https://substackcdn.com/image/fetch/$s_!wLkc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25279443-cf58-48b2-86f6-98122156302a_2482x1184.png 848w, https://substackcdn.com/image/fetch/$s_!wLkc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25279443-cf58-48b2-86f6-98122156302a_2482x1184.png 1272w, https://substackcdn.com/image/fetch/$s_!wLkc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25279443-cf58-48b2-86f6-98122156302a_2482x1184.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wLkc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25279443-cf58-48b2-86f6-98122156302a_2482x1184.png" width="1456" height="695" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/25279443-cf58-48b2-86f6-98122156302a_2482x1184.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:695,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:328486,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wLkc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25279443-cf58-48b2-86f6-98122156302a_2482x1184.png 424w, https://substackcdn.com/image/fetch/$s_!wLkc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25279443-cf58-48b2-86f6-98122156302a_2482x1184.png 848w, https://substackcdn.com/image/fetch/$s_!wLkc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25279443-cf58-48b2-86f6-98122156302a_2482x1184.png 1272w, https://substackcdn.com/image/fetch/$s_!wLkc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25279443-cf58-48b2-86f6-98122156302a_2482x1184.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Tinder High-level architecture</strong></figcaption></figure></div><p>During this process, you will get an idea of what fields are relevant for each data model. Hence, mention the important fields and ignore the redundant ones. For eg: Don&#8217;t spend time on attributes such as <em><strong>firstName</strong></em>, <em><strong>lastName</strong></em> for the <em><strong>User</strong></em> entity.</p><p>At the end, you must ensure that your high-level architecture meets all the functional requirements that were stated in the beginning.</p><h3>Dive deep, Trade-offs and bottlenecks - 20 mins</h3><p>After sketching the high-level design, you need to come up with a comprehensive design. In this step, you will vet whether your design meets all your non-functional requirements and constraints.</p><p>You must dive deep into each flow and justify the choice that you have made. For eg: Explain why PostgreSQL is preferred over Cassandra or DynamoDB. Similarly, rectify and use the correct data store or caching mechanisms to optimize and meet any latency constraints.</p><p>Often, there would be multiple approaches to solve the same problem. For eg: You can use Geo-sharding index provided by PostgreSQL or Elastic Search for finding nearest restaurants or cabs. In such cases, explain the pros/cons of each and why you prefer one over the other in the context of the problem.</p><p>Finally, identify the bottlenecks in your design and explain how you would address each. This could be hotspots or handling sudden burst of traffic. These are solved problems and it&#8217;s important to have a strong hold on fundamentals to tackle them.</p><p>You must make sure that your solution is complete and meets both the functional and non-functional requirements. Also, give the interviewer chance to speak and check if they need to probe any particular area during the discussion.</p><h2>Conclusion</h2><p>System design interviews can be challenging and often involve problems that companies take months or years to solve.</p><p>However, don't let this overwhelm you. A structured approach can help you showcase your skills effectively.</p><p>If you're struggling with system design problems, try applying a six-step approach and practicing interview questions. This method shows your ability to break down complex problems, propose simple solutions, and optimize further.</p><p>Now that you have learnt the six-step approach, try applying the same to problems such as :- </p><ol><li><p>Design a Instagram newsfeed system</p></li><li><p>Design an online judge</p></li><li><p>Design a distributed job scheduler</p></li><li><p>Design a distributed web crawler</p></li></ol><p>After attempting these problems, you can look at the solutions and see how you fared.</p><p>Also, check out these links&#8212;they're helpful for system design interview preparation -</p><ol><li><p><a href="https://www.systemdesignhandbook.com/">System design handbook</a></p></li><li><p><a href="https://www.educative.io/courses/grokking-the-system-design-interview">Educative.io - Grokking the system design interview</a></p></li><li><p><a href="https://www.educative.io/learn-to-code">Educative.io - Learn to code</a></p></li></ol><p>Improving at system design requires patience, perseverance, and hard work. Consistency is key, and the journey will ultimately make you a better engineer. &#128640; &#128640;</p><p>Before you go:</p><ul><li><p>&#10084;&#65039; the story and follow the newsletter for more such articles</p></li><li><p>&#128276; Follow me: <a href="https://www.linkedin.com/in/animesh-gaitonde/">LinkedIn</a>, <a href="https://twitter.com/animesh3436">Twitter</a>, <a href="https://medium.com/@animeshgaitonde">Medium</a></p></li><li><p>Your support helps keep this newsletter free and fuels future content. Consider a small donation to show your appreciation here - <a href="https://www.paypal.com/ncp/payment/EUGP54EHQFDZC">Paypal Donate</a></p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/system-design-interview-success-six-step-framework?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/p/system-design-interview-success-six-step-framework?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p>]]></content:encoded></item><item><title><![CDATA[Designing Real-Time Collaborative Systems: A Deep Dive into Mouse Pointer Tracking]]></title><description><![CDATA[A decade ago, system design interview questions were broad, like "Design Facebook" or "Design WhatsApp," which were too complex to cover in an hour.]]></description><link>https://engineeringatscale.substack.com/p/designing-real-time-collaborative</link><guid isPermaLink="false">https://engineeringatscale.substack.com/p/designing-real-time-collaborative</guid><dc:creator><![CDATA[Animesh Gaitonde]]></dc:creator><pubDate>Sun, 06 Oct 2024 16:44:03 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/74543594-4448-429b-a526-03596455e1ef_2298x1578.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A decade ago, system design interview questions were broad, like "Design Facebook" or "Design WhatsApp," which were too complex to cover in an hour. Candidates began memorizing answers, but struggled when interviewers asked deeper questions.</p><p>Over time, the focus shifted to smaller sub-systems, like newsfeeds or notification systems, which fit within the interview timeframe. These problems often reflect real challenges companies have faced, allowing them to evaluate a candidate's approach. </p><p>Companies sometimes share these issues in blog posts, so it's crucial for developers to stay updated by reading them.</p><p>In today&#8217;s article, we'll explore a real-time mouse pointer system, inspired by a problem solved by Canva. We'll treat it as a system design question, create a solution, and discuss the trade-offs. If you're preparing for system design interviews, this article will guide you on how to approach them. Let's begin!</p><p><strong>Note</strong>: - <a href="https://www.canva.dev/blog/engineering/realtime-mouse-pointers/">This article is inspired by Canva&#8217;s article on how they designed real-time mouse pointer movements</a>. Credits and Kudos to the Canva&#8217;s Engineering team for their efforts.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/subscribe?"><span>Subscribe now</span></a></p><h2>Problem Statement</h2><div><hr></div><p><strong>Design a collaborative editing system which shows the real-time mouse pointer movements of the editors or the viewers.</strong> </p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5sKb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9bf9ea2-bf95-4a3c-b80b-b413656719cd_1722x728.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5sKb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9bf9ea2-bf95-4a3c-b80b-b413656719cd_1722x728.png 424w, https://substackcdn.com/image/fetch/$s_!5sKb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9bf9ea2-bf95-4a3c-b80b-b413656719cd_1722x728.png 848w, https://substackcdn.com/image/fetch/$s_!5sKb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9bf9ea2-bf95-4a3c-b80b-b413656719cd_1722x728.png 1272w, https://substackcdn.com/image/fetch/$s_!5sKb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9bf9ea2-bf95-4a3c-b80b-b413656719cd_1722x728.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5sKb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9bf9ea2-bf95-4a3c-b80b-b413656719cd_1722x728.png" width="1456" height="616" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d9bf9ea2-bf95-4a3c-b80b-b413656719cd_1722x728.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:616,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:73908,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5sKb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9bf9ea2-bf95-4a3c-b80b-b413656719cd_1722x728.png 424w, https://substackcdn.com/image/fetch/$s_!5sKb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9bf9ea2-bf95-4a3c-b80b-b413656719cd_1722x728.png 848w, https://substackcdn.com/image/fetch/$s_!5sKb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9bf9ea2-bf95-4a3c-b80b-b413656719cd_1722x728.png 1272w, https://substackcdn.com/image/fetch/$s_!5sKb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9bf9ea2-bf95-4a3c-b80b-b413656719cd_1722x728.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Two different dashboards showing the user&#8217;s mouse pointers</strong></figcaption></figure></div><h2>Clarifying questions</h2><p>Before proposing a design, clarify assumptions and ask relevant questions. Here are some questions to ask your interviewer: </p><ol><li><p>What should the collaborative editor display to the users ?</p></li><li><p>What should happen on the screen when a user moves their mouse pointer ?</p></li><li><p>How will we differentiate mouse pointers&#8212;by colour or usernames?</p></li><li><p>Should we design the editing features or focus only on mouse pointer movements?</p></li><li><p>What happens when a new user joins or an existing user disconnects ?</p></li></ol><p>These questions help define the functional requirements of your system, influencing your API design and the workflows.</p><p>Additionally, discuss system constraints, such as :</p><ol><li><p>What is the expected scale and how many concurrent users can the system handle?</p></li><li><p>Should the system track and store all mouse movement history?</p></li><li><p>What is the required availability? Should it aim for zero downtime with a 99.99% SLA?</p></li><li><p>How much lag in milliseconds is acceptable for the mouse movement?</p></li><li><p>How accurately should the system display the mouse pointer movements?</p></li></ol><p>Take notes on the interviewer&#8217;s answers and keep these constraints in mind while designing the system.</p><p>Let&#8217;s now define the functional and non-functional requirements for the system. (PS - The following requirements my differ based on the interviewer)</p><h3>Functional requirements (FR)</h3><ol><li><p>Users should see the collaborative editor screen and view other users working on the same document. <strong>FR-1</strong></p></li><li><p>All users should see each other's mouse movements on the screen in real-time. <strong>FR-2</strong></p></li><li><p>Each user's mouse pointer must display their username. <strong>FR-3</strong></p></li><li><p>The feature should focus solely on showing the mouse movements, not the collaborative editing. <strong>FR-4</strong></p></li><li><p>When a new user joins, their mouse pointer should appear on all the screens. If a user disconnects, their pointer should be hidden from all the screens. <strong>FR-5</strong></p></li></ol><h3>Non-Functional requirements (NFR)</h3><ol><li><p>The system must handle mouse movements from <strong>100K online users</strong> with a high throughput. <strong>NFR-1</strong></p></li><li><p>The system should not keep a history of user&#8217;s mouse locations; it must only display the current position and the movement. <strong>NFR-2</strong></p></li><li><p>The system must be highly available with zero downtime and <strong>99.99% availability</strong>, functioning without errors during upgrades or deployments. <strong>NFR-3</strong></p></li><li><p>The system&#8217;s <strong>p99</strong> latency for mouse pointer movements should be under <strong>50 ms</strong> for a seamless user experience. <strong>NFR-4</strong></p></li><li><p>Mouse movements <strong>do not need 100% accuracy</strong>; a tolerance of <strong>5-10%</strong> is acceptable. <strong>NFR-5</strong></p></li></ol><p>Now that we have clear idea of the system&#8217;s requirements, our next step is to come up with a design, define the data models and identify the different workflows.</p><h2>Detailed Design &amp; Choices</h2><p>We will now outline the different actors, their interactions, the data flow, and methods for storing and propagating the data.</p><h3>Actors</h3><ol><li><p><strong>Clients</strong> - Desktop Web Browsers will connect with the backend servers. Further, they would periodically pass the mouse pointer&#8217;s location on the screen. We will assume that the client-side libraries would capture this information and send it to the servers.</p></li><li><p><strong>Servers </strong>- The servers would be responsible for the following functionalities :- </p><ol><li><p>Managing the client connections.</p></li><li><p>Processing the mouse pointer updates from the clients.</p></li><li><p>Passing the mouse pointer update from one client to other clients working on the same document.</p></li></ol></li></ol><h3>Data models</h3><p>The data exchanged between the client and the server falls into the following categories :-</p><ol><li><p><strong>New connection</strong> - Client initiates a connection and sends the document on which it is working along with the mouse pointer&#8217;s current location. (<strong>FR-1</strong>)</p></li><li><p><strong>Mouse pointer movements</strong> - Clients would send this as soon as the user&#8217;s mouse moves. (<strong>FR-2,FR-3, FR-4</strong>)</p></li><li><p><strong>User disconnection</strong> -  The server would have to hide the mouse pointer from other users in case one user disconnects. (<strong>FR-5</strong>)</p></li></ol><p>Out of the above, <strong>2 </strong>would have a very high volume. We can let the client send the mouse&#8217;s updated location three times every second without compromising mouse pointer&#8217;s accuracy on UI (<strong>NFR-5, Clarify this assumption with the interviewer</strong>).</p><p>Additionally, the system need strong reliability guarantees for <strong>1</strong> and <strong>3 </strong>and they shouldn&#8217;t get missed (<strong>FR-5</strong>). In case the updates are missed, the user&#8217;s experience wouldn&#8217;t be accurate. For eg:- Showing an offline user online. It&#8217;s fine if the system misses mouse pointer movements as the accuracy wouldn&#8217;t be compromised much (<strong>NFR-5</strong>).</p><p>Let&#8217;s look at the sample data for the three categories. </p><h4>New connection</h4><pre><code>{
  "eventType": "<strong>NewConnection</strong>",
  "userId": "user123",
  "username": "JohnDoe",
  "documentId": "doc987",
  "mousePointer": {
    "x": 250,
    "y": 300
  },
  "timestamp": "2024-10-06T12:34:56Z"
}
</code></pre><h4><strong>Mouse pointer movements</strong></h4><pre><code>{
  "eventType": "<strong>MouseMovement</strong>",
  "userId": "user123",
  "documentId": "doc987",
  "mousePointer": {
    "x": 320,
    "y": 450
  },
  "timestamp": "2024-10-06T12:35:10Z"
}</code></pre><h4>User disconnection</h4><pre><code>{
  "eventType": "<strong>UserDisconnection</strong>",
  "userId": "user123",
  "documentId": "doc987",
  "timestamp": "2024-10-06T12:36:00Z"
}</code></pre><p>In certain cases, the user may not explicitly leave the screen. For eg:- browser or device crash. In such cases, the server would have to identify the disconnected client and communicate the new state to the other users.</p><h3>Workflows</h3><h4>Client-Server interaction</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PE_K!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10fe091-ed97-4414-9a6e-0d1dcd094846_1290x742.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PE_K!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10fe091-ed97-4414-9a6e-0d1dcd094846_1290x742.png 424w, https://substackcdn.com/image/fetch/$s_!PE_K!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10fe091-ed97-4414-9a6e-0d1dcd094846_1290x742.png 848w, https://substackcdn.com/image/fetch/$s_!PE_K!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10fe091-ed97-4414-9a6e-0d1dcd094846_1290x742.png 1272w, https://substackcdn.com/image/fetch/$s_!PE_K!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10fe091-ed97-4414-9a6e-0d1dcd094846_1290x742.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PE_K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10fe091-ed97-4414-9a6e-0d1dcd094846_1290x742.png" width="1290" height="742" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b10fe091-ed97-4414-9a6e-0d1dcd094846_1290x742.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:742,&quot;width&quot;:1290,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:63533,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!PE_K!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10fe091-ed97-4414-9a6e-0d1dcd094846_1290x742.png 424w, https://substackcdn.com/image/fetch/$s_!PE_K!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10fe091-ed97-4414-9a6e-0d1dcd094846_1290x742.png 848w, https://substackcdn.com/image/fetch/$s_!PE_K!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10fe091-ed97-4414-9a6e-0d1dcd094846_1290x742.png 1272w, https://substackcdn.com/image/fetch/$s_!PE_K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10fe091-ed97-4414-9a6e-0d1dcd094846_1290x742.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Client-Server communication</strong></figcaption></figure></div><p>The clients would need to maintain a persistent connection with the backend servers. The server would need to relay one client&#8217;s mouse update to all other clients. Hence, we would need bi-directional communication between the clients and the servers.</p><p><strong>Websockets </strong>would solve the use case for real-time communication between the client and the server. (<strong>FRs 1-5</strong>). Further, it would have low overhead and latency meeting (<strong>NFR-4)</strong>.</p><p>Moreover, the clients would connect to a <strong>LoadBalancer</strong> which would efficiently distribute the traffic among the different backend servers. The <strong>least loaded load balancing strategy</strong> would be appropriate to ensure even distribution of connections.</p><p>Note that in the above setup, clients working on the same doc may get connected to different servers. This avoids making a server single point of failure and doesn&#8217;t make a single server a <strong>hotspot</strong> thereby improving the availability (<strong>NFR-3).</strong></p><p>Additionally, in case of upgrades and server restarts, the clients would reconnect and the LoadBalancer would rebalance the connection ensuring high availability (<strong>NFR-3</strong>). </p><h4>User connection &amp; disconnection</h4><p>The server needs to handle when a user connects or disconnects and inform all the other users about the change. Since each user connects to a different server, all servers must know where each user is connected. This way, updates are sent to the right servers, which then pass them on to their users.</p><p>To solve this problem, every server must have a view of the session state. The session state would consists of :- </p><ol><li><p>DocumentId - identifier of the document.</p></li><li><p>List of users working on the document, and their corresponding severs.</p></li></ol><p>When the session state changes, one server must notify all others. Others servers must updates their session state view accordingly.</p><p>For <strong>strong reliability, low-latency, </strong>and<strong> high throughput</strong>, <strong>Redis Streams</strong> is ideal for exchanging session state. This ensures that server restarts or deployments won't cause issues, as servers can read data sequentially from a <strong>reliable stream</strong>.</p><p>Each server will read from its own dedicated Redis Stream and write to all other servers' Streams.</p><p>The below diagram illustrates the process in detail :</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!u9Sm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5086ed8a-e85b-4ac5-a903-5d538390836c_2148x1484.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!u9Sm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5086ed8a-e85b-4ac5-a903-5d538390836c_2148x1484.png 424w, https://substackcdn.com/image/fetch/$s_!u9Sm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5086ed8a-e85b-4ac5-a903-5d538390836c_2148x1484.png 848w, https://substackcdn.com/image/fetch/$s_!u9Sm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5086ed8a-e85b-4ac5-a903-5d538390836c_2148x1484.png 1272w, https://substackcdn.com/image/fetch/$s_!u9Sm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5086ed8a-e85b-4ac5-a903-5d538390836c_2148x1484.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!u9Sm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5086ed8a-e85b-4ac5-a903-5d538390836c_2148x1484.png" width="1456" height="1006" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5086ed8a-e85b-4ac5-a903-5d538390836c_2148x1484.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1006,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:268680,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!u9Sm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5086ed8a-e85b-4ac5-a903-5d538390836c_2148x1484.png 424w, https://substackcdn.com/image/fetch/$s_!u9Sm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5086ed8a-e85b-4ac5-a903-5d538390836c_2148x1484.png 848w, https://substackcdn.com/image/fetch/$s_!u9Sm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5086ed8a-e85b-4ac5-a903-5d538390836c_2148x1484.png 1272w, https://substackcdn.com/image/fetch/$s_!u9Sm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5086ed8a-e85b-4ac5-a903-5d538390836c_2148x1484.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Client-Server connection/disconnection via Redis Streams</strong></figcaption></figure></div><h4>Mouse pointer updates</h4><p>On processing the mouse pointer update, the server would have to lookup the clients working on the document and their corresponding servers. It would have to then send the message to all the other servers.</p><p>Redis Pub/Sub would be best solution for this use case since the mouse pointer updates have following characteristics :-</p><ol><li><p>Low-latency delivery (<strong>NFR-4</strong>) - Redis Pub/Sub guarantees real-time quick communication between the clients.</p></li><li><p>Transient messages (<strong>NFR-2, NFR-5</strong>) - Redis Pub/Sub doesn&#8217;t retain the messages if the clients don&#8217;t consume it. Also, it&#8217;s fine to lose a couple of updates during server restarts.</p></li><li><p>Throughput (<strong>NFR-1</strong>) -  Pub/Sub handles real-time updates with high throughput and ideal for collaborative editing use cases. </p></li></ol><p>The <strong>documentId </strong>can be used as a Pub/Sub topic. All the server instances handling a document, would subscribe to this topic. </p><p>Any server receiving an update would add the update in the topic. All other server instances would immediately receive the latest mouse pointer update and process it.</p><p>Further, the server instance can unsubscribe if it doesn&#8217;t have any client working on a particular document. And subscribe as soon as it finds a new client working on a given document.</p><p>The following diagram illustrates how the mouse pointer update originates from one client and gets propagated to other clients working on the same document.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kxbU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e6a85ba-3c81-4370-8b9d-aa80d70f1fdf_2298x1578.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kxbU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e6a85ba-3c81-4370-8b9d-aa80d70f1fdf_2298x1578.png 424w, https://substackcdn.com/image/fetch/$s_!kxbU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e6a85ba-3c81-4370-8b9d-aa80d70f1fdf_2298x1578.png 848w, https://substackcdn.com/image/fetch/$s_!kxbU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e6a85ba-3c81-4370-8b9d-aa80d70f1fdf_2298x1578.png 1272w, https://substackcdn.com/image/fetch/$s_!kxbU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e6a85ba-3c81-4370-8b9d-aa80d70f1fdf_2298x1578.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kxbU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e6a85ba-3c81-4370-8b9d-aa80d70f1fdf_2298x1578.png" width="1456" height="1000" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5e6a85ba-3c81-4370-8b9d-aa80d70f1fdf_2298x1578.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1000,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:392481,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kxbU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e6a85ba-3c81-4370-8b9d-aa80d70f1fdf_2298x1578.png 424w, https://substackcdn.com/image/fetch/$s_!kxbU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e6a85ba-3c81-4370-8b9d-aa80d70f1fdf_2298x1578.png 848w, https://substackcdn.com/image/fetch/$s_!kxbU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e6a85ba-3c81-4370-8b9d-aa80d70f1fdf_2298x1578.png 1272w, https://substackcdn.com/image/fetch/$s_!kxbU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e6a85ba-3c81-4370-8b9d-aa80d70f1fdf_2298x1578.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Mouse pointer update propagation</strong></figcaption></figure></div><h2>Trade-offs</h2><p>We will now justify the choices that we have made in the above design. In system design, there is no right or wrong answer, and we choose the best option that meets our requirements.</p><h3>Client-Server communication - WebSockets.</h3><p>HTTP alternatives such as polling would introduce additional latency and an overhead. This would result in inefficient resource usage and slow updates (violates <strong>NFR-4</strong>).</p><p>Hence, WebSockets would be suitable for our use case of collaborative editing with frequent updates that need minimum latency. </p><p><strong>Trade-off decision:</strong> Given the need for low-latency, real-time updates, WebSockets are the optimal choice for client-server communication in this use case.</p><h3>Session data - Redis Streams</h3><p>Redis Streams provide strong reliability guarantees even if a server goes offline. The server can process missed messages even after restarts.</p><p>However, they require more overhead compared to Pub/Sub, making them less ideal for high-frequency, non-critical updates like mouse movements.</p><p><strong>Trade-off decision:</strong> For session state data, where reliability and message delivery guarantees are critical, Redis Streams are the best solution despite the additional overhead. Since the frequency of connections/disconnections is much lower (about 1/1000th of mouse pointer updates), the overhead is manageable.</p><h3>Mouse pointer updates - Redis Pub-Sub</h3><p>Redis Pub/Sub allows for real-time broadcasting of messages, making it ideal for high-frequency, transient data like mouse pointer movements.</p><p>Pub/Sub doesn&#8217;t guarantee reliable delivery of messages in case the subscribers go down. Hence, subscribers would miss the updates.</p><p><strong>Trade-off decision: </strong>Given the high frequency of mouse pointer updates and the need for speed over durability, Redis Pub/Sub is the best choice for this type of data exchange.</p><h3>Serialization format</h3><p>The mouse pointer and session update data can be exchanged between client-server using JSON. JSON is human-readable and easier to debug. However, with large volume of messages, the CPU consumption would spike.</p><p>Binary serialization is faster and uses less CPU. Hence, a compact binary serialization would be appropriate for this use case. </p><p><strong>Trade-off decision</strong>: Given the high frequency of mouse pointer updates, we must prioritize performance over the convenience of debugging, making binary serialization the better choice.</p><h3>Redis Commands for Mouse pointer updates</h3><p><strong>Flushing Redis commands</strong>: The server can push every mouse pointer update to the Redis Pub-Sub. However, this would be a resource intensive operation. And the system wouldn&#8217;t scale to handle large throughput of messages. </p><p><strong>Batching Redis commands : </strong>Batching the Redis PubSub commands within specific intervals would result in better resource utilization. </p><p><strong>Trade-off decision</strong>:  Although batching results in slight delay of messages (because commands are sent together at intervals), but this is outweighed by the reduction in CPU usage. Since mouse movements don&#8217;t require millisecond-level precision, this was an acceptable trade-off. (<strong>NFR-4</strong>)</p><h2>Conclusion</h2><p>Now, we have a collaborative editing system that shows the real-time mouse pointer movements of the editors or viewers. The design meets all the functional and non-functional requirements that we had listed in the beginning.</p><p>In a nutshell, the design addresses the following aspects :-</p><ol><li><p><strong>Client-Server communication</strong> - Uses <strong>Websockets</strong> for bi-directional communication and low-latency. The <strong>LoadBalancer</strong> ensures high availability and even traffic distribution.</p></li><li><p><strong>Session data</strong> - The system relies on <strong>Redis Streams </strong>to manage and propagate the session data. It ensures that all the servers have a consistent view of users viewing a given document.</p></li><li><p><strong>Mouse movements</strong> - <strong>Redis Pub/Sub</strong> provides low-latency, real-time &amp; high-frequency mouse pointer updates.</p></li></ol><p>In this article, we learnt a methodical approach to tackle any ambiguous system design problem. You can remember this and apply the technique in your next system design interview.</p><p>We came up with the above design assuming that the client would send 3 updates every second. Do you think the above design would scale in case we want to send 60 updates ? </p><p>Are there any bottlenecks in the design to handle 60 updates/sec ? If yes, how can we overcome them ? Leave your thoughts in the comments below.</p><p>For more information of Redis Streams, you can refer my article <a href="https://engineeringatscale.substack.com/p/redis-streams-guide-real-time-data-processing">here</a>. </p><p>Before you go:</p><ul><li><p>&#10084;&#65039; the story and follow the newsletter for more such articles</p></li><li><p>&#128276; Follow me: <a href="https://www.linkedin.com/in/animesh-gaitonde/">LinkedIn</a>, <a href="https://twitter.com/animesh3436">Twitter</a>, <a href="https://medium.com/@animeshgaitonde">Medium</a></p></li><li><p>Your support helps keep this newsletter free and fuels future content. Consider a small donation to show your appreciation here - <a href="https://www.paypal.com/ncp/payment/EUGP54EHQFDZC">Paypal Donate</a></p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/designing-real-time-collaborative?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/p/designing-real-time-collaborative?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><h2>References</h2><ol><li><p><a href="https://www.canva.dev/blog/engineering/realtime-mouse-pointers/">How Canva designed real-time mouse pointer updates</a></p></li></ol>]]></content:encoded></item><item><title><![CDATA[Redis Streams: Ultimate Guide to Real-Time Data Processing]]></title><description><![CDATA[Dive deep into Redis Streams, pros, cons and real-world use cases]]></description><link>https://engineeringatscale.substack.com/p/redis-streams-guide-real-time-data-processing</link><guid isPermaLink="false">https://engineeringatscale.substack.com/p/redis-streams-guide-real-time-data-processing</guid><dc:creator><![CDATA[Animesh Gaitonde]]></dc:creator><pubDate>Sat, 28 Sep 2024 11:39:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!5fEc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b094ff8-0518-4bed-820a-b05a0fac7647_1770x834.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5fEc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b094ff8-0518-4bed-820a-b05a0fac7647_1770x834.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5fEc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b094ff8-0518-4bed-820a-b05a0fac7647_1770x834.png 424w, https://substackcdn.com/image/fetch/$s_!5fEc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b094ff8-0518-4bed-820a-b05a0fac7647_1770x834.png 848w, https://substackcdn.com/image/fetch/$s_!5fEc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b094ff8-0518-4bed-820a-b05a0fac7647_1770x834.png 1272w, https://substackcdn.com/image/fetch/$s_!5fEc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b094ff8-0518-4bed-820a-b05a0fac7647_1770x834.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5fEc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b094ff8-0518-4bed-820a-b05a0fac7647_1770x834.png" width="1456" height="686" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2b094ff8-0518-4bed-820a-b05a0fac7647_1770x834.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:686,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:366727,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5fEc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b094ff8-0518-4bed-820a-b05a0fac7647_1770x834.png 424w, https://substackcdn.com/image/fetch/$s_!5fEc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b094ff8-0518-4bed-820a-b05a0fac7647_1770x834.png 848w, https://substackcdn.com/image/fetch/$s_!5fEc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b094ff8-0518-4bed-820a-b05a0fac7647_1770x834.png 1272w, https://substackcdn.com/image/fetch/$s_!5fEc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b094ff8-0518-4bed-820a-b05a0fac7647_1770x834.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://redis.io/learn/howtos/solutions/streams/streaming-llm-output">Streaming LLM output using Redis Streams</a></figcaption></figure></div><p>In the past decade, streaming data has seen a meteoric growth. From mobile phones, sensors, tablets, to home pc, streaming data is everywhere.</p><p>This explosive increase has driven the development of several software solutions designed to manage and process streaming data efficiently. In 2011, LinkedIn developed Kafka, which was later open-sourced. Similarly, Redis introduced Redis Streams in version 5.0.</p><p>Recently, a friend of mine was giving a system design interview. He was asked a question related to Task queue management.</p><p>He proposed a solution using Redis Streams, but when the interviewer asked him to justify his choice over Kafka, he struggled to explain the trade-offs. He couldn&#8217;t clearly explain the trade-offs and got rejected. The feedback mentioned that he lacked the technical depth and needs to work on it.</p><p>The lesson here is clear: mastering the fundamentals is essential. Knowing the latest technology doesn&#8217;t guarantee success in system design interviews if you can&#8217;t articulate the reasoning behind your choices.</p><p>In this article, we will dive deep into Redis Streams. We'll start by covering its core concepts and architecture, followed by an analysis of its pros and cons. Subsequently, we will compare and contrast Redis Streams with Redis Pub-Sub and Kafka and go through real-world examples.</p><p>By the end of this article, I am sure that you would understand the working and application of Redis Stream. And also confidently justify the choice in your next system design interview. Let&#8217;s dive in.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Engineering At Scale is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><div><hr></div><h2><strong>Boost Your Skills with Educative (Plus an Extra 10% Discount!)</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XTvR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa8acf51-f9ea-40b5-8fe2-4854ff6668d4_318x159.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XTvR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa8acf51-f9ea-40b5-8fe2-4854ff6668d4_318x159.jpeg 424w, https://substackcdn.com/image/fetch/$s_!XTvR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa8acf51-f9ea-40b5-8fe2-4854ff6668d4_318x159.jpeg 848w, https://substackcdn.com/image/fetch/$s_!XTvR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa8acf51-f9ea-40b5-8fe2-4854ff6668d4_318x159.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!XTvR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa8acf51-f9ea-40b5-8fe2-4854ff6668d4_318x159.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XTvR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa8acf51-f9ea-40b5-8fe2-4854ff6668d4_318x159.jpeg" width="318" height="159" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/aa8acf51-f9ea-40b5-8fe2-4854ff6668d4_318x159.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:159,&quot;width&quot;:318,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:5214,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://engineeringatscale.substack.com/i/149521224?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa8acf51-f9ea-40b5-8fe2-4854ff6668d4_318x159.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XTvR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa8acf51-f9ea-40b5-8fe2-4854ff6668d4_318x159.jpeg 424w, https://substackcdn.com/image/fetch/$s_!XTvR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa8acf51-f9ea-40b5-8fe2-4854ff6668d4_318x159.jpeg 848w, https://substackcdn.com/image/fetch/$s_!XTvR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa8acf51-f9ea-40b5-8fe2-4854ff6668d4_318x159.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!XTvR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa8acf51-f9ea-40b5-8fe2-4854ff6668d4_318x159.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Ace your coding interviews with Educative&#8217;s proven prep paths used by engineers at <strong>Google</strong>, <strong>Amazon</strong>, and <strong>Meta</strong>.<br>Get an exclusive <strong>10% discount</strong> when you sign up through this <strong><a href="https://www.educative.io/unlimited?aff=BYJl">link</a></strong>.<br>No setup, no distractions &#8212; just structured learning, real problems, and smart solutions.</p><div><hr></div><h2>Redis Streams Concepts</h2><p>Streaming data is the data that is generated continuously. A popular example is the logging and metric data generated by software systems in enterprises.</p><p>The data has high throughput &amp; is mostly used by analytics and post-processing workloads. Apache Kafka, Apache Flink, Amazon Kinesis, etc are some solutions for managing streaming data.</p><h3>Redis Stream</h3><p>Redis Stream is a data structure that persists real-time streaming data. It stores the data in an append-only fashion. Any data added to a Redis Stream is immutable.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PJPw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff11dd5d6-af1f-462a-b8f8-0f2114c22f8b_1914x576.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PJPw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff11dd5d6-af1f-462a-b8f8-0f2114c22f8b_1914x576.png 424w, https://substackcdn.com/image/fetch/$s_!PJPw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff11dd5d6-af1f-462a-b8f8-0f2114c22f8b_1914x576.png 848w, https://substackcdn.com/image/fetch/$s_!PJPw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff11dd5d6-af1f-462a-b8f8-0f2114c22f8b_1914x576.png 1272w, https://substackcdn.com/image/fetch/$s_!PJPw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff11dd5d6-af1f-462a-b8f8-0f2114c22f8b_1914x576.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PJPw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff11dd5d6-af1f-462a-b8f8-0f2114c22f8b_1914x576.png" width="1456" height="438" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f11dd5d6-af1f-462a-b8f8-0f2114c22f8b_1914x576.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:438,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:75623,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!PJPw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff11dd5d6-af1f-462a-b8f8-0f2114c22f8b_1914x576.png 424w, https://substackcdn.com/image/fetch/$s_!PJPw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff11dd5d6-af1f-462a-b8f8-0f2114c22f8b_1914x576.png 848w, https://substackcdn.com/image/fetch/$s_!PJPw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff11dd5d6-af1f-462a-b8f8-0f2114c22f8b_1914x576.png 1272w, https://substackcdn.com/image/fetch/$s_!PJPw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff11dd5d6-af1f-462a-b8f8-0f2114c22f8b_1914x576.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Redis Streams</strong></figcaption></figure></div><h3>Stream Entry</h3><p>Redis Stream consists of series of stream entries. Each stream entry has a unique id (timestamp) and consists of multiple key-value pairs.</p><p>Adding a stream entry is a O(1) operation since it's append-only operation. Similarly, fetching an entry from the stream is a O(K) operation where K is the length of the id. Since, K is constant, fetching an entry is a constant operation. Internally, Redis Streams store the entries in a Radix tree.</p><p>Below diagram illustrates a Redis Stream Customer Orders consisting of a series of entries.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Bs1a!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67c20471-c691-4ccb-967e-ebe88f63c66b_1934x548.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Bs1a!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67c20471-c691-4ccb-967e-ebe88f63c66b_1934x548.png 424w, https://substackcdn.com/image/fetch/$s_!Bs1a!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67c20471-c691-4ccb-967e-ebe88f63c66b_1934x548.png 848w, https://substackcdn.com/image/fetch/$s_!Bs1a!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67c20471-c691-4ccb-967e-ebe88f63c66b_1934x548.png 1272w, https://substackcdn.com/image/fetch/$s_!Bs1a!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67c20471-c691-4ccb-967e-ebe88f63c66b_1934x548.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Bs1a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67c20471-c691-4ccb-967e-ebe88f63c66b_1934x548.png" width="1456" height="413" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/67c20471-c691-4ccb-967e-ebe88f63c66b_1934x548.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:413,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:101357,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Bs1a!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67c20471-c691-4ccb-967e-ebe88f63c66b_1934x548.png 424w, https://substackcdn.com/image/fetch/$s_!Bs1a!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67c20471-c691-4ccb-967e-ebe88f63c66b_1934x548.png 848w, https://substackcdn.com/image/fetch/$s_!Bs1a!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67c20471-c691-4ccb-967e-ebe88f63c66b_1934x548.png 1272w, https://substackcdn.com/image/fetch/$s_!Bs1a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67c20471-c691-4ccb-967e-ebe88f63c66b_1934x548.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The Streams are stored in-memory and are backed up through persistance (AOF or RDB file). Redis Streams are high-performing since all the operations are in-memory operations and avoids any disk I/O.</p><h3>Producer &amp; Consumers</h3><p>Multiple producer applications can add data to a stream. And several consumer applications can read data from the same stream. This decouples producers from consumers.</p><h3>Reading &amp; Deletion</h3><p>Redis streams work on a pull model. Consumers are responsible for pulling the stream entries. </p><p>Once a stream entry is added to a stream, it exists until it&#8217;s explicitly deleted. Unlike pub-sub, the messages are not lost if the consumers are not connected.</p><p>Multiple consumers can read from a given stream without any side-effect on other consumers.</p><h3>Consumer groups</h3><p>A single consumer reads the entries from a Stream sequentially. This can lead to slowness in processing.</p><p>For scalability, Redis Streams introduces a concept of Consumer groups. Consumer groups are made up of multiple consumer applications.</p><p>When a consumer group is assigned to a stream, multiple entries can be picked up in parallel by each consumer and processed. This improves the overall throughput of the system.</p><p>Note :- Redis guarantees that a single message wouldn&#8217;t be processed multiple times by multiple consumers within a consumer group.</p><p>The following example illustrates a simple messaging system that leverages Redis Streams :- </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jxqj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a93ed62-934e-4c3e-b566-17be4627753c_2976x1616.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jxqj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a93ed62-934e-4c3e-b566-17be4627753c_2976x1616.png 424w, https://substackcdn.com/image/fetch/$s_!jxqj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a93ed62-934e-4c3e-b566-17be4627753c_2976x1616.png 848w, https://substackcdn.com/image/fetch/$s_!jxqj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a93ed62-934e-4c3e-b566-17be4627753c_2976x1616.png 1272w, https://substackcdn.com/image/fetch/$s_!jxqj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a93ed62-934e-4c3e-b566-17be4627753c_2976x1616.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jxqj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a93ed62-934e-4c3e-b566-17be4627753c_2976x1616.png" width="1456" height="791" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7a93ed62-934e-4c3e-b566-17be4627753c_2976x1616.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:791,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:229014,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!jxqj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a93ed62-934e-4c3e-b566-17be4627753c_2976x1616.png 424w, https://substackcdn.com/image/fetch/$s_!jxqj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a93ed62-934e-4c3e-b566-17be4627753c_2976x1616.png 848w, https://substackcdn.com/image/fetch/$s_!jxqj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a93ed62-934e-4c3e-b566-17be4627753c_2976x1616.png 1272w, https://substackcdn.com/image/fetch/$s_!jxqj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a93ed62-934e-4c3e-b566-17be4627753c_2976x1616.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Redis Streams - Producers &amp; Consumers</strong></figcaption></figure></div><p>Now, that you have a good understanding of the fundamentals, let&#8217;s look at the advantages and disadvantages of using Redis Streams.</p><h2>Advantages</h2><ul><li><p><strong>High performance</strong> - In-memory storage results in low latencies and high throughput. Log-structured data model allows efficient reads and writes to Redis Streams.</p></li><li><p><strong>Flexible data model</strong> - The data model is schema-less and clients can store any set of key-value pairs.</p></li><li><p><strong>Integration with other Redis Data Structures</strong> - Streams can seamlessly integrate with other Redis Data Structures such as Lists, Sets and Hashes.</p></li><li><p><strong>Ease of use</strong> - Redis Streams provide APIs, CLIs and SDKs in multiple languages to manipulate the data structure.</p></li><li><p><strong>Time-series data</strong> -  Each stream entry contains an id field that has timestamp. All the stream entries are ordered and hence it makes it suitable for applications that need time-series data management. </p></li></ul><h2>Disadvantages</h2><ul><li><p><strong>Durability</strong> - As the data is stored in-memory, there is a risk of data loss. Hence, shouldn&#8217;t be preferred if you require strong durability guarantees.</p></li><li><p><strong>Limited message retention</strong> - Due to memory constraints, you can&#8217;t infinitely retain all the messages in a stream. Clients have to purge or configure Redis Streams to automatically purge the data.</p></li><li><p><strong>Complex event processing</strong> - Redis Streams don&#8217;t support complex event processing capabilities such as the ones provided by Apache Kafka or Apache Flink.</p></li></ul><p>Since you have understood the pros/cons of Redis Streams. Let&#8217;s now contrast Redis Streams with Redis Pub-Sub and Apache Kafka.</p><h2>Redis Streams Vs Redis Pub-Sub</h2><h3>Redis Pub-Sub</h3><p>Redis Pub-Sub (Publisher-Subscriber) is a data structure that stores the messages sent by producers and immediately sends it to consumers. In case a consumer doesn&#8217;t exist, then the message gets lost.</p><p>Below diagram illustrates how Redis Pub-Sub works.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Zyqx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9045419a-8575-4c75-b5b2-4d9a5427e5cf_1690x1080.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Zyqx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9045419a-8575-4c75-b5b2-4d9a5427e5cf_1690x1080.png 424w, https://substackcdn.com/image/fetch/$s_!Zyqx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9045419a-8575-4c75-b5b2-4d9a5427e5cf_1690x1080.png 848w, https://substackcdn.com/image/fetch/$s_!Zyqx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9045419a-8575-4c75-b5b2-4d9a5427e5cf_1690x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!Zyqx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9045419a-8575-4c75-b5b2-4d9a5427e5cf_1690x1080.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Zyqx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9045419a-8575-4c75-b5b2-4d9a5427e5cf_1690x1080.png" width="1456" height="930" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9045419a-8575-4c75-b5b2-4d9a5427e5cf_1690x1080.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:930,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:148771,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Zyqx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9045419a-8575-4c75-b5b2-4d9a5427e5cf_1690x1080.png 424w, https://substackcdn.com/image/fetch/$s_!Zyqx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9045419a-8575-4c75-b5b2-4d9a5427e5cf_1690x1080.png 848w, https://substackcdn.com/image/fetch/$s_!Zyqx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9045419a-8575-4c75-b5b2-4d9a5427e5cf_1690x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!Zyqx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9045419a-8575-4c75-b5b2-4d9a5427e5cf_1690x1080.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>Summary of differences</h3><p>The below table compares the different features and its support in Redis Streams &amp; Pub-Sub :- </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KyDJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7ea849-adea-4bc1-992f-3478e3450754_1848x1306.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KyDJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7ea849-adea-4bc1-992f-3478e3450754_1848x1306.png 424w, https://substackcdn.com/image/fetch/$s_!KyDJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7ea849-adea-4bc1-992f-3478e3450754_1848x1306.png 848w, https://substackcdn.com/image/fetch/$s_!KyDJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7ea849-adea-4bc1-992f-3478e3450754_1848x1306.png 1272w, https://substackcdn.com/image/fetch/$s_!KyDJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7ea849-adea-4bc1-992f-3478e3450754_1848x1306.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KyDJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7ea849-adea-4bc1-992f-3478e3450754_1848x1306.png" width="1456" height="1029" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ad7ea849-adea-4bc1-992f-3478e3450754_1848x1306.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1029,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:244555,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!KyDJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7ea849-adea-4bc1-992f-3478e3450754_1848x1306.png 424w, https://substackcdn.com/image/fetch/$s_!KyDJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7ea849-adea-4bc1-992f-3478e3450754_1848x1306.png 848w, https://substackcdn.com/image/fetch/$s_!KyDJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7ea849-adea-4bc1-992f-3478e3450754_1848x1306.png 1272w, https://substackcdn.com/image/fetch/$s_!KyDJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7ea849-adea-4bc1-992f-3478e3450754_1848x1306.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Redis Streams Vs Apache Kafka</h2><h3>Apache Kafka</h3><p>Apache Kafka is an open-source distributed event-streaming platform for building real-time data pipelines. There are many commonalities in the working of Kafka and Redis Streams, such as consumer groups, append-only data insertion, etc.</p><p>However, there are subtle differences in their architecture. Apache Kafka is designed to process high volumes of data with low latency. Additionally, it&#8217;s a distributed commit log and allows consumers to read and replay messages whenever needed.</p><p>Unlike Redis Streams, Apache Kafka guarantees data durability and protection from data loss. It also integrates with other stream processing frameworks, such as Apache Flink and Apache Spark.</p><h3>Summary of differences</h3><p>The following table captures the key differences between Redis Streams and Kafka:- </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yeX8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391d4edf-b7bb-4b05-a454-a7eab15b406b_1848x1310.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yeX8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391d4edf-b7bb-4b05-a454-a7eab15b406b_1848x1310.png 424w, https://substackcdn.com/image/fetch/$s_!yeX8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391d4edf-b7bb-4b05-a454-a7eab15b406b_1848x1310.png 848w, https://substackcdn.com/image/fetch/$s_!yeX8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391d4edf-b7bb-4b05-a454-a7eab15b406b_1848x1310.png 1272w, https://substackcdn.com/image/fetch/$s_!yeX8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391d4edf-b7bb-4b05-a454-a7eab15b406b_1848x1310.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yeX8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391d4edf-b7bb-4b05-a454-a7eab15b406b_1848x1310.png" width="1456" height="1032" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/391d4edf-b7bb-4b05-a454-a7eab15b406b_1848x1310.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1032,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:335253,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yeX8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391d4edf-b7bb-4b05-a454-a7eab15b406b_1848x1310.png 424w, https://substackcdn.com/image/fetch/$s_!yeX8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391d4edf-b7bb-4b05-a454-a7eab15b406b_1848x1310.png 848w, https://substackcdn.com/image/fetch/$s_!yeX8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391d4edf-b7bb-4b05-a454-a7eab15b406b_1848x1310.png 1272w, https://substackcdn.com/image/fetch/$s_!yeX8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391d4edf-b7bb-4b05-a454-a7eab15b406b_1848x1310.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>When to use Redis Streams ?</h2><p>Redis Streams are highly performant and can be leveraged for a wide array of use cases. Here is a list of use cases where Redis Streams are suitable :-</p><ol><li><p><strong>Task Queues</strong> - Simple task queues, such as sending email or SMS notifications, can be implemented via Redis Streams. The processing can be scaled by increasing the consumers in the consumer groups.</p></li><li><p><strong>Session management and activity tracking</strong> - Short-term user interactions, such as tracking online/offline users, can be managed through Redis Streams. Using Streams results in better performance due to in-memory operations.</p></li><li><p><strong>Lightweight event sourcing</strong> - Redis Streams can be used for event sourcing, where events are written first and processed asynchronously later. Its in-memory nature makes it suitable for low-latency event processing. However, it&#8217;s not suited to handle high-throughput events.</p></li><li><p><strong>Real-time analytics</strong> - Redis Streams are useful for real-time analytics that don&#8217;t require long-term data storage. For example, showing real-time metrics such as CPU usage, where only recent data is needed.</p></li></ol><h2>Conclusion</h2><p>Redis Streams is a versatile data structure that allows you to store a stream of events in-memory. It&#8217;s highly performant and offers a flexible data model for storing data.</p><p>Redis Streams is useful for developing asynchronous applications and decoupling producers from consumers. Redis Streams provides consumer groups to scale the processing of messages in a given stream.</p><p>The downside of using Redis Streams is that it doesn&#8217;t guarantee data durability and has limited message retention. Furthermore, it doesn&#8217;t support complex event processing like Apache Kafka and Apache Flink.</p><p>If message retention is needed, we must choose Redis Streams over Redis Pub/Sub. Redis Pub/Sub uses a fire-and-forget model and immediately deletes messages if they aren&#8217;t consumed by the consumers.</p><p>Apache Kafka is suitable for high-throughput applications that require stronger durability guarantees, while Redis Streams is suitable for applications that require high performance with weaker durability guarantees.</p><p>Earlier, I mentioned how my friend got rejected because he couldn&#8217;t explain why Redis Streams was the best fit for task queue management. Do you think Redis Streams would be the right answer for that problem? Let me know your thoughts in the comments.</p><h2>Case Studies</h2><p>Do take a look at the following case studies to further deepen your understanding and improve your system design skills:</p><ol><li><p><a href="https://www.canva.dev/blog/engineering/realtime-mouse-pointers/">Canva&#8217;s collaborative editing design</a> - Shows how they leveraged Redis Streams for session management and Redis Pub/Sub for mouse pointer tracking.</p></li><li><p><a href="https://blog.arcjet.com/replacing-kafka-with-redis-streams/">Arcjet&#8217;s use of Redis Streams</a> - Arcjet deliberated between building their own message processing system and leveraging Apache Kafka. They eventually chose Redis Streams, and it was scalable enough to meet their needs.</p></li></ol><p>Also, if you haven&#8217;t used Redis before, you can install the Docker image of Redis and experiment with Redis Stream commands. You can find the documentation here: <a href="https://redis.io/docs/latest/develop/data-types/streams/">Redis Streams doc</a>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/redis-streams-guide-real-time-data-processing?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/p/redis-streams-guide-real-time-data-processing?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p>Before you go:</p><ul><li><p>&#10084;&#65039; the story and follow the newsletter for more such articles</p></li><li><p>&#128276; Follow me: <a href="https://www.linkedin.com/in/animesh-gaitonde/">LinkedIn</a>, <a href="https://twitter.com/animesh3436">Twitter</a>, <a href="https://medium.com/@animeshgaitonde">Medium</a></p></li><li><p>Your support helps keep this newsletter free and fuels future content. Consider a small donation to show your appreciation here - <a href="https://www.paypal.com/ncp/payment/EUGP54EHQFDZC">Paypal Donate</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[Blue Screens to Blackouts: The Story Behind the CrowdStrike Outage]]></title><description><![CDATA[A Deep Dive into the Causes and Consequences of the CrowdStrike Incident]]></description><link>https://engineeringatscale.substack.com/p/blue-screens-to-blackouts-the-story</link><guid isPermaLink="false">https://engineeringatscale.substack.com/p/blue-screens-to-blackouts-the-story</guid><dc:creator><![CDATA[Animesh Gaitonde]]></dc:creator><pubDate>Sat, 20 Jul 2024 09:42:20 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!1Ln7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a641808-0bd0-435c-904c-eb22ff17ceea_1230x762.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Introduction</h2><p>On 19th July 2024, the world witnessed one of the biggest IT disruptions in recent years. Corporations worldwide reported outages and disruptions, with Windows computers displaying the dreaded Blue Screen of Death (BSOD) Error.</p><p>The outage impacted sectors such as airlines, banking, trading, media companies and many more. It was confirmed that there was no security incident or cyberattack resulting in this disruption.</p><p>The outage was due to a software update of Falcon, a tool built by the cybersecurity firm CrowdStrike. The latest update resulted in a crash of Windows operating system and resulted in worldwide outage.</p><p>In this article, we will dive deep and understand the issue. We will start by demystifying the Blue Screen of Death by revisiting the operating system fundamentals. Later, we will look at CrowdStrike&#8217;s architecture, the faulty release and the mitigation strategy. We will conclude by going over some key learnings from this incident.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/subscribe?"><span>Subscribe now</span></a></p><h2>Blue Screen of Death (Blue Screen of Death)</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1Ln7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a641808-0bd0-435c-904c-eb22ff17ceea_1230x762.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1Ln7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a641808-0bd0-435c-904c-eb22ff17ceea_1230x762.png 424w, https://substackcdn.com/image/fetch/$s_!1Ln7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a641808-0bd0-435c-904c-eb22ff17ceea_1230x762.png 848w, https://substackcdn.com/image/fetch/$s_!1Ln7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a641808-0bd0-435c-904c-eb22ff17ceea_1230x762.png 1272w, https://substackcdn.com/image/fetch/$s_!1Ln7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a641808-0bd0-435c-904c-eb22ff17ceea_1230x762.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1Ln7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a641808-0bd0-435c-904c-eb22ff17ceea_1230x762.png" width="1230" height="762" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1a641808-0bd0-435c-904c-eb22ff17ceea_1230x762.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:762,&quot;width&quot;:1230,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:580641,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!1Ln7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a641808-0bd0-435c-904c-eb22ff17ceea_1230x762.png 424w, https://substackcdn.com/image/fetch/$s_!1Ln7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a641808-0bd0-435c-904c-eb22ff17ceea_1230x762.png 848w, https://substackcdn.com/image/fetch/$s_!1Ln7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a641808-0bd0-435c-904c-eb22ff17ceea_1230x762.png 1272w, https://substackcdn.com/image/fetch/$s_!1Ln7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a641808-0bd0-435c-904c-eb22ff17ceea_1230x762.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Blue Screen of Death (BSOD)</strong></figcaption></figure></div><p>If you use Windows, you've likely encountered the <strong>Blue Screen of Death</strong> (<strong>BSOD</strong>). This error screen indicates that the system has malfunctioned, usually due to hardware or software issues.</p><p>After the reboot, everything works seamlessly. But, do you know why the BSOD appears ? And why does it appear only on Windows machine and not on Linux/Mac ? Let&#8217;s understand this in detail.</p><h3>Operating System</h3><p>Before going into the details, we will revisit some <strong>operating system</strong> concepts. This would help us grasp complex details in an easy manner.</p><p>The operating system manages hardware components like memory, CPU, and I/O devices, with the <strong>Kernel</strong> at its core.</p><p>The Kernel is responsible for primary functionalities such as :-</p><ol><li><p><strong>Memory management</strong> - Allocating/Deallocating memory for the running processes. Tracking the memory used by the processes.</p></li><li><p><strong>Process management</strong> - Managing the process lifecycle and ensuring two or more processes run in the memory without any issue.</p></li><li><p><strong>Device management</strong> - Communication with devices like monitor, mouse, keyboard, printers, etc.</p></li><li><p><strong>File System management</strong> - Organizing the files on the hard drive or any external storage.</p></li></ol><p>The processes running on any computer/machine run in two modes - a) <strong>Kernel Mode</strong> b) <strong>User Mode</strong>. </p><h4>Kernel Mode</h4><p>This mode has highest privilege and can directly interact with all the hardware. Operating system processes run in this mode.</p><p>It&#8217;s a critical mode and any errors in the code can result in system instability and eventual crash. Hence, code has to be written meticulously and should be error-free.</p><p>As users, we don&#8217;t directly deal with processes that run in the kernel mode. However, you can view them in the Windows Task Manager. The following snippet shows processes such as <strong>Host processes</strong> and <strong>NT Kernel &amp; System</strong> running in kernel mode.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eLsC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfb2bcb8-a5b6-43b2-82a4-826eccf92f44_1372x958.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eLsC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfb2bcb8-a5b6-43b2-82a4-826eccf92f44_1372x958.png 424w, https://substackcdn.com/image/fetch/$s_!eLsC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfb2bcb8-a5b6-43b2-82a4-826eccf92f44_1372x958.png 848w, https://substackcdn.com/image/fetch/$s_!eLsC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfb2bcb8-a5b6-43b2-82a4-826eccf92f44_1372x958.png 1272w, https://substackcdn.com/image/fetch/$s_!eLsC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfb2bcb8-a5b6-43b2-82a4-826eccf92f44_1372x958.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eLsC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfb2bcb8-a5b6-43b2-82a4-826eccf92f44_1372x958.png" width="1372" height="958" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cfb2bcb8-a5b6-43b2-82a4-826eccf92f44_1372x958.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:958,&quot;width&quot;:1372,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1237297,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!eLsC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfb2bcb8-a5b6-43b2-82a4-826eccf92f44_1372x958.png 424w, https://substackcdn.com/image/fetch/$s_!eLsC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfb2bcb8-a5b6-43b2-82a4-826eccf92f44_1372x958.png 848w, https://substackcdn.com/image/fetch/$s_!eLsC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfb2bcb8-a5b6-43b2-82a4-826eccf92f44_1372x958.png 1272w, https://substackcdn.com/image/fetch/$s_!eLsC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfb2bcb8-a5b6-43b2-82a4-826eccf92f44_1372x958.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Windows Task Manager listing running processes</strong></figcaption></figure></div><h4><strong>User Mode</strong></h4><p>The user mode has least privilege and it can&#8217;t directly interact with the hardware. It uses the operating system to get the data from any hardware device.</p><p>The user mode processes call system calls for sending/receiving data to/from the hardware. For example: User programs call <code>fopen </code>system call to open a file on the hard disk.</p><p>The operating system ensures that the user process doesn&#8217;t access any memory that&#8217;s not assigned to it. In case a user process accesses memory belonging to a different process or a kernel process, the operating system sends a <strong>SIGSEV</strong> to the process. And the process finally terminates and the user sees a <strong>SEGFAULT</strong> (<strong>Segmentation Fault</strong>).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tPF4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9679857b-5443-42a0-b666-00522ddd0e46_1008x908.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tPF4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9679857b-5443-42a0-b666-00522ddd0e46_1008x908.png 424w, https://substackcdn.com/image/fetch/$s_!tPF4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9679857b-5443-42a0-b666-00522ddd0e46_1008x908.png 848w, https://substackcdn.com/image/fetch/$s_!tPF4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9679857b-5443-42a0-b666-00522ddd0e46_1008x908.png 1272w, https://substackcdn.com/image/fetch/$s_!tPF4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9679857b-5443-42a0-b666-00522ddd0e46_1008x908.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tPF4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9679857b-5443-42a0-b666-00522ddd0e46_1008x908.png" width="1008" height="908" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9679857b-5443-42a0-b666-00522ddd0e46_1008x908.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:908,&quot;width&quot;:1008,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:75258,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tPF4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9679857b-5443-42a0-b666-00522ddd0e46_1008x908.png 424w, https://substackcdn.com/image/fetch/$s_!tPF4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9679857b-5443-42a0-b666-00522ddd0e46_1008x908.png 848w, https://substackcdn.com/image/fetch/$s_!tPF4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9679857b-5443-42a0-b666-00522ddd0e46_1008x908.png 1272w, https://substackcdn.com/image/fetch/$s_!tPF4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9679857b-5443-42a0-b666-00522ddd0e46_1008x908.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>User process accessing Kernel&#8217;s memory</strong></figcaption></figure></div><p>Applications that you use daily such as web browsers, MS Excel, MS Word, games, media players like VLC, etc run in user mode.</p><h3>What causes BSOD ?</h3><p>BSOD is only shown for Windows devices. It indicates that the system has malfunctioned. It could be either due to a hardware or software issue.</p><p>The following are few reasons for BSOD :- </p><ol><li><p><strong>File system corruption</strong> - In case the files required by the Kernel are corrupted, the system can crash.</p></li><li><p><strong>Device driver issues</strong> - Incompatible or corrupted device drivers can lead to communication errors. And eventually cause BSOD.</p></li><li><p><strong>Software bugs</strong> - Bugs which modify critical Kernel data structures, and access forbidden memory locations can bring the system to a halt.</p></li><li><p><strong>Malware</strong> - Malware can interfere with the system processes leading to a BSOD.</p></li></ol><p>In most of the cases, we restart the system and as expected it starts functioning. We can often troubleshoot the issue by looking at the system logs.</p><p>To ensure smooth functioning of operating system, it is essential to prevent scenarios such as kernel&#8217;s data corruption, accidental modification of kernel&#8217;s memory, etc.</p><p>Mac/Linux use different Kernel, data structures and error handling mechanisms. In case of an OS crash, both OSs use Kernel panic. Unlike Windows&#8217;s BSOD, Mac/Linux show a screen with error messages.</p><p>Now, that you understand BSOD, let&#8217;s understand the reason for 19th July&#8217;s worldwide BSOD.</p><h2>19th July&#8217;s BSOD</h2><p><strong>72%</strong> of the users in the world are windows users. Windows devices use tools developed by CrowdStrike(<strong>CRWD</strong>) for cybersecurity.</p><p>CrowdStrike has developed a suite of cloud-native tools. One such product in their suite is known as <strong>CrowdStrike Falcon</strong>.</p><p>CrowdStrike Falcon offers the following features :- </p><ol><li><p><strong>Endpoint security</strong> - It detects and prevents malware, ransomware and other threats.</p></li><li><p><strong>Extended detection and response (XDR)</strong> - Helps in investigating security incidents, identifying root causes, and taking the right steps.</p></li><li><p><strong>Cloud workload protection</strong> - It monitors any malicious activity in cloud environments for Azure, AWS , and Google Cloud Platform (GCP).</p></li></ol><h3><strong>CrowdStrike Falcon architecture</strong></h3><p>Falcon is installed on all the devices and runs as an agent (sensor). It continuously monitors the device activity.</p><p>CrowdStrike runs a cloud platform that collects data from all the Falcon agents. This platform also serves as a control plane for CrowdStrike to view the threats and security incidents.</p><p>Falcon agents run as background processes. They collect the security data from the device and send it to the CrowdStrike platform.</p><p>The following image shows the architecture (for representation only) of Falcon :- </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DOPU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10e5d8b-0bc5-45bc-a745-bae053da5a2f_2520x1444.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DOPU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10e5d8b-0bc5-45bc-a745-bae053da5a2f_2520x1444.png 424w, https://substackcdn.com/image/fetch/$s_!DOPU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10e5d8b-0bc5-45bc-a745-bae053da5a2f_2520x1444.png 848w, https://substackcdn.com/image/fetch/$s_!DOPU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10e5d8b-0bc5-45bc-a745-bae053da5a2f_2520x1444.png 1272w, https://substackcdn.com/image/fetch/$s_!DOPU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10e5d8b-0bc5-45bc-a745-bae053da5a2f_2520x1444.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DOPU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10e5d8b-0bc5-45bc-a745-bae053da5a2f_2520x1444.png" width="1456" height="834" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b10e5d8b-0bc5-45bc-a745-bae053da5a2f_2520x1444.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:834,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:245429,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!DOPU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10e5d8b-0bc5-45bc-a745-bae053da5a2f_2520x1444.png 424w, https://substackcdn.com/image/fetch/$s_!DOPU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10e5d8b-0bc5-45bc-a745-bae053da5a2f_2520x1444.png 848w, https://substackcdn.com/image/fetch/$s_!DOPU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10e5d8b-0bc5-45bc-a745-bae053da5a2f_2520x1444.png 1272w, https://substackcdn.com/image/fetch/$s_!DOPU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10e5d8b-0bc5-45bc-a745-bae053da5a2f_2520x1444.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Falcon&#8217;s architecture (for representation only)</strong></figcaption></figure></div><p>Falcon Agent runs as a kernel process since it has to monitor activities such as - </p><ul><li><p>Device driver activity</p></li><li><p>Network traffic</p></li><li><p>Restricted file accesses</p></li></ul><p>The above activities require highest privileges and as a result, the Falcon Agent runs in a <strong>kernel mode</strong>. </p><p>Unlike windows updates, Falcon Agent updates itself silently in the background. It gets the latest update from the cloud platform.</p><p>As seen from the above architecture, the Falcon Agent gets the latest update, restarts and runs the latest version.</p><h3>Faulty deployment</h3><p>Recently, CrowdStrike deployed latest version of Falcon Agent. The file <strong>C-00000291*.sys </strong>was updated and the running agents downloaded the file.</p><p>After consuming the update, windows machines started crashing. The issue wasn&#8217;t observed on the machines where the agent wasn&#8217;t updated.</p><p>This was observed worldwide and brought most of the economic activities such as Air travel, Hospitals, Stock trading, etc to a standstill. </p><p>CrowdStrike discovered that the issue was due to faulty update in the <strong>C-00000291*.sys</strong> file. A fix was deployed and the file <strong>C-00000291*.sys </strong>with timestamp of 0527 UTC had the fix. While the one with 0409 UTC was the problematic one. Reference - <a href="https://www.crowdstrike.com/blog/statement-on-falcon-content-update-for-windows-hosts/">Falcon update for Windows host</a>.</p><p>CrowdStrike hasn&#8217;t published the exact technical details. However, I suspect it could be due to incompatibility between the latest agent update and it&#8217;s interaction with the Kernel.</p><p>The latest Agent might have a bug that might have written to Kernel&#8217;s memory causing corruption. This might have resulted in the crash. And since this was repetitive, the fault might have been in Falcon Agent&#8217;s initialization.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!91FV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf14af9b-0411-4c91-9e72-8ab1b6c1d410_1470x1192.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!91FV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf14af9b-0411-4c91-9e72-8ab1b6c1d410_1470x1192.png 424w, https://substackcdn.com/image/fetch/$s_!91FV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf14af9b-0411-4c91-9e72-8ab1b6c1d410_1470x1192.png 848w, https://substackcdn.com/image/fetch/$s_!91FV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf14af9b-0411-4c91-9e72-8ab1b6c1d410_1470x1192.png 1272w, https://substackcdn.com/image/fetch/$s_!91FV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf14af9b-0411-4c91-9e72-8ab1b6c1d410_1470x1192.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!91FV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf14af9b-0411-4c91-9e72-8ab1b6c1d410_1470x1192.png" width="1456" height="1181" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bf14af9b-0411-4c91-9e72-8ab1b6c1d410_1470x1192.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1181,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:164307,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!91FV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf14af9b-0411-4c91-9e72-8ab1b6c1d410_1470x1192.png 424w, https://substackcdn.com/image/fetch/$s_!91FV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf14af9b-0411-4c91-9e72-8ab1b6c1d410_1470x1192.png 848w, https://substackcdn.com/image/fetch/$s_!91FV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf14af9b-0411-4c91-9e72-8ab1b6c1d410_1470x1192.png 1272w, https://substackcdn.com/image/fetch/$s_!91FV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf14af9b-0411-4c91-9e72-8ab1b6c1d410_1470x1192.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Process illustrating BSOD after Falcon Agent update (for representation only)</strong></figcaption></figure></div><h3>Immediate Fix</h3><p>CrowdStrike mentioned the steps to mitigate the issue immediately. They deployed a fix and machines using the latest Agent wouldn&#8217;t face the same issue.</p><p>They also stated that users should manually delete the faulty <strong>C-00000291*.sys</strong> file from the machines and reboot them. Similar workarounds are suggested for workloads running on cloud.</p><p>According to me, it would take a couple of days for the fix to reach all the machines worldwide. Also, since it requires manual intervention, non-technical users would face a challenge. But, hopefully, it will get resolved soon.</p><h2>Long-term mitigation</h2><p>On 19th July, we witnessed how a simple software update can disrupt our daily life. In the future, such issues must be avoided at all costs.</p><p>In my opinion, there are two angles to the 19th July&#8217;s BSOD issue :- </p><ol><li><p><strong>Agent updates</strong> - The issue could have been prevented if the update wasn&#8217;t rolled out to all the users.</p></li><li><p><strong>OS design</strong> - Linux/Mac didn&#8217;t face the same issue. However, it impacted most of the Windows devices. A better design of OS and its kernel modules would have prevented this havoc.</p></li></ol><h3>Agent updates</h3><p>Since the agents are installed on the end-user devices, it makes the deployment more challenging. Unlike cloud-services, these changes can&#8217;t be rolled-back automatically. And also the blast radius is huge as it encompasses all devices in the world.</p><p>However, in the future, CrowdStrike can follow a strategy similar to blue-green deployment. Instead of all the agents receiving the update, a set of computers (<strong>green environment</strong>) would receive the update. It would bake for few days in the green environment and then the change would roll-out to the <strong>blue environment</strong> (end-user devices).</p><p>Similarly, since the Agent runs in the kernel mode, the <strong>testing</strong> must be rigorous. Also, the <strong>code reviews</strong> must be done <strong>thoroughly</strong> and <strong>critically</strong>. There should be enough guardrails to prevent any accidental updates to the source operating system.</p><h3>OS <strong>design</strong></h3><p>Windows users have a history of dealing with BSOD. Over the years, Windows has become stable and users are seeing BSOD less frequently.</p><p>One of the primary reasons for BSOD can be attributed to the design of Windows OS. While kernel extensions provide low-level access, hardware interaction and customization, the downside is instability.</p><p>Mac followed a similar approach until macOS 10.15 (Catalina). Since then, Mac introduced system sxtensions. System extensions run as User processes and have limited access to the core kernel. This prevents unexpected crashes, and reduces security vulnerabilities.</p><p>Windows can benefit from following Mac&#8217;s footsteps in the future. It would improve overall security and stability.</p><p>Additionally, the Windows kernel is implemented in <strong>C/C++</strong>. These languages are prone to errors such as <strong>buffer overflows</strong>, <strong>dangling pointers</strong>, &amp; <strong>Null pointer references</strong>. The errors lead to process crashes.</p><p>Microsoft has started rewriting its kernel in <strong>Rust</strong>. Rust&#8217;s strong typing and ownership system make it memory safe. In the future, 19th July-like BSOD issues can be prevented with the Windows version written in Rust. </p><h2>Conclusion</h2><p>On 19th July, the majority of systems running Windows faced BSOD. Moreover, cloud services running on Windows servers were impacted, disrupting many clients relying on these services.</p><p>The root cause of the issue was a faulty update of CrowdStrike&#8217;s Falcon Agent (sensor). The latest update caused an OS crash, and users started seeing BSOD.</p><p>CrowdStrike identified the issue and rolled out a fix. They also suggested ways to mitigate the issues on their website. Some users had to manually reboot their machines and delete the problematic file from the update as an immediate fix. In a couple of days, all systems are expected to function normally.</p><p>As a software developer, key takeaways from this incident include :- </p><ol><li><p>Before deployment, assess the impact of the change and the blast radius.</p></li><li><p>Adopt blue-green deployments to minimize the disruption to end-users.</p></li><li><p>Minimize the manual steps for users in case of software roll-backs. Roll-backs must be seamless, and user functionality shouldn&#8217;t get impacted.</p></li><li><p>When dealing with the OS kernel, follow best practices for testing and code reviews.</p></li><li><p>If developing an OS, use memory-safe languages like Rust over C/C++, and use concepts such as system extensions that limit a process&#8217;s access to the OS Kernel.</p></li></ol><p>Let me know in the comments below what your views are and how CrowdStrike or any other company could prevent such issues in the future. Also, restack and share the post if you liked it. </p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/blue-screens-to-blackouts-the-story?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/p/blue-screens-to-blackouts-the-story?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p>Before you go:</p><ul><li><p>&#10084;&#65039; the story and follow the newsletter for more such articles</p></li><li><p>&#128276; Follow me: <a href="https://www.linkedin.com/in/animesh-gaitonde/">LinkedIn</a>, <a href="https://twitter.com/animesh3436">Twitter</a>, <a href="https://medium.com/@animeshgaitonde">Medium</a></p></li><li><p>Your support helps keep this newsletter free and fuels future content. Consider a small donation to show your appreciation here - <a href="https://www.paypal.com/ncp/payment/EUGP54EHQFDZC">Paypal Donate</a></p></li></ul><h2>Reference</h2><ol><li><p><a href="https://www.crowdstrike.com/blog/statement-on-falcon-content-update-for-windows-hosts/">CrowdStrike Statement on Falcon Content Update for Windows Hosts</a></p></li><li><p><a href="https://techcrunch.com/2024/07/19/faulty-crowdstrike-update-causes-major-global-it-outage-taking-out-banks-airlines-and-businesses-globally/">CrowdStrike update causes major global IT outage</a></p></li></ol><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Redis - The Swiss Army Knife of Datastores]]></title><description><![CDATA[Redis, basic & advanced data structures, real-world applications]]></description><link>https://engineeringatscale.substack.com/p/redis-the-swiss-army-knife-of-datastores</link><guid isPermaLink="false">https://engineeringatscale.substack.com/p/redis-the-swiss-army-knife-of-datastores</guid><dc:creator><![CDATA[Animesh Gaitonde]]></dc:creator><pubDate>Sat, 13 Jul 2024 09:13:55 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!PL51!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36b8cca6-3665-4f98-8c40-ad36100de606_1200x1200.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote><p>Hello Readers, </p><p><strong>Do you struggle to understand the intricacies of distributed systems, databases, and programming languages?</strong> <strong>Are you curious to learn how companies design and build software at scale ?.</strong></p><p>My free newsletter breaks down complex tech concepts, architectural trade-offs, and design decisions into clear, actionable steps. Get weekly articles to level up your tech skills and become a better developer.</p><p>If you haven&#8217;t subscribed to my newsletter yet, do subscribe -  </p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/subscribe?"><span>Subscribe now</span></a></p></blockquote><p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PL51!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36b8cca6-3665-4f98-8c40-ad36100de606_1200x1200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PL51!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36b8cca6-3665-4f98-8c40-ad36100de606_1200x1200.png 424w, https://substackcdn.com/image/fetch/$s_!PL51!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36b8cca6-3665-4f98-8c40-ad36100de606_1200x1200.png 848w, https://substackcdn.com/image/fetch/$s_!PL51!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36b8cca6-3665-4f98-8c40-ad36100de606_1200x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!PL51!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36b8cca6-3665-4f98-8c40-ad36100de606_1200x1200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PL51!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36b8cca6-3665-4f98-8c40-ad36100de606_1200x1200.png" width="1200" height="1200" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/36b8cca6-3665-4f98-8c40-ad36100de606_1200x1200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1200,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:187373,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!PL51!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36b8cca6-3665-4f98-8c40-ad36100de606_1200x1200.png 424w, https://substackcdn.com/image/fetch/$s_!PL51!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36b8cca6-3665-4f98-8c40-ad36100de606_1200x1200.png 848w, https://substackcdn.com/image/fetch/$s_!PL51!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36b8cca6-3665-4f98-8c40-ad36100de606_1200x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!PL51!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36b8cca6-3665-4f98-8c40-ad36100de606_1200x1200.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Redis - Swiss Army Knife of datastores</strong></figcaption></figure></div><h2>Redis</h2><p>In 2009, an Italian software developer named Salvatore Sanfilippo was working on building a real-time web log analyzer. His application couldn&#8217;t scale as database was the primary bottleneck.</p><p>Hence, he decided to develop a solution that could serve the data from memory. He implemented the Proof of Concept in TCL and later ported it to C. This was the first version of Redis (<strong>RE</strong>mote <strong>D</strong>ictionary <strong>S</strong>erver).</p><p>Later, Salvatore open-sourced the project and posted it on Hacker News. The project received a lot of traction &amp; enterprises such as Github &amp; Instagram adopted it. Today, big tech companies such as Amazon, Microsoft, Google, Meta, etc use Redis in production.</p><p>What started as an in-memory cache, is now used in a wide array of industries such as gaming, finance, e-commerce, social media, advertisements, etc. </p><p>Redis is now more than an in-memory cache. It has support for message queues, probabilistic data structures, Geospatial indexes, vector-search capabilities and much more.</p><h2>Key Features of Redis</h2><h3><strong>Latency</strong></h3><p>While traditional databases store the data on the disk, Redis stores the data in-memory. Accessing the in-memory data is 10-100x faster than disk access.</p><p>The below image illustrates and compares Database lookup vs a Redis lookup.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8fL8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcdd6e7f-0be0-44c0-b53b-d06f9c938aef_1336x902.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8fL8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcdd6e7f-0be0-44c0-b53b-d06f9c938aef_1336x902.png 424w, https://substackcdn.com/image/fetch/$s_!8fL8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcdd6e7f-0be0-44c0-b53b-d06f9c938aef_1336x902.png 848w, https://substackcdn.com/image/fetch/$s_!8fL8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcdd6e7f-0be0-44c0-b53b-d06f9c938aef_1336x902.png 1272w, https://substackcdn.com/image/fetch/$s_!8fL8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcdd6e7f-0be0-44c0-b53b-d06f9c938aef_1336x902.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8fL8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcdd6e7f-0be0-44c0-b53b-d06f9c938aef_1336x902.png" width="1336" height="902" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dcdd6e7f-0be0-44c0-b53b-d06f9c938aef_1336x902.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:902,&quot;width&quot;:1336,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:281690,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8fL8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcdd6e7f-0be0-44c0-b53b-d06f9c938aef_1336x902.png 424w, https://substackcdn.com/image/fetch/$s_!8fL8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcdd6e7f-0be0-44c0-b53b-d06f9c938aef_1336x902.png 848w, https://substackcdn.com/image/fetch/$s_!8fL8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcdd6e7f-0be0-44c0-b53b-d06f9c938aef_1336x902.png 1272w, https://substackcdn.com/image/fetch/$s_!8fL8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcdd6e7f-0be0-44c0-b53b-d06f9c938aef_1336x902.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>As a result, Redis improves the system&#8217;s performance by reducing the latency of every data access. This makes Redis the right candidate for caching.</p><h3><strong>Availability</strong></h3><p>Redis supports data replication through leader-follower architecture. Clients write the data to the leader which replicates them to the followers.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!N8De!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe0cec42-1da4-48a3-8fc1-21c39a037bef_1556x1264.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!N8De!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe0cec42-1da4-48a3-8fc1-21c39a037bef_1556x1264.png 424w, https://substackcdn.com/image/fetch/$s_!N8De!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe0cec42-1da4-48a3-8fc1-21c39a037bef_1556x1264.png 848w, https://substackcdn.com/image/fetch/$s_!N8De!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe0cec42-1da4-48a3-8fc1-21c39a037bef_1556x1264.png 1272w, https://substackcdn.com/image/fetch/$s_!N8De!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe0cec42-1da4-48a3-8fc1-21c39a037bef_1556x1264.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!N8De!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe0cec42-1da4-48a3-8fc1-21c39a037bef_1556x1264.png" width="1456" height="1183" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fe0cec42-1da4-48a3-8fc1-21c39a037bef_1556x1264.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1183,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:109095,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!N8De!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe0cec42-1da4-48a3-8fc1-21c39a037bef_1556x1264.png 424w, https://substackcdn.com/image/fetch/$s_!N8De!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe0cec42-1da4-48a3-8fc1-21c39a037bef_1556x1264.png 848w, https://substackcdn.com/image/fetch/$s_!N8De!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe0cec42-1da4-48a3-8fc1-21c39a037bef_1556x1264.png 1272w, https://substackcdn.com/image/fetch/$s_!N8De!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe0cec42-1da4-48a3-8fc1-21c39a037bef_1556x1264.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Redis Replication for High Availability</strong></figcaption></figure></div><p>In case a leader goes down, one of the follower becomes the new leader and starts serving writes. This ensures high data availability and avoids system downtimes.</p><h3><strong>Fault-tolerance</strong></h3><p>Since the data stored in the memory is transient, Redis minimizes the data loss by adopting the following techniques :-</p><ol><li><p><strong>Append-Only Files (AOF)</strong> - It persists all the received commands in a file. In case the server restarts, the latest state is constructed by running all the saved commands.</p></li><li><p><strong>Snapshots</strong> - Redis takes periodic snapshots of its state. The snapshot is persisted in a binary file. On server restarts, the state is restored by parsing the binary file.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iW9c!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd17dbed0-93f7-47de-b8ed-b3fb450f97c4_1284x648.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iW9c!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd17dbed0-93f7-47de-b8ed-b3fb450f97c4_1284x648.png 424w, https://substackcdn.com/image/fetch/$s_!iW9c!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd17dbed0-93f7-47de-b8ed-b3fb450f97c4_1284x648.png 848w, https://substackcdn.com/image/fetch/$s_!iW9c!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd17dbed0-93f7-47de-b8ed-b3fb450f97c4_1284x648.png 1272w, https://substackcdn.com/image/fetch/$s_!iW9c!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd17dbed0-93f7-47de-b8ed-b3fb450f97c4_1284x648.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iW9c!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd17dbed0-93f7-47de-b8ed-b3fb450f97c4_1284x648.png" width="1284" height="648" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d17dbed0-93f7-47de-b8ed-b3fb450f97c4_1284x648.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:648,&quot;width&quot;:1284,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:56698,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!iW9c!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd17dbed0-93f7-47de-b8ed-b3fb450f97c4_1284x648.png 424w, https://substackcdn.com/image/fetch/$s_!iW9c!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd17dbed0-93f7-47de-b8ed-b3fb450f97c4_1284x648.png 848w, https://substackcdn.com/image/fetch/$s_!iW9c!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd17dbed0-93f7-47de-b8ed-b3fb450f97c4_1284x648.png 1272w, https://substackcdn.com/image/fetch/$s_!iW9c!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd17dbed0-93f7-47de-b8ed-b3fb450f97c4_1284x648.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Redis snapshot and Append-Only File (AOF) for data persistence</strong></figcaption></figure></div><p>These features safeguard Redis from unexpected crashes, deployments, restarts, and version upgrades.</p><h3><strong>Scalability</strong></h3><p>Redis Cluster consists of a set of servers which store the data. It uses sharding (consistent hashing) to efficiently distribute the data among different servers.</p><p>As a result, the data size is not limited by the memory size of a single server. The Redis Cluster can scale &amp; support additional data by adding more servers.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WCNd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55a5221f-af8e-4bb7-abdb-1570e64bf974_900x864.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WCNd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55a5221f-af8e-4bb7-abdb-1570e64bf974_900x864.png 424w, https://substackcdn.com/image/fetch/$s_!WCNd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55a5221f-af8e-4bb7-abdb-1570e64bf974_900x864.png 848w, https://substackcdn.com/image/fetch/$s_!WCNd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55a5221f-af8e-4bb7-abdb-1570e64bf974_900x864.png 1272w, https://substackcdn.com/image/fetch/$s_!WCNd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55a5221f-af8e-4bb7-abdb-1570e64bf974_900x864.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WCNd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55a5221f-af8e-4bb7-abdb-1570e64bf974_900x864.png" width="712" height="683.52" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/55a5221f-af8e-4bb7-abdb-1570e64bf974_900x864.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:864,&quot;width&quot;:900,&quot;resizeWidth&quot;:712,&quot;bytes&quot;:62366,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!WCNd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55a5221f-af8e-4bb7-abdb-1570e64bf974_900x864.png 424w, https://substackcdn.com/image/fetch/$s_!WCNd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55a5221f-af8e-4bb7-abdb-1570e64bf974_900x864.png 848w, https://substackcdn.com/image/fetch/$s_!WCNd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55a5221f-af8e-4bb7-abdb-1570e64bf974_900x864.png 1272w, https://substackcdn.com/image/fetch/$s_!WCNd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55a5221f-af8e-4bb7-abdb-1570e64bf974_900x864.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Redis cluster supports data sharding</strong></figcaption></figure></div><p>Similarly, it can handle spike in the traffic by evenly distributing the traffic across the shards and replicas.</p><h2>Basic data structures</h2><p>Following are the basic data structures supported by Redis :- </p><ol><li><p><strong>Strings</strong> - Can store upto 512MB data. It can store JSON, XML, and raw strings.</p></li><li><p><strong>Lists</strong> - To store collection of objects. Exposes APIs to push/pop objects.</p></li><li><p><strong>Sets</strong> - To store unique string and perform O(1) lookup on strings.</p></li><li><p><strong>Hashes</strong> - Similar to Hash maps and can store key-value pairs.</p></li><li><p><strong>Sorted</strong> <strong>Sets</strong> - To store collection of objects in a sorted manner.</p></li></ol><p>Most of the relational and non-relational databases don&#8217;t support a wide variety of data structures. Hence, applications have to do an additional data model conversion while storing the data in databases such as PostgreSQL, MySQL, Cassandra, etc.</p><p>If your application uses Redis, it can directly use Redis&#8217;s APIs and pass data stored in complex data structures such as Sorted Sets, Sets, Lists, etc.</p><h2>Advanced data structures</h2><p>In addition to basic data structures, it has support for the following complex data structures :-</p><ul><li><p><strong>HyperLogLog</strong> - It is probabilistic data structure to estimate count of objects in a set.</p></li><li><p><strong>Bitmaps</strong> - It is used for storing &amp; manipulating individual bits.</p></li><li><p><strong>Geospatial Indexes</strong> - It stores geo-location and APIs to lookup using location &amp; distance.</p></li><li><p><strong>Streams</strong> - It is log-based data structure for append-only log data.</p></li><li><p><strong>Vectors</strong> - Vector data structure is a mathematical representation of data as a list of numbers. It allows AI algorithms to perform calculations and make efficient decisions.</p></li></ul><p>For more details, you can go through the official <a href="https://redis.io/redis-enterprise/data-structures/">Redis documentation</a> and play around with the different data structures.</p><p>These features enhance the versatility of Redis for several real-world applications. Now, let's explore some real-world applications of Redis.</p><h2>Real-world applications</h2><p>Each of the Redis data structure can be used to solve a unique distributed systems problem. Here are some data structures with their real-world application :-</p><ol><li><p><strong>HyperLogLog</strong> - It is used for estimating the unique visitors or concurrent users on a website.</p></li><li><p><strong>Bitmaps</strong> - They are used for tracking the online/offline status of a large user base.</p></li><li><p><strong>Geospatial Indexes</strong> -Finding near-by restaurants, users, or stores. Additionally, useful for real-time tracking and spatial analysis.</p></li><li><p><strong>Streams</strong> - Used for Log aggregation, and real-time feeds for social media sites.</p></li><li><p><strong>Strings</strong> - For caching the data and improving the read/write performance of database queries.</p></li><li><p><strong>Vectors</strong> - AI/ML applications such as Recommendation systems, Anomaly Detection, Search &amp; Discovery, etc store data in form of vectors.</p></li></ol><h2>Conclusion</h2><p>Redis started as a simple key-value data store in <strong>2009</strong> and has evolved into a versatile tool capable of functioning as a database, message queue, cache, and much more. Its rich support for various data structures&#8212;such as <strong>Lists</strong>, <strong>Sets</strong>, <strong>HyperLogLog</strong>, and <strong>Geospatial</strong> <strong>indexes</strong>&#8212;sets it apart from other data stores.</p><p>This versatility makes Redis an essential component in many distributed systems, solving problems like distributed locking, rate limiting, and finding nearby users. With the rise of AI, Redis has also adapted to serve as a vector database.</p><p>One standout feature of Redis is its in-memory data storage, making it ideal for performance-critical real-time systems. However, in 2024, Redis switched to a <strong>proprietary software license</strong>.</p><p>How do you think this shift will impact Redis and its adoption in the tech community? Will it continue to thrive, or will alternatives rise to take its place? Share your thoughts in the comments below.</p><p>Before you go:</p><ul><li><p>&#10084;&#65039; the story and follow the newsletter for more such articles</p></li><li><p>&#128276; Follow me: <a href="https://www.linkedin.com/in/animesh-gaitonde/">LinkedIn</a>, <a href="https://twitter.com/animesh3436">Twitter</a>, <a href="https://medium.com/@animeshgaitonde">Medium</a></p></li></ul><h2>References</h2><ol><li><p><a href="https://en.wikipedia.org/wiki/Redis">Redis wikipedia</a></p></li><li><p><a href="https://redis.io/">Redis data platform</a></p></li></ol><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[How Twitter processes 400 billion events daily ?]]></title><description><![CDATA[Twitter's event processing pipelines, old Lambda architecture & improvements through new Kappa architecture.]]></description><link>https://engineeringatscale.substack.com/p/twitter-event-processing-kappa-lambda</link><guid isPermaLink="false">https://engineeringatscale.substack.com/p/twitter-event-processing-kappa-lambda</guid><dc:creator><![CDATA[Animesh Gaitonde]]></dc:creator><pubDate>Mon, 17 Jun 2024 04:31:03 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!nWJK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd796d44a-9b37-4991-be5b-f9ec1e45fc7d_1422x656.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote><p>Hi Folks, </p><p><strong>Do you struggle to understand the intricacies of distributed systems, databases, and programming languages?</strong> <strong>Are you curious to learn how companies design and build software at scale ?</strong></p><p>My free newsletter breaks down complex tech concepts, architectural trade-offs, and design decisions into clear, actionable steps. Get weekly articles to level up your tech skills and become a better engineer.</p><p>If you haven&#8217;t subscribed to my newsletter yet, do subscribe :- </p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption"></p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div></blockquote><p>X.com (formerly Twitter) receives more than 400 billion events daily. The events include tweet views, likes, retweets, engagements, etc. The events are critical as they are used by Ad-serving systems &amp; determine the company&#8217;s revenue.</p><p>There are several components that work behind the scenes to process these events. The events are finally aggregated, and stored in a data store. And multiple downstream consumers rely on this data store. </p><p>Scale, performance and accuracy are three important pillars while building an event processing system. Twitter&#8217;s old Lambda architecture faced multiple challenges while handling the exponential growth in events. Hence, they adopted new Kappa architecture &amp; improved the accuracy, scalability and performance.</p><p>In this article, we will dive into Twitter&#8217;s architecture that processes 400 billion events daily. We will look at the old Lambda architecture,  why it couldn&#8217;t scale &amp; how the new architecture addressed the bottlenecks.</p><div><hr></div><p>This article uses this <a href="https://blog.x.com/engineering/en_us/topics/infrastructure/2021/processing-billions-of-events-in-real-time-at-twitter-">blog</a> from Twitter that was written in 2021. Twitter would have made multiple changes in the architecture since then. Hence, the article doesn&#8217;t talk about the latest state and it&#8217;s evolution over last 3 years.</p><div><hr></div><h2>Lambda architecture</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nWJK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd796d44a-9b37-4991-be5b-f9ec1e45fc7d_1422x656.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nWJK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd796d44a-9b37-4991-be5b-f9ec1e45fc7d_1422x656.png 424w, https://substackcdn.com/image/fetch/$s_!nWJK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd796d44a-9b37-4991-be5b-f9ec1e45fc7d_1422x656.png 848w, https://substackcdn.com/image/fetch/$s_!nWJK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd796d44a-9b37-4991-be5b-f9ec1e45fc7d_1422x656.png 1272w, https://substackcdn.com/image/fetch/$s_!nWJK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd796d44a-9b37-4991-be5b-f9ec1e45fc7d_1422x656.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nWJK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd796d44a-9b37-4991-be5b-f9ec1e45fc7d_1422x656.png" width="1422" height="656" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d796d44a-9b37-4991-be5b-f9ec1e45fc7d_1422x656.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:656,&quot;width&quot;:1422,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:210381,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!nWJK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd796d44a-9b37-4991-be5b-f9ec1e45fc7d_1422x656.png 424w, https://substackcdn.com/image/fetch/$s_!nWJK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd796d44a-9b37-4991-be5b-f9ec1e45fc7d_1422x656.png 848w, https://substackcdn.com/image/fetch/$s_!nWJK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd796d44a-9b37-4991-be5b-f9ec1e45fc7d_1422x656.png 1272w, https://substackcdn.com/image/fetch/$s_!nWJK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd796d44a-9b37-4991-be5b-f9ec1e45fc7d_1422x656.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong><a href="https://blog.x.com/engineering/en_us/topics/infrastructure/2021/processing-billions-of-events-in-real-time-at-twitter-">Lambda architecture</a></strong></figcaption></figure></div><p>The lambda architecture consisted of batch-processing and real-time pipelines. These two pipelines store the data in different data stores.</p><p>Different consumer services query the Query Service for fetching the aggregated data. The Query service aggregates the computed data from different sources and returns it to the consumer services.</p><p>We will go over the different components comprising the architecture :-</p><ol><li><p><strong>Batch processing</strong></p><ol><li><p><strong>Data sources</strong> - The raw data exists in the form of logs stored in HDFS. This contains event data for tweet views, clicks, timelines, etc.</p></li><li><p><strong>Scalding</strong> - Scalding platform enables developers to write data pipelines for batch processing. Scaling pipelines read the raw data and then perform different types of aggregations.</p></li></ol></li><li><p><strong>Stream processing</strong></p><ol><li><p><strong>Data sources</strong> - The streaming data is written to different Kafka topics.</p></li><li><p><strong>Heron </strong>- Heron reads &amp; processes the streaming data from the Kafka topics.</p></li></ol></li><li><p><strong>Data stores </strong></p><ol><li><p><strong>Manhattan </strong>- The computed batch data is stored in Manhattan, a distributed database.</p></li><li><p><strong>Nighthawk</strong> - It is Twitter&#8217;s distributed cache used for storing the processed streaming data.</p></li></ol></li></ol><h2>Challenges with Lambda architecture</h2><p>Although, the above architecture was able to support the scale but it ran into several limitations. Following were the challenges with the old architecture :-</p><ol><li><p><strong>Performance - </strong>The performance of the system was dependent on the throughput of Heron. Heron nodes used to get impacted due to high garbage collection costs. Slowness of Heron consumers increased the overall processing latency.</p></li><li><p><strong>Accuracy </strong>- The system didn&#8217;t guarantee data durability. And Heron node restarts would result in data loss. This would impact the data accuracy. Additionally, it didn&#8217;t process late or out-of-the order events. </p></li><li><p><strong>Complexity </strong>- Two separate pipelines added to the architectural complexity and increased maintenance costs.</p></li><li><p><strong>Operational overhead</strong> <strong>- </strong>Developers often had to intervene to restart Heron nodes to speed up real-time data processing.</p></li></ol><h2>Kappa architecture</h2><p>To address the challenges, Twitter decided to adopt the Kappa architecture. This architecture used stream processing pipelines only. Further, they leveraged multiple Google cloud services for data processing.</p><p>The architecture consists of two parts - </p><ol><li><p><strong>Twitter data center</strong> - It hosts components and services within Twitter.</p></li><li><p><strong>Google Cloud</strong> - It consists of all the Cloud services used for stream processing.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uH6E!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff47c29db-dade-4600-875c-5c3053cfa76d_1426x960.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uH6E!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff47c29db-dade-4600-875c-5c3053cfa76d_1426x960.png 424w, https://substackcdn.com/image/fetch/$s_!uH6E!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff47c29db-dade-4600-875c-5c3053cfa76d_1426x960.png 848w, https://substackcdn.com/image/fetch/$s_!uH6E!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff47c29db-dade-4600-875c-5c3053cfa76d_1426x960.png 1272w, https://substackcdn.com/image/fetch/$s_!uH6E!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff47c29db-dade-4600-875c-5c3053cfa76d_1426x960.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uH6E!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff47c29db-dade-4600-875c-5c3053cfa76d_1426x960.png" width="1426" height="960" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f47c29db-dade-4600-875c-5c3053cfa76d_1426x960.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:960,&quot;width&quot;:1426,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:232781,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uH6E!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff47c29db-dade-4600-875c-5c3053cfa76d_1426x960.png 424w, https://substackcdn.com/image/fetch/$s_!uH6E!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff47c29db-dade-4600-875c-5c3053cfa76d_1426x960.png 848w, https://substackcdn.com/image/fetch/$s_!uH6E!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff47c29db-dade-4600-875c-5c3053cfa76d_1426x960.png 1272w, https://substackcdn.com/image/fetch/$s_!uH6E!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff47c29db-dade-4600-875c-5c3053cfa76d_1426x960.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://blog.x.com/engineering/en_us/topics/infrastructure/2021/processing-billions-of-events-in-real-time-at-twitter-">Kappa architecture</a></figcaption></figure></div><h3>Twitter Data Center</h3><ol><li><p><strong>Event Mappers</strong> - These were part of preprocessing pipelines. They transformed, re-mapped the fields and sent it to Kafka topics.</p></li><li><p><strong>Event processors</strong> - They were responsible for data model conversion from internal representation to Google pub-sub format. They streamed events with at-least-once semantics.</p></li><li><p> <strong>Twitter LDC Query Service</strong> - This service served the queries from different consumers by fetching the data from different cloud data stores.</p></li></ol><h3>Google Cloud</h3><ol><li><p><strong>Cloud Pub/Sub </strong>- The pub/sub relays the data pushed by Twitter&#8217;s Event processors to Dataflow. It guarantees no data loss in the event processing journey.</p></li><li><p><strong>Dataflow </strong>- Dataflow workers dedup (remove the duplicates) and aggregate the data. </p></li><li><p><strong>Bigtable/BigQuery - </strong>The aggregated count for the query key is written to the BigQuery and BigTable.</p></li></ol><h2>Kappa&#8217;s performance</h2><p>The new architecture reduced the costs to build and maintain a separate batch processing pipeline. With no data loss guarantees, it ensured high accuracy.</p><p>Following were some key improvements observed in the Kappa architecture :-</p><ol><li><p><strong>Events processed</strong> - Handled more than 4 million/second</p></li><li><p><strong>Throughput</strong> - More than 1 GB/sec. It was 10x improvement over Lambda architecture.</p></li><li><p><strong>Latency</strong> - The approximate latency was 10 sec. This was significant improvement over Lambda&#8217;s latency of 10 sec-10 mins.</p></li></ol><p>Besides, Kappa added support for late event handling and guaranteed no data loss. This improved the overall accuracy of the system.</p><h2>Conclusion</h2><p>Twitter&#8217;s original event processing system was based on Lambda architecture that combined batch-processing and stream-processing system together. There were several limitations of the Lambda architecture such as performance, accuracy, complexity and operational overhead.</p><p>To overcome Lambda architecture&#8217;s limitations, Twitter decided to adopt the Kappa architecture. This architecture adopted real-time streaming of events. </p><p>The event pre-processing and transformation was done via services in Twitter&#8217;s data center. And they leveraged Google Cloud services for event aggregation and storage.</p><p>Here is how the Kappa architecture addressed Lambda architecture&#8217;s limitations :-</p><ol><li><p><strong>Performance</strong> - It reduced the overall latency to ~10 sec from ~10 sec-10 min.</p></li><li><p><strong>Accuracy</strong> - Safety against data loss, at-least-once delivery semantics, event deduplication &amp; processing of delayed events improved the accuracy.</p></li><li><p><strong>Complexity</strong> - In contrast to Lambda architecture, Kappa required only real-time processing pipeline. This resulted in architectural simplification.</p></li><li><p><strong>Operational overhead</strong> - It eliminated the need for developer intervention to restart components (Heron nodes) and fix issues. This improved the developer productivity.</p></li></ol><p>Before you go:</p><ul><li><p>&#10084;&#65039; the story and follow the newsletter for more such articles</p></li><li><p>&#128276; Follow me: <a href="https://www.linkedin.com/in/animesh-gaitonde/">LinkedIn</a>, <a href="https://twitter.com/animesh3436">Twitter</a>, <a href="https://medium.com/@animeshgaitonde">Medium</a></p></li></ul><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/twitter-event-processing-kappa-lambda?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thank you for reading Engineering At Scale. This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://engineeringatscale.substack.com/p/twitter-event-processing-kappa-lambda?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://engineeringatscale.substack.com/p/twitter-event-processing-kappa-lambda?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><h2>References</h2><ol><li><p><a href="https://blog.x.com/engineering/en_us/topics/infrastructure/2021/processing-billions-of-events-in-real-time-at-twitter-">Processing billions of events in real-time at Twitter</a></p></li></ol><p></p><p></p><p></p>]]></content:encoded></item></channel></rss>