<?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[HrithikChandok]]></title><description><![CDATA[Backend Developer ]]></description><link>https://hrithikchandok.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!HwKs!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7662c0b0-f1e9-400d-a1b5-85bb39764171_1280x1280.png</url><title>HrithikChandok</title><link>https://hrithikchandok.substack.com</link></image><generator>Substack</generator><lastBuildDate>Mon, 22 Jun 2026 04:20:41 GMT</lastBuildDate><atom:link href="https://hrithikchandok.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Chandok]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[hrithikchandok@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[hrithikchandok@substack.com]]></itunes:email><itunes:name><![CDATA[HrithikChandok]]></itunes:name></itunes:owner><itunes:author><![CDATA[HrithikChandok]]></itunes:author><googleplay:owner><![CDATA[hrithikchandok@substack.com]]></googleplay:owner><googleplay:email><![CDATA[hrithikchandok@substack.com]]></googleplay:email><googleplay:author><![CDATA[HrithikChandok]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Nike SDE2 Interview Experience: A Lesson in System Design]]></title><description><![CDATA[Breaking down my DSA mistakes, the System Design "culprit discussion," and my key takeaways.]]></description><link>https://hrithikchandok.substack.com/p/nike-sde2-interview-experience-a</link><guid isPermaLink="false">https://hrithikchandok.substack.com/p/nike-sde2-interview-experience-a</guid><dc:creator><![CDATA[HrithikChandok]]></dc:creator><pubDate>Sat, 20 Jun 2026 18:23:23 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!gEOc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c2b70fb-bca3-4366-8620-cbcfbce59a54_765x667.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I was really confident about this opportunity, but unfortunately, I ended up getting rejected. Here are the lessons I learned.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gEOc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c2b70fb-bca3-4366-8620-cbcfbce59a54_765x667.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gEOc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c2b70fb-bca3-4366-8620-cbcfbce59a54_765x667.webp 424w, https://substackcdn.com/image/fetch/$s_!gEOc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c2b70fb-bca3-4366-8620-cbcfbce59a54_765x667.webp 848w, https://substackcdn.com/image/fetch/$s_!gEOc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c2b70fb-bca3-4366-8620-cbcfbce59a54_765x667.webp 1272w, https://substackcdn.com/image/fetch/$s_!gEOc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c2b70fb-bca3-4366-8620-cbcfbce59a54_765x667.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gEOc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c2b70fb-bca3-4366-8620-cbcfbce59a54_765x667.webp" width="765" height="667" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0c2b70fb-bca3-4366-8620-cbcfbce59a54_765x667.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:667,&quot;width&quot;:765,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:40426,&quot;alt&quot;:&quot;Photo&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&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="Photo" title="Photo" srcset="https://substackcdn.com/image/fetch/$s_!gEOc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c2b70fb-bca3-4366-8620-cbcfbce59a54_765x667.webp 424w, https://substackcdn.com/image/fetch/$s_!gEOc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c2b70fb-bca3-4366-8620-cbcfbce59a54_765x667.webp 848w, https://substackcdn.com/image/fetch/$s_!gEOc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c2b70fb-bca3-4366-8620-cbcfbce59a54_765x667.webp 1272w, https://substackcdn.com/image/fetch/$s_!gEOc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c2b70fb-bca3-4366-8620-cbcfbce59a54_765x667.webp 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></figure></div><h4>DSA Questions</h4><p><strong>1. Removing Stars From a String</strong></p><ul><li><p><strong>Outcome:</strong> I was able to solve this optimally with a Time Complexity of O(n) and a Space Complexity of O(n).</p></li></ul><p><strong>2. Longest Palindromic Substring</strong></p><ul><li><p><strong>Approach:</strong> I provided a solution with a Time Complexity of O(n&#179;) and a Space Complexity of O(1), which was not optimized at all.</p></li><li><p><strong>Outcome:</strong> I wasn&#8217;t able to solve this one. I started with a completely wrong approach, and the interviewer&#8217;s hints unfortunately threw me even further off the mark.</p></li></ul><h4>System Design Round (The Culprit Discussion)</h4><p>This is where things got tough. Here is what we discussed:</p><ul><li><p>An introduction to my current project.</p></li><li><p>Which AWS services I have hands-on experience working with.</p></li><li><p>How deployment works in my current organization.</p></li><li><p>How I would improve a database containing 10 million records <strong>without</strong> making architecture-level changes.</p></li><li><p>Why I chose ECS for my current project instead of other available services.</p></li><li><p>How to scale the delivery of 500KB images for 40,000 users.</p></li><li><p>Identifying what components are likely to break when handling large-scale traffic in my project.</p></li><li><p>A discussion on PDF Puppeteer and why it failed.</p></li><li><p>An explanation of the SOLID principles.</p></li><li><p>The Singleton Design Pattern and its practical use cases.</p></li><li><p>How to design a website to handle read-heavy database operations.</p></li></ul><p>Since it was a Cloud Platform team, they were specifically looking for someone with strong Kubernetes and containerisation experience.</p><p>The biggest lesson I learned? Take System Design preparation very seriously.</p><p>Chalo bye. Aage dekhte hai! </p>]]></content:encoded></item><item><title><![CDATA[Trapping Rain Water]]></title><description><![CDATA[Input: height = [0,2,0,3,1,0,1,3,2,1] Output: 9 Recommended Time & Space Complexity You should aim for a solution as good or better than O(n) time and O(n) space, where n is the size of the input array.]]></description><link>https://hrithikchandok.substack.com/p/trapping-rain-water</link><guid isPermaLink="false">https://hrithikchandok.substack.com/p/trapping-rain-water</guid><dc:creator><![CDATA[HrithikChandok]]></dc:creator><pubDate>Mon, 01 Jun 2026 12:02:57 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!caM9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a2cd68-0045-4ad9-8b6d-09081d7974b2_1250x491.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_!caM9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a2cd68-0045-4ad9-8b6d-09081d7974b2_1250x491.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!caM9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a2cd68-0045-4ad9-8b6d-09081d7974b2_1250x491.png 424w, https://substackcdn.com/image/fetch/$s_!caM9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a2cd68-0045-4ad9-8b6d-09081d7974b2_1250x491.png 848w, https://substackcdn.com/image/fetch/$s_!caM9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a2cd68-0045-4ad9-8b6d-09081d7974b2_1250x491.png 1272w, https://substackcdn.com/image/fetch/$s_!caM9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a2cd68-0045-4ad9-8b6d-09081d7974b2_1250x491.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!caM9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a2cd68-0045-4ad9-8b6d-09081d7974b2_1250x491.png" width="726" height="285.1728" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/10a2cd68-0045-4ad9-8b6d-09081d7974b2_1250x491.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:491,&quot;width&quot;:1250,&quot;resizeWidth&quot;:726,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&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_!caM9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a2cd68-0045-4ad9-8b6d-09081d7974b2_1250x491.png 424w, https://substackcdn.com/image/fetch/$s_!caM9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a2cd68-0045-4ad9-8b6d-09081d7974b2_1250x491.png 848w, https://substackcdn.com/image/fetch/$s_!caM9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a2cd68-0045-4ad9-8b6d-09081d7974b2_1250x491.png 1272w, https://substackcdn.com/image/fetch/$s_!caM9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10a2cd68-0045-4ad9-8b6d-09081d7974b2_1250x491.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></figure></div><pre><code><code>Input: height = [0,2,0,3,1,0,1,3,2,1]

Output: 9

Recommended Time &amp; Space Complexity
You should aim for a solution as good or better than O(n) time and O(n) space, where n is the size of the input array.</code></code></pre><h3>Brute Force Approach : </h3><p>For each index <code>i</code>, calculate the maximum left and right walls to find the trapped water.</p><p>Time Complexity : O(N^2)</p><p>Space Complexity : O(1)</p><h3>Suffix and Prefix Array : </h3><p>In this approach, we will maintain two arrays to precompute the maximum heights:</p><ul><li><p><strong>Prefix Array (</strong><code>leftMax</code><strong>):</strong> This array will store the highest wall encountered from the left side up to each element. Specifically, <code>leftMax[i]</code> represents the maximum height from index <code>0</code> to <code>i</code>.</p></li><li><p><strong>Suffix Array (</strong><code>rightMax</code><strong>):</strong> This array will store the highest wall encountered from the right side up to each element. Specifically, <code>rightMax[i]</code> represents the maximum height from index <code>i</code> to the end of the array (<code>n - 1</code>).</p></li></ul><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;dbe78b64-c50b-40a6-8b63-802cdf8c2bf8&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public class Solution {
    public int trap(int[] height) {
        int n = height.length;
        if (n == 0) {
            return 0;
        }

        int[] leftMax = new int[n];
        int[] rightMax = new int[n];

        leftMax[0] = height[0];
        for (int i = 1; i &lt; n; i++) {
            leftMax[i] = Math.max(leftMax[i - 1], height[i]);
        }

        rightMax[n - 1] = height[n - 1];
        for (int i = n - 2; i &gt;= 0; i--) {
            rightMax[i] = Math.max(rightMax[i + 1], height[i]);
        }

        int res = 0;
        for (int i = 0; i &lt; n; i++) {
            res += Math.min(leftMax[i], rightMax[i]) - height[i];
        }
        return res;
    }
}
// Time Complexity - O(n)
// Space Complexity - O(2n)</code></pre></div><p></p><h3>Two Pointer Approach : </h3><p>Intuition behind this : Water at any position depends on the shorter wall between the left and right sides. So if the left wall is shorter, the right wall can't help us&#8212;water is limited by the left side.<br>That means we safely move the left pointer inward and calculate how much water can be trapped there.<br>Similarly, if the right wall is shorter, we move the right pointer left.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;b1cee011-01c3-44b0-b16c-7ad8ec6ca65b&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public class Solution {
    public int trap(int[] height) {
        if (height == null || height.length == 0) {
            return 0;
        }
        int l = 0, r = height.length - 1;
        int leftMax = height[l], rightMax = height[r];
        int res = 0;
        while (l &lt; r) {
            if (leftMax &lt; rightMax) {
                res += leftMax - height[l];
                l++;
                leftMax = Math.max(leftMax, height[l]);
            } else {
                res += rightMax - height[r];
                r--;
                rightMax = Math.max(rightMax, height[r]);
            }
        }
        return res;
    }
}
// Time Complexity - O(n)
// Space Complexity - O(1)</code></pre></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://hrithikchandok.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">Thanks for reading! Subscribe for free to receive new posts and support my work.</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>]]></content:encoded></item><item><title><![CDATA[KPMG SDE1 Interview Experience: Complete Guide & DSA Questions]]></title><description><![CDATA[A step-by-step breakdown of my prep strategy, the interview format, and the exact LeetCode questions asked.]]></description><link>https://hrithikchandok.substack.com/p/kpmg-sde1-interview-experience-complete</link><guid isPermaLink="false">https://hrithikchandok.substack.com/p/kpmg-sde1-interview-experience-complete</guid><dc:creator><![CDATA[HrithikChandok]]></dc:creator><pubDate>Thu, 28 May 2026 13:16:32 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!2vGX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856ed526-cd1f-4333-a888-657b45d87bfb_826x640.jpeg" 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_!2vGX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856ed526-cd1f-4333-a888-657b45d87bfb_826x640.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2vGX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856ed526-cd1f-4333-a888-657b45d87bfb_826x640.jpeg 424w, https://substackcdn.com/image/fetch/$s_!2vGX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856ed526-cd1f-4333-a888-657b45d87bfb_826x640.jpeg 848w, https://substackcdn.com/image/fetch/$s_!2vGX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856ed526-cd1f-4333-a888-657b45d87bfb_826x640.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!2vGX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856ed526-cd1f-4333-a888-657b45d87bfb_826x640.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2vGX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856ed526-cd1f-4333-a888-657b45d87bfb_826x640.jpeg" width="826" height="640" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/856ed526-cd1f-4333-a888-657b45d87bfb_826x640.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:640,&quot;width&quot;:826,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:98796,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://hrithikchandok.substack.com/i/199360022?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0dea597-0a8f-4a73-ac2f-47dbeede515a_1200x1600.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_!2vGX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856ed526-cd1f-4333-a888-657b45d87bfb_826x640.jpeg 424w, https://substackcdn.com/image/fetch/$s_!2vGX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856ed526-cd1f-4333-a888-657b45d87bfb_826x640.jpeg 848w, https://substackcdn.com/image/fetch/$s_!2vGX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856ed526-cd1f-4333-a888-657b45d87bfb_826x640.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!2vGX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856ed526-cd1f-4333-a888-657b45d87bfb_826x640.jpeg 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></figure></div><p></p><h2>My Preparation Strategy</h2><p>To get interview-ready, my core focus was on building strong problem-solving fundamentals:</p><ul><li><p><strong><a href="https://neetcode.io/practice">Neetcode 150 Questions</a>:</strong> An essential list for mastering algorithmic patterns.</p></li><li><p><strong>Java Basics:</strong> Deep diving into the language fundamentals.</p></li><li><p><strong>Object-Oriented Programming (OOPs):</strong> Crucial for writing clean, structured code.</p></li></ul><div><hr></div><h2>The Interview Format</h2><p>Each technical round lasted exactly one hour and followed a rigorous, two-step format:</p><ol><li><p><strong>White-boarding:</strong> First, I had to write out the most optimal solution on paper.</p></li><li><p><strong>Live Coding:</strong> Next, I had to type that exact same logic into a LeetCode-style editor.</p></li></ol><h2>Round 1: DSA</h2><p>This round tested foundational data structures and array manipulation.</p><ul><li><p><strong>Q1:</strong> <a href="https://leetcode.com/problems/min-stack/">Min Stack</a></p></li><li><p><strong>Q2:</strong> <a href="https://leetcode.com/problems/capacity-to-ship-packages-within-d-days/">Capacity to Ship Packages Within D Days</a></p></li></ul><h2>Round 2: DSA</h2><p>This round shifted focus to searching algorithms and standard data structure design.</p><ul><li><p><strong>Q1:</strong> <a href="https://leetcode.com/problems/first-bad-version/">First Bad Version</a></p></li><li><p><strong>Q2:</strong> <a href="https://leetcode.com/problems/lru-cache/">LRU Cache</a><br></p></li></ul><h2>Additional Practice Questions</h2><p>Based on my experience, KPMG usually focuses on the easy-to-medium difficulty range. Here are a few more standard problems that are highly relevant for your preparation:</p><ul><li><p><a href="https://leetcode.com/problems/course-schedule/description/">Course Schedule</a></p></li><li><p><a href="https://leetcode.com/problems/symmetric-tree/description/">Symmetric Tree</a></p></li><li><p><a href="https://leetcode.com/problems/valid-parentheses/">Valid Parentheses</a></p></li></ul><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://hrithikchandok.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">Thanks for reading! Subscribe for free to receive new posts and support my work.</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><strong>Up Next:</strong> The Client Interview round in Part 2 : <a href="http://Loading">ComingSoon</a><br>If this guide helped your prep, drop a like and subscribe so you don't miss it. &#129293;<br></p>]]></content:encoded></item><item><title><![CDATA[Design Distributed Cache : Part 1 ]]></title><description><![CDATA[A solid understanding of Distributed Caching is essential before tackling any system design interview. This article breaks down the fundamentals, equipping you with the basics needed to design highly]]></description><link>https://hrithikchandok.substack.com/p/design-distributed-cache-part-1</link><guid isPermaLink="false">https://hrithikchandok.substack.com/p/design-distributed-cache-part-1</guid><dc:creator><![CDATA[HrithikChandok]]></dc:creator><pubDate>Sun, 24 May 2026 06:32:48 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!HwKs!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7662c0b0-f1e9-400d-a1b5-85bb39764171_1280x1280.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Topics to be Discussed </p><ol><li><p>Writing Policies</p></li><li><p>Eviction Policies</p></li><li><p>Cache Invalidation</p></li><li><p>Sharding in Cache Clusters<br></p></li></ol><div><hr></div><p><strong>WRITING POLICY </strong></p><ol><li><p><strong>Write Through</strong>  &#8594; Synchronously write to cache and DB to make sure data remains consistent between them . </p><ol><li><p>a pros &#8594; Data Consistency , No Stale Data</p></li><li><p>b cons &#8594; Latency in Write , Write heavy system might be laggy /slow .</p></li></ol></li><li><p><strong>Write Back</strong> &#8594; Write to Cache and Asychronously flushed the changes to DB .</p><ol><li><p>Pros &#8594; Low Write Latency </p></li><li><p>Cons &#8594; Data Loss in case of Cache Crashed Just Before Flushing to DB. Temporarily Inconsistency as well.</p></li></ol></li><li><p><strong>Write Around </strong>&#8594; Write will take place to DB . Then in case of Miss Cache will get the latest Data . </p><ol><li><p>Pros &#8594; Low Write Latency , No Data Loss .</p></li><li><p>Cons &#8594; Cache Would contain Stale Data , Data Inconsistency .</p></li></ol></li></ol><div><hr></div><p><strong>EVICTION POLICY </strong></p><ol><li><p><strong>Least Recently Used(LRU)</strong></p></li><li><p><strong>Least Frequently Used(LFU)</strong></p></li><li><p><strong>Most Recently Used(MRU)</strong></p></li><li><p><strong>Most Frequently Used(MFU)</strong></p></li><li><p><strong>First In First Out (FIFO)</strong></p><p></p></li></ol><div><hr></div><p><strong>CACHE INVALIDATION</strong></p><p>Time to Live ( TTL )&#8594; For each cache entry a TTL will be asign to each cache Entry . On the expiry of the that Time Limit . The Data in Cache would be considered as expired/InValid  data.</p><ol><li><p>Active Expiration &#8594; A background process periodically scans the cache and removes expired items.</p></li><li><p>Passive Expiration &#8594; An item&#8217;s TTL is checked only when it is requested. If it has expired, it is removed, and a cache miss is triggered.</p></li></ol><div><hr></div><p><strong>Sharding in cache Clusters </strong></p><ol><li><p><strong>Dedicated Cache Servers (Distributed Cache)</strong></p><ol><li><p>An independent network service that stores data in RAM across a cluster of separate, dedicated machines. It provides a centralized, shared caching layer decoupled from the application, allowing any application server in a distributed system to read and write to a single source of true cached state. <em>(Examples: Redis, Memcached, AWS ElastiCache)</em></p></li></ol></li><li><p><em><strong> </strong></em><strong>Co-Located Cache (Local / In-Process Cache)</strong></p><ol><li><p>A caching mechanism where data is stored directly within the local memory space (heap) of the application process itself. It eliminates network latency by sharing the same host hardware and lifecycle as the application, but limits the cached data to that specific application instance. <em>(Examples: Caffeine, Guava Cache, Python's </em><code>@lru_cache</code><em>)</em></p></li></ol></li><li><p><strong>Cache Client</strong></p><ol><li><p>A software library embedded within the application that manages connections, serialization, and operations against a cache service. In a distributed caching architecture, the client is responsible for data sharding and topology awareness&#8212;using algorithms like consistent hashing to deterministically route <code>PUT</code> and <code>GET</code> requests for a specific key to the correct node in the cache cluster.</p></li></ol><div><hr></div><p><strong>Next up in this series:</strong> Read Design Distributed Cache : Part 2 here <a href="http://Random">Coming Soon</a></p></li></ol>]]></content:encoded></item><item><title><![CDATA[Engineering Tinder: Scaling a System for 4 Billion Daily Swipes]]></title><description><![CDATA[Building a system architecture capable of managing a massive global dating application requires solving severe scaling issues, complex spatial queries, and extreme write-heavy workloads.]]></description><link>https://hrithikchandok.substack.com/p/engineering-tinder-scaling-a-system-for-4-billion-daily-swipes-28cfb97fad10</link><guid isPermaLink="false">https://hrithikchandok.substack.com/p/engineering-tinder-scaling-a-system-for-4-billion-daily-swipes-28cfb97fad10</guid><dc:creator><![CDATA[HrithikChandok]]></dc:creator><pubDate>Sun, 17 May 2026 10:59:28 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/02a1d497-a819-4607-ac80-b7eb11a4f7bd_1024x1218.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Building a system architecture capable of managing a massive global dating application requires solving severe scaling issues, complex spatial queries, and extreme write-heavy workloads. This article breaks down the end-to-end system design of Tinder, analyzing how it handles massive scale, location-based discovery, and real-time match detection.</p><h3>1. High-Level Architecture Overview</h3><p>To support tens of millions of Daily Active Users (DAU), the architecture is split into decoupled, horizontally scalable microservices. Each component is optimized for a specific domain&#8202;&#8212;&#8202;whether that is persistent profile storage, high-performance spatial indexing, or rapid write paths for user interactions.</p><p>The system relies on an <strong>API Gateway</strong> acting as the central entry point handling routing, authentication (JWT validation), and rate limiting. Behind it sit three core&nbsp;systems:</p><ul><li><p><strong>Profile Service:</strong> Manages user registration and modifications.</p></li><li><p><strong>Discovery Engine:</strong> Geographically targets and ranks potential matches.</p></li><li><p><strong>Swipe Service:</strong> Absorbs the massive firehose of user interactions.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Y1J_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6fa555d-ff03-4927-b336-19bffa0cd9c5_1024x1218.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Y1J_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6fa555d-ff03-4927-b336-19bffa0cd9c5_1024x1218.png 424w, https://substackcdn.com/image/fetch/$s_!Y1J_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6fa555d-ff03-4927-b336-19bffa0cd9c5_1024x1218.png 848w, https://substackcdn.com/image/fetch/$s_!Y1J_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6fa555d-ff03-4927-b336-19bffa0cd9c5_1024x1218.png 1272w, https://substackcdn.com/image/fetch/$s_!Y1J_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6fa555d-ff03-4927-b336-19bffa0cd9c5_1024x1218.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Y1J_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6fa555d-ff03-4927-b336-19bffa0cd9c5_1024x1218.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b6fa555d-ff03-4927-b336-19bffa0cd9c5_1024x1218.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Y1J_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6fa555d-ff03-4927-b336-19bffa0cd9c5_1024x1218.png 424w, https://substackcdn.com/image/fetch/$s_!Y1J_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6fa555d-ff03-4927-b336-19bffa0cd9c5_1024x1218.png 848w, https://substackcdn.com/image/fetch/$s_!Y1J_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6fa555d-ff03-4927-b336-19bffa0cd9c5_1024x1218.png 1272w, https://substackcdn.com/image/fetch/$s_!Y1J_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6fa555d-ff03-4927-b336-19bffa0cd9c5_1024x1218.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a><figcaption class="image-caption">Tinder Complete&nbsp;Design</figcaption></figure></div><h3>2. The Dual-Database Strategy: Profile Service vs. Discovery Index</h3><p>A common interview trap is trying to force a single database to handle both regular user management and complex spatial discovery queries. Tinder elegantly solves this by decoupling its data into two specialized layers: <strong>DynamoDB</strong> (the Source of Truth) and <strong>Elasticsearch</strong> (the Discovery Index).</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!l9mG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feef9a7bf-1d82-4dd2-be5d-5d69fb26518e_1024x848.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!l9mG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feef9a7bf-1d82-4dd2-be5d-5d69fb26518e_1024x848.png 424w, https://substackcdn.com/image/fetch/$s_!l9mG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feef9a7bf-1d82-4dd2-be5d-5d69fb26518e_1024x848.png 848w, https://substackcdn.com/image/fetch/$s_!l9mG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feef9a7bf-1d82-4dd2-be5d-5d69fb26518e_1024x848.png 1272w, https://substackcdn.com/image/fetch/$s_!l9mG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feef9a7bf-1d82-4dd2-be5d-5d69fb26518e_1024x848.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!l9mG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feef9a7bf-1d82-4dd2-be5d-5d69fb26518e_1024x848.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/eef9a7bf-1d82-4dd2-be5d-5d69fb26518e_1024x848.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!l9mG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feef9a7bf-1d82-4dd2-be5d-5d69fb26518e_1024x848.png 424w, https://substackcdn.com/image/fetch/$s_!l9mG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feef9a7bf-1d82-4dd2-be5d-5d69fb26518e_1024x848.png 848w, https://substackcdn.com/image/fetch/$s_!l9mG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feef9a7bf-1d82-4dd2-be5d-5d69fb26518e_1024x848.png 1272w, https://substackcdn.com/image/fetch/$s_!l9mG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feef9a7bf-1d82-4dd2-be5d-5d69fb26518e_1024x848.png 1456w" sizes="100vw"></picture><div></div></div></a></figure></div><h3>DynamoDB&#8202;&#8212;&#8202;The Source of&nbsp;Truth</h3><p>The Profile Service writes synchronously to Amazon DynamoDB. Relational databases (SQL) are intentionally avoided here because the system does not require complex ACID transactions, multi-table joins, or foreign keys. Instead, it requires predictable scaling and high-performance key-value lookups.</p><ul><li><p><strong>Data Structure:</strong> Profiles are stored as single documents.</p></li><li><p><strong>Access Pattern:</strong> When a user requests a profile via GET /profile/{id}, it executes a direct, single-partition point lookup using the userId as the Partition Key (PK). This bypasses expensive table scans entirely.</p></li><li><p><strong>TTL &amp; Inactivity:</strong> A Time-To-Live (TTL) attribute is assigned to lastHeartbeat. If a user is inactive for more than 24 hours, DynamoDB Streams can catch this event to trigger background reactivation workflows or push notifications.</p></li></ul><h3>Elasticsearch&#8202;&#8212;&#8202;The Discovery Index</h3><p>Elasticsearch (ES) serves as a specialized, slimmed-down copy of the profile data. It is optimized explicitly for high-velocity filtering and relevance sorting rather than primary data durability.</p><ul><li><p><strong>Asynchronous Decoupling via Kafka:</strong> Writing directly to Elasticsearch from the synchronous profile path is dangerous. If the Elasticsearch cluster undergoes a node failure or experiences a latency spike, the primary Profile Service would degrade. To prevent this, the Profile Service writes updates to a Kafka topic (user.profile.created/updated). An <strong>ES Feeder Worker</strong> consumes these events asynchronously, buffering the load and ensuring isolation.</p></li></ul><h3>3. The Discovery Engine &amp; Spatial Geosharding</h3><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8xmj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F479b2dba-bc50-4d9d-9a59-72612f7bb289_1024x803.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8xmj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F479b2dba-bc50-4d9d-9a59-72612f7bb289_1024x803.png 424w, https://substackcdn.com/image/fetch/$s_!8xmj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F479b2dba-bc50-4d9d-9a59-72612f7bb289_1024x803.png 848w, https://substackcdn.com/image/fetch/$s_!8xmj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F479b2dba-bc50-4d9d-9a59-72612f7bb289_1024x803.png 1272w, https://substackcdn.com/image/fetch/$s_!8xmj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F479b2dba-bc50-4d9d-9a59-72612f7bb289_1024x803.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8xmj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F479b2dba-bc50-4d9d-9a59-72612f7bb289_1024x803.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/479b2dba-bc50-4d9d-9a59-72612f7bb289_1024x803.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!8xmj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F479b2dba-bc50-4d9d-9a59-72612f7bb289_1024x803.png 424w, https://substackcdn.com/image/fetch/$s_!8xmj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F479b2dba-bc50-4d9d-9a59-72612f7bb289_1024x803.png 848w, https://substackcdn.com/image/fetch/$s_!8xmj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F479b2dba-bc50-4d9d-9a59-72612f7bb289_1024x803.png 1272w, https://substackcdn.com/image/fetch/$s_!8xmj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F479b2dba-bc50-4d9d-9a59-72612f7bb289_1024x803.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>When a mobile client calls GET /feed?lat=12.97&amp;lon=77.59&amp;dist=50, the system must search through millions of profiles instantly. Doing a raw SQL-style bounding box filter (SELECT * WHERE distance &lt; 50km) against 50 million active users causes full table scans and completely breaks at&nbsp;scale.</p><p>Tinder scales this layer using <strong>GeoSharding</strong> powered by Google&#8217;s open-source <strong>S2 Geometry&nbsp;Library</strong>.</p><h3>How S2 Spatial Sharding&nbsp;Works</h3><p>The S2 library projects the Earth&#8217;s sphere onto a flat surface and hierarchically subdivides it into cell structures.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AKf6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc36f1fd-be0f-4921-a126-9d771bf05ace_1024x643.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AKf6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc36f1fd-be0f-4921-a126-9d771bf05ace_1024x643.png 424w, https://substackcdn.com/image/fetch/$s_!AKf6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc36f1fd-be0f-4921-a126-9d771bf05ace_1024x643.png 848w, https://substackcdn.com/image/fetch/$s_!AKf6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc36f1fd-be0f-4921-a126-9d771bf05ace_1024x643.png 1272w, https://substackcdn.com/image/fetch/$s_!AKf6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc36f1fd-be0f-4921-a126-9d771bf05ace_1024x643.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AKf6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc36f1fd-be0f-4921-a126-9d771bf05ace_1024x643.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dc36f1fd-be0f-4921-a126-9d771bf05ace_1024x643.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!AKf6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc36f1fd-be0f-4921-a126-9d771bf05ace_1024x643.png 424w, https://substackcdn.com/image/fetch/$s_!AKf6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc36f1fd-be0f-4921-a126-9d771bf05ace_1024x643.png 848w, https://substackcdn.com/image/fetch/$s_!AKf6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc36f1fd-be0f-4921-a126-9d771bf05ace_1024x643.png 1272w, https://substackcdn.com/image/fetch/$s_!AKf6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc36f1fd-be0f-4921-a126-9d771bf05ace_1024x643.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><ol><li><p><strong>Dynamic Cell Sizes:</strong> Cell dimensions are mathematically derived based on regional user density, active user counts, and query velocity. Highly populated, high-density metropolitan areas like Mumbai are divided into numerous <strong>small cells</strong>. Sparsely populated regions, such as the Sahara Desert, are mapped to a single <strong>massive cell</strong>. This ensures that the overall server compute load remains uniform worldwide.</p></li><li><p><strong>Parallel Fan-Out Queries:</strong> When a user requests a feed, the Discovery Engine passes their exact latitude, longitude, and radius parameters into the S2 library. The library calculates and returns a discrete list of intersecting cell IDs that cover that&nbsp;radius.</p></li></ol><p>Rather than hitting a single monolithic database cluster, the system executes a <strong>parallel fan-out query</strong> across the specific Elasticsearch shards assigned to those exact cell IDs (e.g., Shards A, B, C, and&nbsp;D).</p><h3>Inside the Elasticsearch Shard: Filter vs.&nbsp;Sort</h3><p>Once the parallel queries hit the designated geoshards, the search process executes in two distinct&nbsp;phases:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6NOX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03d04d81-d324-48a9-a96b-632861f5d0da_1024x614.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6NOX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03d04d81-d324-48a9-a96b-632861f5d0da_1024x614.png 424w, https://substackcdn.com/image/fetch/$s_!6NOX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03d04d81-d324-48a9-a96b-632861f5d0da_1024x614.png 848w, https://substackcdn.com/image/fetch/$s_!6NOX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03d04d81-d324-48a9-a96b-632861f5d0da_1024x614.png 1272w, https://substackcdn.com/image/fetch/$s_!6NOX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03d04d81-d324-48a9-a96b-632861f5d0da_1024x614.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6NOX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03d04d81-d324-48a9-a96b-632861f5d0da_1024x614.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/03d04d81-d324-48a9-a96b-632861f5d0da_1024x614.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!6NOX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03d04d81-d324-48a9-a96b-632861f5d0da_1024x614.png 424w, https://substackcdn.com/image/fetch/$s_!6NOX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03d04d81-d324-48a9-a96b-632861f5d0da_1024x614.png 848w, https://substackcdn.com/image/fetch/$s_!6NOX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03d04d81-d324-48a9-a96b-632861f5d0da_1024x614.png 1272w, https://substackcdn.com/image/fetch/$s_!6NOX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03d04d81-d324-48a9-a96b-632861f5d0da_1024x614.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><ul><li><p><strong>Phase 1: Filter Context (Hard Exclusions):</strong> The engine evaluates rigid Boolean requirements (e.g., geo_distance &lt;= 50km, age between 22-30, interestedIn == "female", moderationStatus == "ok"). This step operates inside a specialized filter context, bypassing relevance scoring. The binary yes/no results are cached inside highly optimized bitsets within memory, resulting in virtually zero recurring execution cost.</p></li><li><p><strong>Phase 2: Query Context (Relevance Scoring):</strong> Profiles that survive the hard filters pass into the sorting engine. Here, a custom script plugin calculates a floating-point score based on tinder algorithms, incorporating factors like activityScore (primary) and lastActiveAt (recency boost). The top ~25 highest-scoring documents per shard are returned to the Discovery Engine, which merges, de-duplicates, and filters out previously swiped profiles before delivering a final feed of ~20 profiles back to the mobile client in less than&nbsp;300ms.</p></li></ul><h3>4. The Swipe Service: Handling 4 Billion Swipes&nbsp;Daily</h3><p>The true engineering bottleneck of a major dating application is the write path for user interaction. Consider the core scale&nbsp;metrics:</p><p>20M Daily Active Users * 200 swipes/day = 4 Billion swipe writes per&nbsp;day</p><p>This volume averages out to roughly <strong>46,000 writes per second</strong>, with massive traffic spikes during peak evening windows. The architecture of the Swipe Service is engineered end-to-end to absorb this massive throughput without performance degradation.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LrDb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51913170-04fb-47a3-b832-515769776b1a_1024x804.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LrDb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51913170-04fb-47a3-b832-515769776b1a_1024x804.png 424w, https://substackcdn.com/image/fetch/$s_!LrDb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51913170-04fb-47a3-b832-515769776b1a_1024x804.png 848w, https://substackcdn.com/image/fetch/$s_!LrDb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51913170-04fb-47a3-b832-515769776b1a_1024x804.png 1272w, https://substackcdn.com/image/fetch/$s_!LrDb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51913170-04fb-47a3-b832-515769776b1a_1024x804.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LrDb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51913170-04fb-47a3-b832-515769776b1a_1024x804.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/51913170-04fb-47a3-b832-515769776b1a_1024x804.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!LrDb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51913170-04fb-47a3-b832-515769776b1a_1024x804.png 424w, https://substackcdn.com/image/fetch/$s_!LrDb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51913170-04fb-47a3-b832-515769776b1a_1024x804.png 848w, https://substackcdn.com/image/fetch/$s_!LrDb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51913170-04fb-47a3-b832-515769776b1a_1024x804.png 1272w, https://substackcdn.com/image/fetch/$s_!LrDb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51913170-04fb-47a3-b832-515769776b1a_1024x804.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h3>The Synchronous Swipe&nbsp;Path</h3><p>When a user right-swipes, the mobile client executes a POST /swipe/{targetId} call containing the payload { decision: "yes" }. The Swipe Service validates the inbound JSON Web Token (JWT), extracts the swiperId and targetId, and immediately forks the execution path into two distinct concurrent streams:</p><ol><li><p><strong>Persistence Layer (Cassandra):</strong> The interaction is instantly written to Apache Cassandra. Because Cassandra writes are highly optimized disk appends, this call returns almost immediately. Once the Cassandra log append and in-memory structures acknowledge the write, the system returns a 200 OK HTTP status to the client app. The client does not block or wait for match processing to complete.</p></li><li><p><strong>In-Memory Match Detection (Redis):</strong> Concurrently, the service leverages Redis to run ultra-low latency lookups to check if the target user has already liked the&nbsp;swiper.</p></li></ol><h3>5. Real-Time Match Detection Using&nbsp;Redis</h3><p>Querying a persistent disk-based database to evaluate if two users have mutually liked each other is far too slow for real-time engagement. Instead, Redis handles match detection completely in-memory using an elegant key-naming convention.</p><h3>The Key-Value Lookup&nbsp;Pattern</h3><p>The system stores swipe states using a highly deterministic string formatting structure: swiperId_targetId. Let's analyze the exact command flow when <strong>Person B (id: 456)</strong> right-swipes on <strong>Person A (id:&nbsp;123)</strong>:</p><p>Code snippet</p><pre><code>SET 456_123 "yes" EX 1209600
GET 123_456</code></pre><ul><li><p>The system runs a SET command to log Person B's swipe with an explicit 14-day Time-To-Live (TTL) expiration window</p></li><li><p>It instantly fires a GET 123_456 command to verify if Person A has an active historical swipe record pointing back to Person B. If the GET command hits an active value, a mutual match is instantly confirmed.</p></li></ul><h3>Managing Memory Footprint via&nbsp;TTL</h3><p>Because memory is highly expensive and holding millions of historical keys indefinitely is unfeasible, the 14-day TTL trade-off is critical. If Person A swiped right on Person B three weeks ago, that key has automatically expired out of memory. If Person B swipes right today, the GET lookup returns a cache&nbsp;miss.</p><p>This design choice means no instant match will fire; instead, the interaction falls back onto the background batch processing engine or requires an eventual profile re-encounter, sacrificing absolute edge-case accuracy to maintain an optimized Redis memory footprint.</p><h3>Eliminating Race Conditions via Atomic Lua&nbsp;Scripts</h3><p>A prominent system design trap occurs during simultaneous swipes. If Person A and Person B right-swipe each other at the exact same millisecond across different application nodes, a classic race condition emerges:</p><ul><li><p><strong>Node A Execution:</strong> Executes SET A_B, then runs GET B_A. It returns a cache miss because Node B&#8217;s write has not yet committed.</p></li><li><p><strong>Node B Execution:</strong> Executes SET B_A, then runs GET A_B. It also returns a cache miss because Node A&#8217;s write was concurrent.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oh0y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4afbf938-f7da-4c86-9ee9-02942d729e1e_1024x640.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oh0y!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4afbf938-f7da-4c86-9ee9-02942d729e1e_1024x640.png 424w, https://substackcdn.com/image/fetch/$s_!oh0y!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4afbf938-f7da-4c86-9ee9-02942d729e1e_1024x640.png 848w, https://substackcdn.com/image/fetch/$s_!oh0y!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4afbf938-f7da-4c86-9ee9-02942d729e1e_1024x640.png 1272w, https://substackcdn.com/image/fetch/$s_!oh0y!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4afbf938-f7da-4c86-9ee9-02942d729e1e_1024x640.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oh0y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4afbf938-f7da-4c86-9ee9-02942d729e1e_1024x640.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4afbf938-f7da-4c86-9ee9-02942d729e1e_1024x640.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!oh0y!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4afbf938-f7da-4c86-9ee9-02942d729e1e_1024x640.png 424w, https://substackcdn.com/image/fetch/$s_!oh0y!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4afbf938-f7da-4c86-9ee9-02942d729e1e_1024x640.png 848w, https://substackcdn.com/image/fetch/$s_!oh0y!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4afbf938-f7da-4c86-9ee9-02942d729e1e_1024x640.png 1272w, https://substackcdn.com/image/fetch/$s_!oh0y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4afbf938-f7da-4c86-9ee9-02942d729e1e_1024x640.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Both operations miss, failing to detect the mutual match in real time. Tinder resolves this by packaging the lookup logic into an <strong>atomic Lua Script</strong> executed directly inside the single-threaded execution loop of the Redis&nbsp;engine:</p><p>Lua</p><pre><code>redis.call('SET', KEYS[1], 'yes', 'EX', 1209600)
local inverse = redis.call('GET', KEYS[2])
return inverse</code></pre><p>Because Redis guarantees that a Lua script runs as an isolated, atomic block, no separate commands can interleave between the write and the check, entirely eliminating simultaneous race conditions.</p><p>As a redundant safety net, a background reconciliation system periodically sweeps historical Cassandra entries to catch any mismatched anomalies and retroactively deliver push notifications to affected&nbsp;users.</p><h3>6. Storage Deep-Dive: Why Apache Cassandra Dominates Writes</h3><p>Standard relational database management systems (RDBMS) like MySQL or PostgreSQL fall over under a continuous load of 46,000 writes/second. This failure happens because relational engines utilize B-Tree indexing structures, which require random I/O operations to modify indexes in-place on physical storage&nbsp;media.</p><p>Apache Cassandra circumvents this bottleneck by ensuring the physical write path relies entirely on sequential disk append operations.</p><h3>The Append-Only Log Architecture</h3><p>Cassandra processes incoming swipe data through a three-stage pipeline:</p><ul><li><p><strong>CommitLog (Write-Ahead Log):</strong> The write request lands on a physical storage node and is appended sequentially to an on-disk CommitLog. Because it acts as a plain sequential append stream, the physical drive head doesn't shift positions, maximizing disk performance. This serves as a durability guarantee if a node suffers sudden power&nbsp;loss.</p></li><li><p><strong>MemTable (In-Memory Buffer):</strong> The data immediately populates an internal, sorted write-buffer in RAM called the MemTable. Once the data is registered in the MemTable, the database returns a success code to the application layer.</p></li><li><p><strong>SSTables (Sorted String Tables):</strong> When the MemTable reaches its maximum memory capacity (typically ~32MB), it flushes its sorted contents to disk as an immutable SSTable file. Because SSTables are completely immutable, they are never modified in-place. A background compaction process periodically merges older, separate tables together while filtering out outdated&nbsp;records.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ih5t!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9b47cfb-515f-4a69-9c1e-4b67f78c72d4_1024x652.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ih5t!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9b47cfb-515f-4a69-9c1e-4b67f78c72d4_1024x652.png 424w, https://substackcdn.com/image/fetch/$s_!ih5t!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9b47cfb-515f-4a69-9c1e-4b67f78c72d4_1024x652.png 848w, https://substackcdn.com/image/fetch/$s_!ih5t!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9b47cfb-515f-4a69-9c1e-4b67f78c72d4_1024x652.png 1272w, https://substackcdn.com/image/fetch/$s_!ih5t!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9b47cfb-515f-4a69-9c1e-4b67f78c72d4_1024x652.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ih5t!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9b47cfb-515f-4a69-9c1e-4b67f78c72d4_1024x652.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a9b47cfb-515f-4a69-9c1e-4b67f78c72d4_1024x652.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!ih5t!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9b47cfb-515f-4a69-9c1e-4b67f78c72d4_1024x652.png 424w, https://substackcdn.com/image/fetch/$s_!ih5t!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9b47cfb-515f-4a69-9c1e-4b67f78c72d4_1024x652.png 848w, https://substackcdn.com/image/fetch/$s_!ih5t!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9b47cfb-515f-4a69-9c1e-4b67f78c72d4_1024x652.png 1272w, https://substackcdn.com/image/fetch/$s_!ih5t!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9b47cfb-515f-4a69-9c1e-4b67f78c72d4_1024x652.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h3>Maximizing Query Speeds via Partitions</h3><p>Cassandra achieves linear horizontal scalability by hashing data properties across cluster rings using a <strong>Partition Key</strong>.</p><p>Tinder partitions data directly by swiping_user_id. When the application queries the data to check user status (e.g., <em>"Did user_123 swipe on user_A?"</em>), the query hashes the partition ID and routes directly to the single cluster node holding that user's partition block. This completely eliminates expensive cross-node scatter-gather operations, executing reads within sub-millisecond windows.</p><h3>7. Optimizing Feeds using Bloom&nbsp;Filters</h3><p>To prevent users from seeing profiles they have already swiped on, the discovery feed generation needs a memory-efficient way to check for past interactions. Rather than scanning Cassandra records for every candidate profile in a feed, the system relies on an in-memory probabilistic data structure: a <strong>Bloom&nbsp;Filter</strong>.</p><h3>How the Bloom Filter&nbsp;Works</h3><p>A Bloom filter represents historical interactions using a bit array of $m$ bits (initially all set to 0) combined with $k$ independent cryptographic hash functions.</p><ul><li><p><strong>Writing an Interaction:</strong> When a user left-swipes or right-swipes a profile (userId = "u_456"), that ID is passed through the $k$ hash functions. Each function outputs a specific index position inside the bit array (e.g., indices 2, 7, and 12). The system flips those specific bits to&nbsp;1.</p></li><li><p><strong>Checking an Interaction:</strong> When evaluating whether a candidate profile (u_999) should appear in a user's discovery feed, the system runs the candidate ID through the same hash functions.</p></li><li><p>If <strong>any</strong> of the computed bit locations contain a value of 0, the profile is <strong>definitely not seen</strong> and can safely be included in the&nbsp;feed.</p></li><li><p>If <strong>all</strong> evaluated bit locations contain a value of 1, the profile is flagged as <strong>probably seen</strong> and is excluded from the&nbsp;feed.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WzfR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5595346c-f4b1-47a9-b4bd-14380db3e382_1024x582.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WzfR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5595346c-f4b1-47a9-b4bd-14380db3e382_1024x582.png 424w, https://substackcdn.com/image/fetch/$s_!WzfR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5595346c-f4b1-47a9-b4bd-14380db3e382_1024x582.png 848w, https://substackcdn.com/image/fetch/$s_!WzfR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5595346c-f4b1-47a9-b4bd-14380db3e382_1024x582.png 1272w, https://substackcdn.com/image/fetch/$s_!WzfR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5595346c-f4b1-47a9-b4bd-14380db3e382_1024x582.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WzfR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5595346c-f4b1-47a9-b4bd-14380db3e382_1024x582.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5595346c-f4b1-47a9-b4bd-14380db3e382_1024x582.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!WzfR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5595346c-f4b1-47a9-b4bd-14380db3e382_1024x582.png 424w, https://substackcdn.com/image/fetch/$s_!WzfR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5595346c-f4b1-47a9-b4bd-14380db3e382_1024x582.png 848w, https://substackcdn.com/image/fetch/$s_!WzfR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5595346c-f4b1-47a9-b4bd-14380db3e382_1024x582.png 1272w, https://substackcdn.com/image/fetch/$s_!WzfR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5595346c-f4b1-47a9-b4bd-14380db3e382_1024x582.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h3>The Probabilistic Trade-Off</h3><p>Bloom filters guarantee <strong>zero false negatives</strong>&#8202;&#8212;&#8202;if a user swiped on a profile, its corresponding bits are mathematically guaranteed to be set to 1, meaning the user will never accidentally see a profile they already rejected.</p><p>While <strong>false positives</strong> are statistically possible due to rare bit collisions (where separate IDs happen to map to the same set of bits), the trade-off is highly acceptable. At worst, a user misses out on seeing a single candidate profile, which is a negligible cost for a massive reduction in database read operations.</p><p><strong>Summary of Architectural Choices</strong></p><ul><li><p><strong>User Profile Storage:</strong> Amazon&nbsp;DynamoDB</p></li><li><p><em>Core Reason:</em> High-performance, schema less document point lookups via&nbsp;userId.</p></li><li><p><strong>Discovery Search Engine:</strong> Elasticsearch</p></li><li><p><em>Core Reason:</em> Lightning-fast spatial filter caching and dynamic relevance scoring.</p></li><li><p><strong>Spatial Indexing:</strong> Google S2&nbsp;Library</p></li><li><p><em>Core Reason:</em> Translates coordinates into discrete cell clusters for parallelized geosharding.</p></li><li><p><strong>Data Streaming:</strong> Apache&nbsp;Kafka</p></li><li><p><em>Core Reason:</em> Decouples profile updates and swipe match events from execution paths.</p></li><li><p><strong>High-Throughput Swipes:</strong> Apache Cassandra</p></li><li><p><em>Core Reason:</em> Append-only write path (CommitLog + MemTable) that scales linearly.</p></li><li><p><strong>Real-Time Match Engine:</strong> Redis +&nbsp;Lua</p></li><li><p><em>Core Reason:</em> Ultra-low latency, in-memory atomic key-value operations.</p></li><li><p><strong>Feed Deduplication:</strong> Bloom&nbsp;Filters</p></li><li><p><em>Core Reason:</em> Highly space-efficient method to prevent duplicate profile encounters.</p></li><li><p><strong>Real-Time Push Alerts:</strong> WebSockets +&nbsp;APNS/FCM</p></li><li><p><em>Core Reason:</em> Maintains open connections for matches and background notification routing.</p></li></ul>]]></content:encoded></item><item><title><![CDATA[How to Answer Any System Design Interview]]></title><description><![CDATA[System Design interviews are not about giving the &#8220;perfect architecture.&#8221;]]></description><link>https://hrithikchandok.substack.com/p/how-to-answer-any-system-design-interview</link><guid isPermaLink="false">https://hrithikchandok.substack.com/p/how-to-answer-any-system-design-interview</guid><dc:creator><![CDATA[HrithikChandok]]></dc:creator><pubDate>Sat, 16 May 2026 08:37:13 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!HwKs!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7662c0b0-f1e9-400d-a1b5-85bb39764171_1280x1280.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>System Design interviews are not about giving the &#8220;perfect architecture.&#8221;<br>They are mainly about showing how you think, how you break problems down, and how you make engineering decisions.</p><p>The biggest mistake people make is jumping straight into databases or randomly naming technologies.<br>Instead, always follow a simple structure.</p><div><hr></div><h1>The Flow to Follow</h1><pre><code><code>1. Requirements
2. Estimations
3. High-Level Design
4. Database Design
5. APIs &amp; Data Flow
6. Deep Dive
7. Scaling
8. Reliability
9. Security
10. Tradeoffs
11. Bottlenecks &amp; Improvements
</code></code></pre><div><hr></div><h1>1. Understand the Requirements</h1><p>Before designing anything, first understand:</p><ul><li><p>What are we building?</p></li><li><p>What features are needed?</p></li><li><p>What scale are we talking about?</p></li><li><p>Is consistency important or availability?</p></li></ul><p>Example:</p><ul><li><p>millions of users?</p></li><li><p>low latency?</p></li><li><p>real-time updates?</p></li></ul><p>This helps shape the entire design.</p><div><hr></div><h1>2. Estimate the Scale</h1><p>Do rough calculations:</p><ul><li><p>requests per second,</p></li><li><p>storage,</p></li><li><p>traffic,</p></li><li><p>daily active users.</p></li></ul><p>The goal is not perfect math.<br>The goal is to justify your architecture decisions.</p><div><hr></div><h1>3. Start with High-Level Design</h1><p>Begin with a simple flow:</p><pre><code><code>Client
&#8594; Load Balancer
&#8594; API Gateway
&#8594; Application Servers
&#8594; Cache / Queue / Database
</code></code></pre><p>For every component, explain:</p><ul><li><p>why it exists,</p></li><li><p>what problem it solves,</p></li><li><p>and why it helps at scale.</p></li></ul><div><hr></div><h1>4. Design the Database</h1><p>Decide:</p><ul><li><p>SQL or NoSQL?</p></li></ul><p>Then discuss:</p><ul><li><p>partitioning,</p></li><li><p>indexing,</p></li><li><p>replication,</p></li><li><p>sharding.</p></li></ul><p>A big focus should be:</p><blockquote><p>&#8220;How will this database scale?&#8221;</p></blockquote><div><hr></div><h1>5. Explain APIs and Data Flow</h1><p>Show how a request moves through the system.</p><p>Example:</p><pre><code><code>Client &#8594; Server &#8594; Database &#8594; Kafka &#8594; Notification Service
</code></code></pre><p>This shows that you understand real backend workflows.</p><div><hr></div><h1>6. Deep Dive Into Important Parts</h1><p>This is usually the most important section.</p><p>Pick 1&#8211;2 complex areas and go deeper.</p><p>Examples:</p><ul><li><p>message ordering in chat apps,</p></li><li><p>driver matching in ride-sharing,</p></li><li><p>feed generation,</p></li><li><p>caching strategy,</p></li><li><p>real-time communication.</p></li></ul><p>This is where interviews are often won.</p><div><hr></div><h1>7. Explain How the System Scales</h1><p>Talk about:</p><ul><li><p>horizontal scaling,</p></li><li><p>caching,</p></li><li><p>sharding,</p></li><li><p>queues,</p></li><li><p>read replicas,</p></li><li><p>CDN.</p></li></ul><p>The interviewer wants to know:</p><blockquote><p>&#8220;Will this still work if traffic becomes 100x bigger?&#8221;</p></blockquote><div><hr></div><h1>8. Reliability Matters</h1><p>Strong candidates always discuss failure handling.</p><p>Mention:</p><ul><li><p>retries,</p></li><li><p>dead letter queues,</p></li><li><p>failover,</p></li><li><p>replication,</p></li><li><p>idempotency,</p></li><li><p>circuit breakers.</p></li></ul><p>Real systems fail all the time.<br>Good engineers design for failures.</p><div><hr></div><h1>9. Mention Security</h1><p>Briefly cover:</p><ul><li><p>HTTPS,</p></li><li><p>authentication,</p></li><li><p>JWT/OAuth,</p></li><li><p>encryption,</p></li><li><p>rate limiting.</p></li></ul><p>A small security discussion makes your answer feel complete.</p><div><hr></div><h1>10. Discuss Tradeoffs</h1><p>This is one of the most important parts.</p><p>There is no perfect system.<br>Every design choice has tradeoffs.</p><p>Examples:</p><ul><li><p>consistency vs availability,</p></li><li><p>SQL vs NoSQL,</p></li><li><p>synchronous vs asynchronous processing.</p></li></ul><p>The interviewer cares more about:</p><blockquote><p>why you chose something</p></blockquote><p>than the technology itself.</p><div><hr></div><h1>11. End with Bottlenecks and Improvements</h1><p>Finally, discuss:</p><ul><li><p>possible bottlenecks,</p></li><li><p>scaling challenges,</p></li><li><p>hot partitions,</p></li><li><p>cache issues,</p></li><li><p>database pressure.</p></li></ul><p>Then suggest improvements.</p><p>This shows mature engineering thinking.</p><div><hr></div><h1>What Interviewers Actually Want</h1><p>They are not checking whether you can build Google or Netflix from scratch.</p><p>They mainly want to see:</p><ul><li><p>structured thinking,</p></li><li><p>clear communication,</p></li><li><p>tradeoff awareness,</p></li><li><p>scalability understanding,</p></li><li><p>and problem-solving ability.</p></li></ul><p>If your thinking process is clear and structured, even an imperfect design can still be a very strong interview answer.</p>]]></content:encoded></item><item><title><![CDATA[What is Pub/Sub Messaging?]]></title><description><![CDATA[System Design Fundamentals]]></description><link>https://hrithikchandok.substack.com/p/what-is-pubsub-messaging</link><guid isPermaLink="false">https://hrithikchandok.substack.com/p/what-is-pubsub-messaging</guid><dc:creator><![CDATA[HrithikChandok]]></dc:creator><pubDate>Mon, 11 May 2026 07:18:54 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!B_7B!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa9345d1-f385-4aa9-a7aa-8043f2d6ff3c_1520x921.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Publish/Subscribe (Pub/Sub)</strong> is an asynchronous service-to-service communication pattern. In this model, any message published to a <strong>topic</strong> (a logical channel) is immediately received by all <strong>subscribers</strong> of that topic.</p><p>The defining feature is <strong>decoupling</strong>:</p><ul><li><p><strong>Publishers</strong> don&#8217;t know who is receiving the messages.</p></li><li><p><strong>Subscribers</strong> don&#8217;t need to know who sent the message.</p></li><li><p>The <strong>Message Broker</strong> sits in the middle, handling the routing and delivery.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!B_7B!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa9345d1-f385-4aa9-a7aa-8043f2d6ff3c_1520x921.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!B_7B!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa9345d1-f385-4aa9-a7aa-8043f2d6ff3c_1520x921.png 424w, https://substackcdn.com/image/fetch/$s_!B_7B!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa9345d1-f385-4aa9-a7aa-8043f2d6ff3c_1520x921.png 848w, https://substackcdn.com/image/fetch/$s_!B_7B!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa9345d1-f385-4aa9-a7aa-8043f2d6ff3c_1520x921.png 1272w, https://substackcdn.com/image/fetch/$s_!B_7B!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa9345d1-f385-4aa9-a7aa-8043f2d6ff3c_1520x921.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!B_7B!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa9345d1-f385-4aa9-a7aa-8043f2d6ff3c_1520x921.png" width="1456" height="882" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fa9345d1-f385-4aa9-a7aa-8043f2d6ff3c_1520x921.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:882,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&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_!B_7B!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa9345d1-f385-4aa9-a7aa-8043f2d6ff3c_1520x921.png 424w, https://substackcdn.com/image/fetch/$s_!B_7B!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa9345d1-f385-4aa9-a7aa-8043f2d6ff3c_1520x921.png 848w, https://substackcdn.com/image/fetch/$s_!B_7B!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa9345d1-f385-4aa9-a7aa-8043f2d6ff3c_1520x921.png 1272w, https://substackcdn.com/image/fetch/$s_!B_7B!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa9345d1-f385-4aa9-a7aa-8043f2d6ff3c_1520x921.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></figure></div><div><hr></div><h3>Core Concepts &amp; Filtering</h3><p>In Pub/Sub, subscribers usually only want a specific subset of messages. This is handled through <strong>filtering</strong>:</p><ul><li><p><strong>Topic-Based Filtering:</strong> Messages are published to named channels (e.g., <code>orders</code>, <code>logs</code>). Subscribers receive everything on that channel.</p></li><li><p><strong>Content-Based Filtering:</strong> The broker examines the message content and only delivers it if it matches specific criteria defined by the subscriber (e.g., &#8220;only messages where <code>price &gt; 100</code>&#8220;).</p></li></ul><div><hr></div><h3>In-Depth Examples &amp; Use Cases</h3><h4>1. Event Notification (Decoupling Services)</h4><p>In a traditional system, if a user makes a purchase, the OrderService might have to manually call the EmailService, ShippingService, and InventoryService. If one is down, the whole process might fail.</p><ul><li><p><strong>Pub/Sub Approach:</strong> The OrderService simply publishes an &#8220;Order Created&#8221; message to a topic.</p></li><li><p><strong>Benefit:</strong> The OrderService can &#8220;fire and forget&#8221;. It doesn&#8217;t care if the EmailService is currently offline; the broker will ensure the message is delivered when the service is back online.</p></li><li><p><strong>Real-World Example:</strong><em> <strong>Split.io</strong></em> uses this to send feature flag updates to millions of apps. If an app is offline, it gets the update as soon as it reconnects.</p></li></ul><h4>2. Distributed Caching (State Synchronization)</h4><p>When you have multiple server instances, you need them to have the same data in their local memory (cache).</p><ul><li><p><strong>Pub/Sub Approach:</strong> When data changes in the database, a message is published to a &#8220;Cache Update&#8221; topic. All server instances subscribe to this and update their local cache immediately.</p></li><li><p><strong>Real-World Example:</strong> <em><strong>Seats.io</strong></em> uses this for live seat bookings. When someone buys a ticket, the floor plan is updated across all global caches instantly so two people don&#8217;t buy the same seat.</p></li></ul><h4>3. Distributed Logging</h4><p>Managing logs in a distributed system with 100+ servers is difficult if you have to log into each one.</p><ul><li><p><strong>Pub/Sub Approach:</strong> Every server publishes its logs to a central &#8220;Logs&#8221; topic.</p></li><li><p><strong>Parallel Processing:</strong> One subscriber can send those logs to <strong>Elasticsearch</strong> for searching, while another subscriber monitors them for errors to trigger an <strong>SMS alert</strong>.</p></li></ul><h4>4. Handling &#8220;Thundering Herds&#8221; (Burstability)</h4><p>In education or live events, thousands of users might join at the exact same second.</p><ul><li><p><strong>Pub/Sub Approach:</strong> A dedicated broker (like Redis or Kafka) is designed to handle massive &#8220;fanout&#8221; bursts&#8212;sending one message to 100,000 people simultaneously.</p></li><li><p><strong>Real-World Example:</strong> <em><strong>Wooclap</strong></em> uses this so students in a large lecture hall can all see a professor&#8217;s question on their phones at the exact same time, even on spotty Wi-Fi.</p></li></ul>]]></content:encoded></item><item><title><![CDATA[ Message Queue vs. Pub-Sub: The Only Guide You Need]]></title><description><![CDATA[The Asynchronous Dilemma]]></description><link>https://hrithikchandok.substack.com/p/message-queue-vs-pub-sub-the-only-guide-you-need-553eb0fa3ccf</link><guid isPermaLink="false">https://hrithikchandok.substack.com/p/message-queue-vs-pub-sub-the-only-guide-you-need-553eb0fa3ccf</guid><dc:creator><![CDATA[HrithikChandok]]></dc:creator><pubDate>Sun, 10 May 2026 09:01:05 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/b66e4789-4894-4fe1-8aeb-66914b8c22ee_1024x600.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3>The Asynchronous Dilemma</h3><p>In modern microservices, &#8220;Fire and Forget&#8221; is the gold standard. We want Service A to talk to Service B without waiting for a response&#8202;&#8212;&#8202;ensuring that if one system fails, the whole application doesn&#8217;t go down with&nbsp;it.</p><p>But when you open the AWS or Azure console, you&#8217;re faced with a choice: <strong>Message Queue (MQ) or Pub-Sub?</strong> Getting this wrong can lead to data loss or a system that&#8217;s impossible to&nbsp;scale.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BkPs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12249cd1-71cf-4d31-9b82-247e15760c14_1024x600.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BkPs!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12249cd1-71cf-4d31-9b82-247e15760c14_1024x600.png 424w, https://substackcdn.com/image/fetch/$s_!BkPs!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12249cd1-71cf-4d31-9b82-247e15760c14_1024x600.png 848w, https://substackcdn.com/image/fetch/$s_!BkPs!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12249cd1-71cf-4d31-9b82-247e15760c14_1024x600.png 1272w, https://substackcdn.com/image/fetch/$s_!BkPs!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12249cd1-71cf-4d31-9b82-247e15760c14_1024x600.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BkPs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12249cd1-71cf-4d31-9b82-247e15760c14_1024x600.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/12249cd1-71cf-4d31-9b82-247e15760c14_1024x600.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!BkPs!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12249cd1-71cf-4d31-9b82-247e15760c14_1024x600.png 424w, https://substackcdn.com/image/fetch/$s_!BkPs!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12249cd1-71cf-4d31-9b82-247e15760c14_1024x600.png 848w, https://substackcdn.com/image/fetch/$s_!BkPs!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12249cd1-71cf-4d31-9b82-247e15760c14_1024x600.png 1272w, https://substackcdn.com/image/fetch/$s_!BkPs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12249cd1-71cf-4d31-9b82-247e15760c14_1024x600.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><h4><strong>What is a message&nbsp;queue?</strong></h4><p>A message queue basically contains a publisher, and in between there will be a queue containing messages, and there will be multiple consumers subscribing to that queue. Examples: <strong>AWS SQS,&nbsp;RabbitMQ</strong></p><p>Let's look at the&nbsp;diagram.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!E_Gw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5863c9e7-c4ad-4d0b-97e4-feca85213fd8_1024x351.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!E_Gw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5863c9e7-c4ad-4d0b-97e4-feca85213fd8_1024x351.png 424w, https://substackcdn.com/image/fetch/$s_!E_Gw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5863c9e7-c4ad-4d0b-97e4-feca85213fd8_1024x351.png 848w, https://substackcdn.com/image/fetch/$s_!E_Gw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5863c9e7-c4ad-4d0b-97e4-feca85213fd8_1024x351.png 1272w, https://substackcdn.com/image/fetch/$s_!E_Gw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5863c9e7-c4ad-4d0b-97e4-feca85213fd8_1024x351.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!E_Gw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5863c9e7-c4ad-4d0b-97e4-feca85213fd8_1024x351.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5863c9e7-c4ad-4d0b-97e4-feca85213fd8_1024x351.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!E_Gw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5863c9e7-c4ad-4d0b-97e4-feca85213fd8_1024x351.png 424w, https://substackcdn.com/image/fetch/$s_!E_Gw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5863c9e7-c4ad-4d0b-97e4-feca85213fd8_1024x351.png 848w, https://substackcdn.com/image/fetch/$s_!E_Gw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5863c9e7-c4ad-4d0b-97e4-feca85213fd8_1024x351.png 1272w, https://substackcdn.com/image/fetch/$s_!E_Gw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5863c9e7-c4ad-4d0b-97e4-feca85213fd8_1024x351.png 1456w" sizes="100vw"></picture><div></div></div></a></figure></div><p>We can see Publisher is going to publish that m n+1 message to the queue, and there are consuming servers A and&nbsp;B.</p><p>Let's see how this system behaves over&nbsp;time.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!q36p!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1c2d62d-b698-4746-a093-0903077e9bf2_1024x351.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!q36p!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1c2d62d-b698-4746-a093-0903077e9bf2_1024x351.png 424w, https://substackcdn.com/image/fetch/$s_!q36p!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1c2d62d-b698-4746-a093-0903077e9bf2_1024x351.png 848w, https://substackcdn.com/image/fetch/$s_!q36p!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1c2d62d-b698-4746-a093-0903077e9bf2_1024x351.png 1272w, https://substackcdn.com/image/fetch/$s_!q36p!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1c2d62d-b698-4746-a093-0903077e9bf2_1024x351.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!q36p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1c2d62d-b698-4746-a093-0903077e9bf2_1024x351.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f1c2d62d-b698-4746-a093-0903077e9bf2_1024x351.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!q36p!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1c2d62d-b698-4746-a093-0903077e9bf2_1024x351.png 424w, https://substackcdn.com/image/fetch/$s_!q36p!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1c2d62d-b698-4746-a093-0903077e9bf2_1024x351.png 848w, https://substackcdn.com/image/fetch/$s_!q36p!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1c2d62d-b698-4746-a093-0903077e9bf2_1024x351.png 1272w, https://substackcdn.com/image/fetch/$s_!q36p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1c2d62d-b698-4746-a093-0903077e9bf2_1024x351.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>As you can see, the m1 message has been consumed by Consumer A and its no more available in the&nbsp;queue.</p><p>When to use a message queue in the system?<br>When a system use case is like we want to delegate some work to the service, then MQ (Message Queue) would be preferred. When we want a single execution of the message or task. This type of system is known as the point-to-point<strong> messaging model.</strong></p><h4>What is the Pub/Sub messaging model?</h4><p>The only difference from a message queue is that here we want to deliver our task/message published by the publisher to reach at least once to each of the consumers. Examples: <strong>AWS SNS</strong>, <strong>Apache&nbsp;Kafka</strong></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CFFD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf22b350-38e0-4f10-9bd2-a5ed24edfa1e_1024x277.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CFFD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf22b350-38e0-4f10-9bd2-a5ed24edfa1e_1024x277.png 424w, https://substackcdn.com/image/fetch/$s_!CFFD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf22b350-38e0-4f10-9bd2-a5ed24edfa1e_1024x277.png 848w, https://substackcdn.com/image/fetch/$s_!CFFD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf22b350-38e0-4f10-9bd2-a5ed24edfa1e_1024x277.png 1272w, https://substackcdn.com/image/fetch/$s_!CFFD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf22b350-38e0-4f10-9bd2-a5ed24edfa1e_1024x277.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CFFD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf22b350-38e0-4f10-9bd2-a5ed24edfa1e_1024x277.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bf22b350-38e0-4f10-9bd2-a5ed24edfa1e_1024x277.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!CFFD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf22b350-38e0-4f10-9bd2-a5ed24edfa1e_1024x277.png 424w, https://substackcdn.com/image/fetch/$s_!CFFD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf22b350-38e0-4f10-9bd2-a5ed24edfa1e_1024x277.png 848w, https://substackcdn.com/image/fetch/$s_!CFFD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf22b350-38e0-4f10-9bd2-a5ed24edfa1e_1024x277.png 1272w, https://substackcdn.com/image/fetch/$s_!CFFD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf22b350-38e0-4f10-9bd2-a5ed24edfa1e_1024x277.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Let's see the flow of data over&nbsp;time.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eCyG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7695adfa-3a19-401c-8bcd-691d638684e6_1024x258.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eCyG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7695adfa-3a19-401c-8bcd-691d638684e6_1024x258.png 424w, https://substackcdn.com/image/fetch/$s_!eCyG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7695adfa-3a19-401c-8bcd-691d638684e6_1024x258.png 848w, https://substackcdn.com/image/fetch/$s_!eCyG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7695adfa-3a19-401c-8bcd-691d638684e6_1024x258.png 1272w, https://substackcdn.com/image/fetch/$s_!eCyG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7695adfa-3a19-401c-8bcd-691d638684e6_1024x258.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eCyG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7695adfa-3a19-401c-8bcd-691d638684e6_1024x258.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7695adfa-3a19-401c-8bcd-691d638684e6_1024x258.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!eCyG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7695adfa-3a19-401c-8bcd-691d638684e6_1024x258.png 424w, https://substackcdn.com/image/fetch/$s_!eCyG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7695adfa-3a19-401c-8bcd-691d638684e6_1024x258.png 848w, https://substackcdn.com/image/fetch/$s_!eCyG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7695adfa-3a19-401c-8bcd-691d638684e6_1024x258.png 1272w, https://substackcdn.com/image/fetch/$s_!eCyG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7695adfa-3a19-401c-8bcd-691d638684e6_1024x258.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>On the left we have a publisher. Publishing a message to the topic. This topic will have multiple subscribers. This topic will broadcast this message to its subscriber. It will make sure each subscriber will get a copy of that message published into the&nbsp;topic.</p><h3>Which one to use and&nbsp;when?</h3><p>Another benefit of using either pub-sub or message queues is that the communication is more durable than traditional synchronous modes of communication. For example, if app A communicates to app B via an asynchronous HTTP call, then if either of the applications goes down, the data is lost and the request must be&nbsp;retried.</p><p>Using message queues, if a consumer application instance goes down, then another consumer will be able to handle the message instead. Using pub-sub, if a subscriber is down, then once it has recovered, the messages it has missed will be available for consumption in its subscribing queue.</p><p>Finally, context is key. Choosing whether to use pub-sub or message queue architecture comes down to defining exactly how you want the consuming service to behave. The most important factor to keep in mind is&nbsp;asking,</p><p>"Does<strong> it matter if every consumer gets every message?</strong>&#8221;<br>If <strong>yes:</strong> Use Pub-Sub.<br>If <strong>No</strong>: Use a Message&nbsp;Queue.</p>]]></content:encoded></item><item><title><![CDATA[The Hard Truth About Scaling WebSockets in Production]]></title><description><![CDATA[I have been working with WebSockets for quite some time now, and let me tell you a secret: implementing basic WebSockets isn&#8217;t that hard.]]></description><link>https://hrithikchandok.substack.com/p/the-hard-truth-about-scaling-websockets-in-production-e924719cc76a</link><guid isPermaLink="false">https://hrithikchandok.substack.com/p/the-hard-truth-about-scaling-websockets-in-production-e924719cc76a</guid><dc:creator><![CDATA[HrithikChandok]]></dc:creator><pubDate>Sat, 09 May 2026 10:24:07 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/119a51d6-a041-41e5-8d42-ca38c331f862_892x838.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!k1kW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46aadb87-6891-49aa-a2b0-c203190a4dbb_892x838.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!k1kW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46aadb87-6891-49aa-a2b0-c203190a4dbb_892x838.png 424w, https://substackcdn.com/image/fetch/$s_!k1kW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46aadb87-6891-49aa-a2b0-c203190a4dbb_892x838.png 848w, https://substackcdn.com/image/fetch/$s_!k1kW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46aadb87-6891-49aa-a2b0-c203190a4dbb_892x838.png 1272w, https://substackcdn.com/image/fetch/$s_!k1kW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46aadb87-6891-49aa-a2b0-c203190a4dbb_892x838.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!k1kW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46aadb87-6891-49aa-a2b0-c203190a4dbb_892x838.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/46aadb87-6891-49aa-a2b0-c203190a4dbb_892x838.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;WebSocket Protocol. ws uses port 80 and wss uses port 443&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="WebSocket Protocol. ws uses port 80 and wss uses port 443" title="WebSocket Protocol. ws uses port 80 and wss uses port 443" srcset="https://substackcdn.com/image/fetch/$s_!k1kW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46aadb87-6891-49aa-a2b0-c203190a4dbb_892x838.png 424w, https://substackcdn.com/image/fetch/$s_!k1kW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46aadb87-6891-49aa-a2b0-c203190a4dbb_892x838.png 848w, https://substackcdn.com/image/fetch/$s_!k1kW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46aadb87-6891-49aa-a2b0-c203190a4dbb_892x838.png 1272w, https://substackcdn.com/image/fetch/$s_!k1kW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46aadb87-6891-49aa-a2b0-c203190a4dbb_892x838.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a><figcaption class="image-caption">Websocket Protocol&nbsp;, ws uses port 80 and wss uses 443&nbsp;port.</figcaption></figure></div><h3>I have been working with WebSockets for quite some time now, and let me tell you a secret: implementing basic WebSockets isn&#8217;t that&nbsp;hard.</h3><p>But orchestrating a secure, bidirectional communication framework&#8202;&#8212;&#8202;especially when scaling an enterprise tracking system to handle around 40,000 distributed agents&#8202;&#8212;&#8202;is an entirely different beast. Scaling them, handling sudden disconnections, and managing state across multiple instances? That is where the real engineering happens.</p><p>WebSocket servers are inherently resource-hungry. Before we dive into the architecture of scaling, let&#8217;s get on the same page with the vocabulary.</p><h3>10 WebSocket Terms You Need to&nbsp;Know</h3><p>If you are building real-time systems, these concepts should be second&nbsp;nature:</p><ul><li><p><strong>Heartbeat:</strong> Pings sent back and forth to verify the connection is still&nbsp;alive.</p></li><li><p><strong>Buffer / Undelivered Messages:</strong> Storing messages temporarily when a client briefly drops&nbsp;offline.</p></li><li><p><strong>Message Routing:</strong> Directing the right payload to the right active connection.</p></li><li><p><strong>Broadcast:</strong> Sending a single message to all connected clients simultaneously.</p></li><li><p><strong>Handling Backpressure:</strong> Managing the flow of data when the server is sending messages faster than the client can process&nbsp;them.</p></li><li><p><strong>Automatic Reconnection:</strong> The client&#8217;s ability to seamlessly re-establish a dropped connection.</p></li><li><p><strong>Message Acknowledgements (ACKs):</strong> Confirming that a message was actually received by the&nbsp;client.</p></li><li><p><strong>Encryption:</strong> Securing the data payload (WSS /&nbsp;TLS).</p></li><li><p><strong>Multiplexing:</strong> Sending multiple streams of data over a single underlying TCP connection.</p></li><li><p><strong>Fallback:</strong> Using techniques like HTTP Long Polling if a client&#8217;s browser or corporate firewall blocks WebSockets.</p></li></ul><h3>The Reality of Scaling WebSockets</h3><p>When your traffic grows, you have two&nbsp;choices.</p><p><strong>1. Vertical Scaling (The Brute Force Approach)</strong> This means throwing more CPU and RAM at a single server. Depending on your server resources, you can support a massive amount of connections on one&nbsp;machine.</p><ul><li><p><strong>The Catch:</strong> Single point of failure. If you need to deploy an update, or if the server crashes, every single user gets disconnected at once. That&#8217;s a terrible user experience.</p></li></ul><p><strong>2. Horizontal Scaling (The Engineering Approach)</strong> This means spinning up multiple server instances.</p><ul><li><p><strong>The Problem:</strong> If User A is connected to Server 1, and User B is connected to Server 2, they cannot talk to each other. Server 1 has no idea User B&nbsp;exists.</p></li></ul><p>The Solution: Redis&nbsp;Pub/Sub</p><h4>Challenges in Horizontal Scaling</h4><p>While Redis solves the routing problem, horizontal scaling introduces new headaches:</p><ul><li><p>Data Synchronization</p></li><li><p>Connection State Synchronization</p></li><li><p>Making Redis Redundant</p></li><li><p>Load Shedding</p></li><li><p>Restoring Connections</p></li></ul><h3>Handling the &#8220;Thundering Herd&#8221; (Reconnection Logic)</h3><p>Connections drop all the time. It&#8217;s normal. It happens due to network switching (Wi-Fi to Cellular), proxy timeouts (ALB/API Gateways), or just laptops going to sleep and suspending the TCP connection.</p><p>I wrote a specific reconnection logic for my agents to handle unexpected drops. If a server goes down, every single client will instantly try to reconnect at the exact same millisecond. This is called the <strong>Thundering Herd problem</strong>, and it will instantly crash your server&nbsp;again.</p><p>To protect the server, you need <strong>Exponential Backoff with Jitter</strong>. Jitter adds randomness, spreading the retry wave out over time. Here is the exact logic I&nbsp;use:</p><pre><code>function createBackoff({ base = 500, max = 30000, jitter = true } = {}) {
  let attempt = 0;
return {
    next() {
      // Calculate the exponential delay, capped at the max value
      const exponential = Math.min(base * Math.pow(2, attempt), max);
      
      // Apply jitter (randomness) to prevent synchronized retries
      const delay = jitter
        ? exponential * (0.5 + Math.random() * 0.5)
        : exponential;
        
      attempt++;
      return Math.floor(delay);
    },
    reset() {
      attempt = 0;
    },
  };
}</code></pre><h3>A Final Note: What I Learned Going to&nbsp;Prod</h3><p>There is a massive misconception in the community about WebSocket capacity. People always focus on <em>how many</em> connections a single instance can&nbsp;hold.</p><p>When I took my architecture to production, here was the biggest takeaway:</p><p><strong>&#8220;A 10k connection load writing 100 messages per second is a far heavier beast than 50k idle connections.&#8221;</strong></p><p>Throughput and message frequency will choke your CPU and memory long before raw connection counts will. Plan your architecture around your message velocity, not just your concurrent users.</p><p><em>References &amp; Further&nbsp;Reading:</em></p><ul><li><p><a href="https://websocket.org/guides/websocket-protocol/">The WebSocket Protocol Guide (WebSocket.org)</a></p></li><li><p><a href="https://ably.com/blog/scaling-pub-sub-with-websockets-and-redis">Scaling Pub/Sub with WebSockets and Redis&nbsp;(Ably)</a></p></li><li><p><a href="https://ably.com/topic/when-and-how-to-load-balance-websockets-at-scale">When and How to Load Balance WebSockets at Scale&nbsp;(Ably)</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[AWS Developer Interview Experience ]]></title><description><![CDATA[My Interview Experience at Brillio Technology]]></description><link>https://hrithikchandok.substack.com/p/aws-developer-interview-experience-f05e847fd4de</link><guid isPermaLink="false">https://hrithikchandok.substack.com/p/aws-developer-interview-experience-f05e847fd4de</guid><dc:creator><![CDATA[HrithikChandok]]></dc:creator><pubDate>Thu, 07 May 2026 19:39:31 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!HwKs!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7662c0b0-f1e9-400d-a1b5-85bb39764171_1280x1280.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3><strong>My Interview Experience at Brillio Technology</strong></h3><p>This was my interview experience for an AWS Developer role at Brillio. Overall, it was a great learning experience&#8202;&#8212;&#8202;I got a clear understanding of the expectations companies have from AWS Developers and the kind of skills they look for.&nbsp;&#128640;</p><p>Some of the topics discussed:</p><p>&#8226; What is AWS Lambda and how does serverless scaling work?<br>&#8226; Amazon SQS internals&#8202;&#8212;&#8202;visibility timeout, retries, and DLQ<br>&#8226; SQS vs Kinesis&#8202;&#8212;&#8202;queueing vs real-time streaming<br>&#8226; Why exceptions are raised in Lambda when consuming SQS messages<br>&#8226; Public Subnet vs Private Subnet<br>&#8226; Internet Gateway vs NAT Gateway<br>&#8226; Components of VPC<br>&#8226; NACL vs Security Groups<br>&#8226; What are Pre-Signed URLs in S3?<br>&#8226; Different S3 Storage Classes and real-world use cases<br>&#8226; How to solve HTTP 413 (Entity Too Large) errors in AWS architectures<br>&#8226; Node.js AWS SDK code to retrieve images from an S3&nbsp;bucket</p><p>We also discussed a production-level architecture:</p><p>Agent Upload &#8594; S3 Bucket &#8594; Metadata stored in OpenSearch &#8594; Backend fetches S3 Key &#8594; Generates Pre-Signed URL &#8594; Frontend displays secure&nbsp;images</p><p>Key Learning&nbsp;&#128161;</p><p>S3 is optimized for object storage, not metadata searching. That&#8217;s why storing searchable metadata in OpenSearch while keeping images private in S3 is a scalable and secure approach.</p><p>One thing I realized during these discussions is that hands-on experience with deployments and cloud architecture makes a huge difference. It helps in understanding how systems handle scale, retries, failures, security, and traffic patterns in real-world production environments.</p><p>Tech Stack Discussed:<br>AWS Lambda | SQS | S3 | OpenSearch | VPC | Node.js | Serverless Architecture</p><p>These discussions were a great reminder that strong backend engineering is not just about coding, but also about designing scalable, secure, and fault-tolerant systems.</p><p>Thank you&#8202;&#8212;&#8202;see you at deployment &#128640;</p><p>#AWS #Serverless #Lambda #SQS #S3 #OpenSearch #NodeJS #BackendDevelopment #SoftwareEngineering #CloudComputing #SystemDesign #Microservices #AWSDeveloper #DistributedSystems</p>]]></content:encoded></item><item><title><![CDATA[Recursion Patterns in DSA: Pick vs Not Pick Explained with LeetCode Examples]]></title><description><![CDATA[Learn the Pick and Not Pick recursion pattern used in DSA and coding interviews.]]></description><link>https://hrithikchandok.substack.com/p/recursion-patterns-in-dsa-pick-vs-not-pick-explained-with-leetcode-examples-16a84cc6336b</link><guid isPermaLink="false">https://hrithikchandok.substack.com/p/recursion-patterns-in-dsa-pick-vs-not-pick-explained-with-leetcode-examples-16a84cc6336b</guid><dc:creator><![CDATA[HrithikChandok]]></dc:creator><pubDate>Mon, 04 May 2026 20:26:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!HwKs!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7662c0b0-f1e9-400d-a1b5-85bb39764171_1280x1280.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Learn the Pick and Not Pick recursion pattern used in DSA and coding interviews. Understand backtracking with clear examples from LeetCode problems like Combination Sum and&nbsp;Subsets.</p><h3>&#128309; Pattern 1: &#8220;Pick / Not Pick&#8221; (FULL&nbsp;TREE)</h3><h3>&#9989; Code (Combination Sum style&#8202;&#8212;&#8202;allows full&nbsp;tree)</h3><pre><code>class Solution {
    List&lt;List&lt;Integer&gt;&gt; ans = new ArrayList&lt;&gt;();
void ok(int index, int[] nums, int target, List&lt;Integer&gt; temp) {
        if (target == 0) {
            ans.add(new ArrayList&lt;&gt;(temp));
            return;
        }
        if (index == nums.length) return;
        // &#9989; TAKE
        if (nums[index] &lt;= target) {
            temp.add(nums[index]);
            ok(index, nums, target - nums[index], temp); // reuse allowed
            temp.remove(temp.size() - 1);
        }
        // &#10060; NOT TAKE
        ok(index + 1, nums, target, temp);
    }
}</code></pre><p>&#128073; <strong>Used&nbsp;when:</strong></p><ul><li><p>You don&#8217;t care about duplicates</p></li><li><p>OR problem is simple include/exclude</p></li><li><p>OR reuse of elements is allowed (like in <strong>Combination Sum</strong>)</p></li></ul><h3>&#127795; Tree&nbsp;Shape</h3><pre><code>At every index &#8594; 2 choices

        index
        /     \
     take     skip</code></pre><p>&#128073; Size &#8776; <strong>2^n (full binary tree)</strong><br>&#128073; Explores all subsets / possibilities<br>&#128073; Can generate duplicates &#8594; &#10060; inefficient for duplicate inputs</p><h3>&#128308; Pattern 2: &#8220;For Loop + Pruning&#8221; (REDUCED&nbsp;TREE)</h3><p>&#128073; <strong>Used&nbsp;when:</strong></p><ul><li><p>You want to avoid duplicates</p></li><li><p>You want controlled branching</p></li><li><p>Input contains duplicates</p></li><li><p>Each element can be used <strong>only once</strong> (like in <strong>Combination Sum&nbsp;II</strong>)</p></li></ul><h3>&#9989; Code (Combination Sum 2 style&#8202;&#8212;&#8202;optimized)</h3><pre><code>class Solution {
    List&lt;List&lt;Integer&gt;&gt; ans = new ArrayList&lt;&gt;();
void ok(int index, int[] nums, int target, List&lt;Integer&gt; temp) {
if (target == 0) {
            ans.add(new ArrayList&lt;&gt;(temp));
            return;
        }
        for (int i = index; i &lt; nums.length; i++) {
            // &#128680; skip duplicates
            if (i &gt; index &amp;&amp; nums[i] == nums[i - 1]) continue;
            if (nums[i] &gt; target) break;
            temp.add(nums[i]);
            ok(i + 1, nums, target - nums[i], temp); // move forward
            temp.remove(temp.size() - 1);
        }
    }
}</code></pre><h3>&#127795; Tree&nbsp;Shape</h3><pre><code>At each level &#8594; choose ONE among many

        level
     /    |    \
   pick  pick  pick</code></pre><p>&#128073; Size <strong>much smaller than 2^n</strong><br>&#128073; No duplicate branches &#9989;<br>&#128073; More optimized for interview constraints</p><h3>&#128293; Look at Combination Sum vs Combination Sum&nbsp;II</h3><p>Take a simpler&nbsp;case:</p><pre><code>nums = [1, 1, 2]
target = 3</code></pre><p>Sorted:</p><pre><code>[1a, 1b, 2]   (same value, different indices)</code></pre><h3>&#10060; Your Approach (Pick / Not&nbsp;Pick)</h3><p>At every index &#8594; 2&nbsp;choices</p><h3>&#127795; Recursion Tree (your&nbsp;code)</h3><pre><code>                        []
               /                      \
          take 1a                  skip 1a
           [1]                       []
        /       \               /          \
   take 1b    skip 1b     take 1b       skip 1b
    [1,1]        [1]        [1]            []
    /   \       /   \      /   \          /   \
 take2 skip2  take2 skip2 take2 skip2  take2 skip2
 [1,1,2] ...  [1,2] ...   [1,2] ...    [2] ...</code></pre><h3>&#127919; Look at duplicates</h3><p>You get:</p><pre><code>[1,2]  &#8592; from (take 1a, skip 1b, take 2)
[1,2]  &#8592; from (skip 1a, take 1b, take 2)</code></pre><p>&#128073; Same combination, <strong>different paths</strong></p><h3>&#128165; What&#8217;s happening?</h3><ul><li><p>Tree size &#8776;&nbsp;<strong>2^n</strong></p></li><li><p>Duplicate values &#8594; <strong>duplicate branches</strong></p></li><li><p>You generate:</p></li></ul><pre><code>[1,2] multiple times</code></pre><p>Then:</p><pre><code>HashSet removes duplicates &#10060; (too late, too costly)</code></pre><h3>&#9989; Optimized Approach (For-loop + Skip duplicates)</h3><h3>&#128273; Key&nbsp;line:</h3><pre><code>if (i &gt; index &amp;&amp; nums[i] == nums[i - 1]) continue;</code></pre><h3>&#127795; Recursion Tree (optimized)</h3><pre><code>                []
          /           \
       pick 1a        pick 2
        [1]           [2]
      /      \
  pick 1b    pick 2
   [1,1]      [1,2]</code></pre><h3>&#128680; Notice:</h3><ul><li><p>We <strong>DO NOT start a branch with 1b at same&nbsp;level</strong></p></li><li><p>So this path is&nbsp;removed:</p></li></ul><pre><code>(skip 1a &#8594; pick 1b) &#10060;</code></pre><p>&#128073; This is the <strong>exact pruning step</strong> that reduces tree&nbsp;size</p><h3>&#129504; Final Insight (Interview Gold)</h3><blockquote><p><em>Pick/Not Pick builds a full binary tree (2^n), while the for-loop pattern prunes duplicate branches at the same level, reducing unnecessary recursion and improving performance.</em></p></blockquote><blockquote><p>&#8220;See you at the deployment&#8217;&#8217; <br>Thank you&nbsp;!</p></blockquote>]]></content:encoded></item><item><title><![CDATA[Recursion Patterns in DSA: Pick vs Not Pick Explained with LeetCode Examples]]></title><description><![CDATA[Learn the Pick and Not Pick recursion pattern used in DSA and coding interviews. Understand backtracking with clear examples from LeetCode problems like Combination Sum and Subsets.]]></description><link>https://hrithikchandok.substack.com/p/recursion-pattern-pick-not-pick-backtracking-dsa</link><guid isPermaLink="false">https://hrithikchandok.substack.com/p/recursion-pattern-pick-not-pick-backtracking-dsa</guid><dc:creator><![CDATA[HrithikChandok]]></dc:creator><pubDate>Mon, 04 May 2026 20:11:42 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!HwKs!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7662c0b0-f1e9-400d-a1b5-85bb39764171_1280x1280.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>&#128309; Pattern 1: &#8220;Pick / Not Pick&#8221; (FULL TREE)</h1><h2>&#9989; Code (Combination Sum style &#8211; allows full tree)</h2><pre><code><code>class Solution {
    List&lt;List&lt;Integer&gt;&gt; ans = new ArrayList&lt;&gt;();

    void ok(int index, int[] nums, int target, List&lt;Integer&gt; temp) {

        if (target == 0) {
            ans.add(new ArrayList&lt;&gt;(temp));
            return;
        }

        if (index == nums.length) return;

        // &#9989; TAKE
        if (nums[index] &lt;= target) {
            temp.add(nums[index]);
            ok(index, nums, target - nums[index], temp); // reuse allowed
            temp.remove(temp.size() - 1);
        }

        // &#10060; NOT TAKE
        ok(index + 1, nums, target, temp);
    }
}</code></code></pre><div><hr></div><p>&#128073; <strong>Used when:</strong></p><ul><li><p>You don&#8217;t care about duplicates<br></p></li><li><p>OR problem is simple include/exclude<br></p></li><li><p>OR reuse of elements is allowed (like in <strong>Combination Sum</strong>)<br></p></li></ul><div><hr></div><h2>&#127795; Tree Shape</h2><pre><code><code>At every index &#8594; 2 choices

         index
        /     \
     take     skip</code></code></pre><p>&#128073; Size &#8776; <strong>2^n (full binary tree)</strong><br><br>&#128073; Explores all subsets / possibilities<br><br>&#128073; Can generate duplicates &#8594; &#10060; inefficient for duplicate inputs</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://hrithikchandok.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">Thanks for reading! Subscribe for free to receive new posts and support my work.</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><div><hr></div><h1>&#128308; Pattern 2: &#8220;For Loop + Pruning&#8221; (REDUCED TREE)</h1><p>&#128073; <strong>Used when:</strong></p><ul><li><p>You want to avoid duplicates<br></p></li><li><p>You want controlled branching<br></p></li><li><p>Input contains duplicates<br></p></li><li><p>Each element can be used <strong>only once</strong> (like in <strong>Combination Sum II</strong>)<br></p></li></ul><div><hr></div><h2>&#9989; Code (Combination Sum 2 style &#8211; optimized)</h2><pre><code><code>class Solution {
    List&lt;List&lt;Integer&gt;&gt; ans = new ArrayList&lt;&gt;();

    void ok(int index, int[] nums, int target, List&lt;Integer&gt; temp) {

        if (target == 0) {
            ans.add(new ArrayList&lt;&gt;(temp));
            return;
        }

        for (int i = index; i &lt; nums.length; i++) {

            // &#128680; skip duplicates
            if (i &gt; index &amp;&amp; nums[i] == nums[i - 1]) continue;

            if (nums[i] &gt; target) break;

            temp.add(nums[i]);
            ok(i + 1, nums, target - nums[i], temp); // move forward
            temp.remove(temp.size() - 1);
        }
    }
}</code></code></pre><div><hr></div><h2>&#127795; Tree Shape</h2><pre><code><code>At each level &#8594; choose ONE among many

         level
     /    |    \
   pick  pick  pick</code></code></pre><p>&#128073; Size <strong>much smaller than 2^n</strong><br><br>&#128073; No duplicate branches &#9989;<br><br>&#128073; More optimized for interview constraints</p><div><hr></div><h1>&#128293; Look at Combination Sum vs Combination Sum II</h1><p>Take a simpler case:</p><pre><code><code>nums = [1, 1, 2]
target = 3</code></code></pre><p>Sorted:</p><pre><code><code>[1a, 1b, 2]   (same value, different indices)</code></code></pre><div><hr></div><h1>&#10060; Your Approach (Pick / Not Pick)</h1><p>At every index &#8594; 2 choices</p><h2>&#127795; Recursion Tree (your code)</h2><pre><code><code>                         []
               /                      \
          take 1a                  skip 1a
           [1]                       []
        /       \               /          \
   take 1b    skip 1b     take 1b       skip 1b
    [1,1]        [1]        [1]            []
    /   \       /   \      /   \          /   \
 take2 skip2  take2 skip2 take2 skip2  take2 skip2
 [1,1,2] ...  [1,2] ...   [1,2] ...    [2] ...</code></code></pre><div><hr></div><h2>&#127919; Look at duplicates</h2><p>You get:</p><pre><code><code>[1,2]  &#8592; from (take 1a, skip 1b, take 2)
[1,2]  &#8592; from (skip 1a, take 1b, take 2)</code></code></pre><p>&#128073; Same combination, <strong>different paths</strong></p><div><hr></div><h2>&#128165; What&#8217;s happening?</h2><ul><li><p>Tree size &#8776; <strong>2^n</strong><br></p></li><li><p>Duplicate values &#8594; <strong>duplicate branches</strong><br></p></li><li><p>You generate:<br></p></li></ul><pre><code><code>[1,2] multiple times</code></code></pre><p>Then:</p><pre><code><code>HashSet removes duplicates &#10060; (too late, too costly)</code></code></pre><div><hr></div><h1>&#9989; Optimized Approach (For-loop + Skip duplicates)</h1><h3>&#128273; Key line:</h3><pre><code><code>if (i &gt; index &amp;&amp; nums[i] == nums[i - 1]) continue;</code></code></pre><div><hr></div><h2>&#127795; Recursion Tree (optimized)</h2><pre><code><code>                    []
          /           \
       pick 1a        pick 2
        [1]           [2]
      /      \
  pick 1b    pick 2
   [1,1]      [1,2]</code></code></pre><div><hr></div><h2>&#128680; Notice:</h2><ul><li><p>We <strong>DO NOT start a branch with 1b at same level</strong><br></p></li><li><p>So this path is removed:<br></p></li></ul><pre><code><code>(skip 1a &#8594; pick 1b) &#10060;</code></code></pre><p>&#128073; This is the <strong>exact pruning step</strong> that reduces tree size</p><div><hr></div><h1>&#129504; Final Insight (Interview Gold)</h1><blockquote><p>Pick/Not Pick builds a full binary tree (2^n), while the for-loop pattern prunes duplicate branches at the same level, reducing unnecessary recursion and improving performance.</p></blockquote><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://hrithikchandok.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">Thanks for reading! Subscribe for free to receive new posts and support my work.</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>]]></content:encoded></item><item><title><![CDATA[Set Matrix Zeroes]]></title><description><![CDATA[Given an m x n matrix, if any cell contains 0, make its entire row and column 0.]]></description><link>https://hrithikchandok.substack.com/p/set-matrix-zeroes-47f330a7f267</link><guid isPermaLink="false">https://hrithikchandok.substack.com/p/set-matrix-zeroes-47f330a7f267</guid><dc:creator><![CDATA[HrithikChandok]]></dc:creator><pubDate>Fri, 01 May 2026 17:38:57 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/1bd33c54-675b-477a-802c-5f3fbc2a455f_812x314.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Given an m x n matrix, if any cell contains 0, make its entire row and column&nbsp;0.</p><p>The matrix must be modified in-place.</p><p>Follow up: Could you solve it using O(1)&nbsp;space?</p><p><strong>Example 1:</strong></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mSiV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f51ee86-def8-4d0f-b5f8-9c44ed587432_812x314.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mSiV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f51ee86-def8-4d0f-b5f8-9c44ed587432_812x314.png 424w, https://substackcdn.com/image/fetch/$s_!mSiV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f51ee86-def8-4d0f-b5f8-9c44ed587432_812x314.png 848w, https://substackcdn.com/image/fetch/$s_!mSiV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f51ee86-def8-4d0f-b5f8-9c44ed587432_812x314.png 1272w, https://substackcdn.com/image/fetch/$s_!mSiV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f51ee86-def8-4d0f-b5f8-9c44ed587432_812x314.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mSiV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f51ee86-def8-4d0f-b5f8-9c44ed587432_812x314.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9f51ee86-def8-4d0f-b5f8-9c44ed587432_812x314.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!mSiV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f51ee86-def8-4d0f-b5f8-9c44ed587432_812x314.png 424w, https://substackcdn.com/image/fetch/$s_!mSiV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f51ee86-def8-4d0f-b5f8-9c44ed587432_812x314.png 848w, https://substackcdn.com/image/fetch/$s_!mSiV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f51ee86-def8-4d0f-b5f8-9c44ed587432_812x314.png 1272w, https://substackcdn.com/image/fetch/$s_!mSiV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f51ee86-def8-4d0f-b5f8-9c44ed587432_812x314.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><pre><code>Input: matrix = [
  [1,2,3],
  [4,0,5],
  [6,7,8]
]</code></pre><pre><code>Output: [
  [1,0,3],
  [0,0,0],
  [6,0,8]
]</code></pre><h4>Solution Brute&nbsp;Force</h4><p>Create another&nbsp;matrix.</p><p>Whenever a 0 is found, make its entire row and column 0 in the new&nbsp;matrix.</p><p>Complexity</p><ul><li><p>TC &#8594; O(m*n*(m+n))</p></li><li><p>SC &#8594;&nbsp;O(m*n)</p></li></ul><h4>Better Approach</h4><p>Use two&nbsp;arrays:</p><ul><li><p>row[]</p></li><li><p>col[]</p></li></ul><p>If matrix[i][j] == 0,&nbsp;mark:</p><pre><code>row[i] = 1;
col[j] = 1;</code></pre><p>Then traverse again and make all marked rows and columns&nbsp;zero.</p><h3>Complexity</h3><ul><li><p>TC &#8594;&nbsp;O(m*n)</p></li><li><p>SC &#8594;&nbsp;O(m+n)</p></li></ul><h3>Optimal Approach&#8202;&#8212;&#8202;O(1)&nbsp;Space</h3><p>Instead of extra arrays,&nbsp;use:</p><ul><li><p>first row &#8594; column&nbsp;markers</p></li><li><p>first column &#8594; row&nbsp;markers</p></li></ul><h3>Catch</h3><p>matrix[0][0] is shared by both first row and first&nbsp;column.</p><pre><code>class Solution {
    public void setZeroes(int[][] mat) {
        int m = mat.length;
        int n = mat[0].length;

        boolean firstRow = false;
        boolean firstCol = false;

        // check first row
        for (int j = 0; j &lt; n; j++) {
            if (mat[0][j] == 0) {
                firstRow = true;
                break;
            }
        }

        // check first column
        for (int i = 0; i &lt; m; i++) {
            if (mat[i][0] == 0) {
                firstCol = true;
                break;
            }
        }

        // mark rows and columns
        for (int i = 1; i &lt; m; i++) {
            for (int j = 1; j &lt; n; j++) {
                if (mat[i][j] == 0) {
                    mat[i][0] = 0;
                    mat[0][j] = 0;
                }
            }
        }

        // set zeroes
        for (int i = 1; i &lt; m; i++) {
            for (int j = 1; j &lt; n; j++) {
                if (mat[i][0] == 0 || mat[0][j] == 0) {
                    mat[i][j] = 0;
                }
            }
        }

        // first row
        if (firstRow) {
            for (int j = 0; j &lt; n; j++) {
                mat[0][j] = 0;
            }
        }

        // first column
        if (firstCol) {
            for (int i = 0; i &lt; m; i++) {
                mat[i][0] = 0;
            }
        }
    }
}</code></pre><h3>Complexity</h3><ul><li><p>TC &#8594;&nbsp;O(m*n)</p></li><li><p>SC &#8594;&nbsp;O(1)</p></li></ul><p>&#8216;See you at deployment&#8217;<br>Thank you&nbsp;!</p>]]></content:encoded></item><item><title><![CDATA[Fan-Out/Fan-In Architecture System Design]]></title><description><![CDATA[Topics To be Discussed&#8230;]]></description><link>https://hrithikchandok.substack.com/p/fan-out-fan-in-architecture-system-design-bcf599444dbe</link><guid isPermaLink="false">https://hrithikchandok.substack.com/p/fan-out-fan-in-architecture-system-design-bcf599444dbe</guid><dc:creator><![CDATA[HrithikChandok]]></dc:creator><pubDate>Mon, 27 Apr 2026 21:30:12 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/4ce6216d-9ea0-4144-b558-38f1a962e147_1024x559.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JryE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb50116ca-2001-46fe-9309-fb71fb701edf_1024x559.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JryE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb50116ca-2001-46fe-9309-fb71fb701edf_1024x559.png 424w, https://substackcdn.com/image/fetch/$s_!JryE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb50116ca-2001-46fe-9309-fb71fb701edf_1024x559.png 848w, https://substackcdn.com/image/fetch/$s_!JryE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb50116ca-2001-46fe-9309-fb71fb701edf_1024x559.png 1272w, https://substackcdn.com/image/fetch/$s_!JryE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb50116ca-2001-46fe-9309-fb71fb701edf_1024x559.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JryE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb50116ca-2001-46fe-9309-fb71fb701edf_1024x559.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b50116ca-2001-46fe-9309-fb71fb701edf_1024x559.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!JryE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb50116ca-2001-46fe-9309-fb71fb701edf_1024x559.png 424w, https://substackcdn.com/image/fetch/$s_!JryE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb50116ca-2001-46fe-9309-fb71fb701edf_1024x559.png 848w, https://substackcdn.com/image/fetch/$s_!JryE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb50116ca-2001-46fe-9309-fb71fb701edf_1024x559.png 1272w, https://substackcdn.com/image/fetch/$s_!JryE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb50116ca-2001-46fe-9309-fb71fb701edf_1024x559.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><h4>Topics To be Discussed&#8230;</h4><p>1. Fan-Out Pattern<br>2. Fan-In Pattern<br>3. Real World System using these pattern<br>4. <strong>Celebrity problem </strong>/ Hot keys in Fan-Out pattern<br>5. <strong>Straggler problem </strong>in Fan-In pattern<br>6. <strong>Interview Question</strong> on these pattern<br>7. Related Topics and Examples.</p><h3>1. Fan-out Architecture: The &#8220;Distributor&#8221;</h3><p><strong>Fan-out</strong> occurs when a single input or event triggers multiple parallel processes or is delivered to multiple destinations simultaneously.</p><h3>How it&nbsp;Works</h3><ol><li><p><strong>Event Producer:</strong> A single service generates a message or a&nbsp;task.</p></li><li><p><strong>Message Broker:</strong> The message is sent to a topic (e.g., in Kafka or&nbsp;SNS).</p></li><li><p><strong>Multiple Consumers:</strong> Several independent services subscribe to that topic. Each service gets a copy of the message and performs its own specific&nbsp;logic.</p></li></ol><h3>Deep-Dive Example: Social Media Post (e.g., Twitter/X)</h3><p>When a celebrity with 10 million followers posts a &#8220;tweet,&#8221; the system uses a fan-out&nbsp;pattern:</p><ul><li><p><strong>The Event:</strong> User clicks&nbsp;&#8220;Post.&#8221;</p></li><li><p><strong>The Fan-out:</strong> The system pushes that tweet into the &#8220;Timeline Cache&#8221; of all 10 million followers.</p></li><li><p><strong>Benefit:</strong> When followers open their app, the data is already there (read-heavy optimization).</p></li></ul><h3>2. Fan-in Architecture: The &#8220;Aggregator&#8221;</h3><p><strong>Fan-in</strong> is the mathematical opposite. it is the process of combining results from multiple independent sources or parallel tasks into a single unified&nbsp;result.</p><h3>How it&nbsp;Works</h3><ol><li><p><strong>Multiple Inputs:</strong> Various workers or upstream services finish their individual tasks.</p></li><li><p><strong>Synchronisation Point:</strong> A coordinator or a &#8220;Barrier&#8221; waits for all (or a quorum) of these tasks to complete.</p></li><li><p><strong>Aggregation:</strong> The results are merged, summarized, or reduced into a final&nbsp;output.</p></li></ol><h3>Deep-Dive Example: Search Engine Results (e.g.,&nbsp;Google)</h3><p>When you search for &#8220;Best Pizza,&#8221; the system doesn&#8217;t search one giant database.</p><ul><li><p><strong>Parallel Search:</strong> The query is sent to hundreds of &#8220;leaf nodes&#8221; (shards of the web&nbsp;index).</p></li><li><p><strong>The Fan-in:</strong> An aggregator service collects the top 10 results from <em>every</em> shard, re-ranks them by relevance, and presents you with the final top 10&nbsp;list.</p></li></ul><h3>Real World System using these&nbsp;pattern</h3><p>&#128661; Case Study: The Uber Notification &amp; Reporting System</p><h3>&#128168; The Fan-Out Pattern: Total Decoupling</h3><p>When a <strong>&#8220;Ride Completed&#8221;</strong> event triggers in the Uber app, we can&#8217;t afford a single delay. Several critical but independent operations need to happen <strong>simultaneously</strong>, and one slow process cannot block the&nbsp;rest.</p><p><strong>The Fan-Out System&nbsp;Flow:</strong></p><ul><li><p><strong>&#9889;&#65039; The Trigger:</strong> A user clicks &#8220;Complete Ride,&#8221; generating a &#8220;Ride Completed&#8221; event.</p></li><li><p><strong>&#128225; The Exchange:</strong> The system publishes this event to a message broker/exchange (e.g., Kafka, RabbitMQ).</p></li><li><p><strong>&#127881; The Fan-Out:</strong> The single message is fanned out and immediately picked up by <strong>three separate, concurrent consumers:</strong></p></li></ul><ol><li><p>&#128179; <strong>Billing Service:</strong> Instantly calculates the final fare and initiates the credit card&nbsp;charge.</p></li><li><p>&#128276; <strong>Push Notification Service:</strong> Pings the user&#8217;s phone with a &#8220;Rate your driver!&#8221;&nbsp;alert.</p></li><li><p>&#128200; <strong>Analytics Service:</strong> Updates the driver&#8217;s lifetime stats, completion rates, and adds the location data to heatmaps.</p></li></ol><p><strong>&#128161; Why Fan-Out?</strong> Total independence. If the Billing Service is under high load or down, it does not stop the user from receiving their crucial notification or the Analytics Service from logging data. This isolation maximizes reliability and responsiveness.</p><h3>&#129521; The Fan-In Pattern: Strict Coordination</h3><p>Fast-forward to Sunday night. The requirements change from &#8220;speed&#8221; to &#8220;completion and correctness.&#8221; The goal: generate a driver&#8217;s <strong>&#8220;Weekly Earnings Report.&#8221;</strong> This cannot happen instantly and requires precise synchronization.</p><p><strong>The Fan-In System&nbsp;Flow:</strong></p><ul><li><p><strong>&#128736;&#65039; The Fan-Out (Sub-tasks):</strong> The Reporter system triggers <strong>7 parallel jobs</strong>&#8202;&#8212;&#8202;one for each day of the week&#8202;&#8212;&#8202;to fetch detailed earning data from cold&nbsp;storage.</p></li><li><p><strong>&#128721; The Barrier:</strong> A coordination service sets a synchronization &#8220;barrier,&#8221; waiting until <strong>all 7 jobs confirm completion.</strong></p></li><li><p><strong>&#129309; The Fan-In (The Aggregation):</strong> A specialized Reporter Service collects all 7 daily data sets, <em>sums</em> the daily totals, calculates tax deductions, and <em>merges</em> the findings into a single, comprehensive PDF&nbsp;report.</p></li></ul><p><strong>&#128680; Critical System Design Detail: Handling Failures</strong> In Fan-In, the most critical decision is <strong>coordination logic</strong>. If the job for Saturday fails or the data is missing, the Fan-In coordinator must be programmed with a&nbsp;policy:</p><ol><li><p><strong>Fail-fast:</strong> Show the driver an error&nbsp;message.</p></li><li><p><strong>Partial-success:</strong> Generate the report but clearly mark Saturday&#8217;s data as &#8220;Pending/Unavailable.&#8221; This is a major discussion point in interviews!</p></li></ol><h3>2. Case Study: E-commerce Order Fulfillment</h3><p>In a complex e-commerce system like <strong>Amazon</strong>, checking out is a high-stakes Fan-out/Fan-in dance.</p><h3>The Workflow</h3><ol><li><p><strong>Fan-out (Inventory Check):</strong> When a user views a cart with 10 different items, the system fans out 10 requests to different warehouse databases to check stock&nbsp;levels.</p></li><li><p><strong>Fan-in (Cart Validation):</strong> The frontend &#8220;Fans-in&#8221; these 10 responses. Only if <em>all</em> items are confirmed available does the &#8220;Proceed to Checkout&#8221; button turn&nbsp;orange.</p></li><li><p><strong>Fan-out (Order Success):</strong> Once payment is confirmed:</p></li><li><p><strong>Email Service</strong> sends a&nbsp;receipt.</p></li></ol><ul><li><p><strong>Warehouse Service</strong> prints a packing&nbsp;slip.</p></li><li><p><strong>Inventory Service</strong> decrements the&nbsp;count.</p></li><li><p><strong>Loyalty Service</strong> adds&nbsp;points.</p></li></ul><h3><strong>Celebrity problem </strong>/ <strong>Hot keys</strong> / <strong>Thundering Herd</strong></h3><p>In a Fan-out architecture, engineers typically use a <strong>Hybrid Push/Pull Model</strong>. This is a classic system design interview deep-dive.</p><h4>1. The Hybrid Model: Push for &#8220;Peons,&#8221; Pull for&nbsp;&#8220;Kings&#8221;</h4><p>In a standard fan-out, when User A posts, the system &#8220;pushes&#8221; the post into the timelines of all followers. For a celebrity with 100M followers, this write-operation is catastrophic.</p><ul><li><p><strong>The Strategy:</strong> * <strong>Low-Follower Users (Push):</strong> When they post, fan-out to all followers&#8217; caches immediately. This keeps latency low for the average&nbsp;user.</p></li><li><p><strong>Celebrities/High-Follower Users (Pull):</strong> When they post, do <strong>not</strong> fan-out. Instead, store the post in a single &#8220;Celebrity Post&nbsp;Store.&#8221;</p></li><li><p><strong>The Merge on Read:</strong> When a follower opens their feed, the system pulls the pre-computed &#8220;Push&#8221; feed and then queries the &#8220;Celebrity Store&#8221; for any new posts from the celebrities they follow. It merges them on the&nbsp;fly.</p></li></ul><h3>The <strong>Straggler Problem</strong> / &#8220;Tail Latency&#8221;&nbsp;problem</h3><p>It occurs when a single task in a parallel computing job takes significantly longer to complete than the others. If 99 workers finish in <strong>1 second</strong>, but 1 worker (the straggler) takes <strong>30 seconds</strong>:The <strong>User Experience</strong> is 30 seconds of waiting, not 1&nbsp;second.</p><h4>Real-World Solutions (Interview Answers)</h4><h4>A. Speculative Execution (Hedged Requests)</h4><p>This is the strategy used by <strong>Google (MapReduce)</strong> and&nbsp;<strong>Hadoop</strong>.</p><ul><li><p><strong>How it works:</strong> The system monitors the progress of all workers. If it sees that 95% of workers are done, but a few are still &#8220;straggling,&#8221; it launches a <strong>duplicate</strong> of those specific tasks on different, idle&nbsp;workers.</p></li><li><p><strong>The Race:</strong> The system accepts the result from whoever finishes first and kills the other&nbsp;one.</p></li><li><p><strong>Trade-off:</strong> It uses more resources (CPU/Network), but it drastically reduces the &#8220;tail latency.&#8221;</p></li></ul><h4>B. Load Balancing with &#8220;Least&nbsp;Loaded&#8221;</h4><ul><li><p><strong>How it works:</strong> Instead of a simple Round-Robin fan-out, use a load balancer that tracks how many active tasks each worker&nbsp;has.</p></li><li><p><strong>Benefit:</strong> This prevents sending a new chunk to a worker that is already struggling with a &#8220;heavy&#8221;&nbsp;task.</p></li></ul><h4>C. Graceful Degradation (Partial&nbsp;Results)</h4><ul><li><p><strong>How it works:</strong> In non-critical systems (like a Search Engine or a &#8220;Recommended Videos&#8221; list), if a straggler exceeds a strict timeout (e.g., 500ms), the Fan-in service simply <strong>ignores&nbsp;it</strong>.</p></li><li><p><strong>The Result:</strong> The user sees 9 out of 10 search results immediately, which is better than waiting 30 seconds for all&nbsp;10.</p></li></ul><h3><strong>Interview Question</strong></h3><ul><li><p><strong>Q: How do you handle idempotency in a Fan-out&nbsp;system?</strong></p></li><li><p><strong>Why it matters:</strong> If a fan-out message is delivered twice (at-least-once delivery), you don&#8217;t want to charge a customer twice or send two notifications.</p></li><li><p><strong>The Answer:</strong> Use <strong>Idempotency Keys</strong> (UUIDs). The receiver checks a cache (like Redis) to see if that specific Task ID has already been processed before executing.</p></li><li><p><strong>Q: In a Fan-in architecture, how do you handle &#8220;Partial Availability&#8221;?</strong></p></li><li><p><strong>The Scenario:</strong> You fan-out a search to 10 shards. 9 return in 50ms, 1 is timed out. Do you wait or return 90% of the&nbsp;results?</p></li><li><p><strong>The Answer:</strong> Discuss <strong>Graceful Degradation</strong>. For a search engine, 90% of the index is better than a 500 error. For a banking transaction, you must wait or fail the whole thing (Atomic operations).</p></li><li><p><strong>Q: How do you scale the &#8220;Aggregator&#8221; in a Fan-in if the data being merged is too big for one machine&#8217;s memory?</strong></p></li><li><p><strong>The Answer:</strong> Use <strong>Multi-level Fan-in</strong> (Hierarchical Merging). Instead of 1,000 workers sending to 1 aggregator, have 1,000 workers send to 10 &#8220;Intermediate Aggregators,&#8221; which then send to 1 &#8220;Final Aggregator.&#8221;</p></li></ul><h3>Related Topics and&nbsp;Examples</h3><p>Exponential Backoff&nbsp;: is a error handling strategy where a request will get retry after some time on the down service&nbsp;. <br>The delay between each request will be increase exponential&nbsp;.</p><p>Jitter Concept&nbsp;: if a server goes down and 10k clients all start their exponential backoff at the exact same time, they will still all hit the server simultaneously at the 1s, 2s, 4s, and 8s marks. This is called <strong>Synchronization</strong>.</p><p>To solve this, we add <strong>Jitter</strong> (randomness). Instead of waiting exactly 4 seconds, the client waits for a random value between 0 and 4&nbsp;seconds.</p><h3>. Interview &#8220;Pro-Tips&#8221;</h3><ul><li><p><strong>The Ceiling:</strong> Always mention a <strong>Maximum Backoff Cap</strong>. You don&#8217;t want a client waiting 24 hours between retries if the math keeps doubling. You might cap the delay at 30 or 60&nbsp;seconds.</p></li><li><p><strong>The &#8220;Circuit Breaker&#8221; Link:</strong> If an interviewer asks about Backoff, mention the <strong>Circuit Breaker Pattern</strong>. While Backoff helps the client retry, a Circuit Breaker stops the client from even trying if it knows the server is definitely down, saving resources on both&nbsp;ends.</p></li></ul><blockquote><p><strong>See you at the deployment. &#128640;</strong></p></blockquote>]]></content:encoded></item><item><title><![CDATA[Why Solving LeetCode Isn’t Enough for Amazon SDE 1 Anymore]]></title><description><![CDATA[Recently, I was discussing interview experiences with a junior, and one thing became very clear &#8212; SDE interviews are evolving.]]></description><link>https://hrithikchandok.substack.com/p/why-solving-leetcode-isnt-enough-for-amazon-sde-1-anymore-c8ed8c058375</link><guid isPermaLink="false">https://hrithikchandok.substack.com/p/why-solving-leetcode-isnt-enough-for-amazon-sde-1-anymore-c8ed8c058375</guid><dc:creator><![CDATA[HrithikChandok]]></dc:creator><pubDate>Wed, 22 Apr 2026 20:09:27 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/ec3c6e2d-a18f-41ec-aadc-aae26301495a_1024x512.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DFmI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff5e07b4-8a65-4046-9fb4-9c9a42149f09_1024x512.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DFmI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff5e07b4-8a65-4046-9fb4-9c9a42149f09_1024x512.png 424w, https://substackcdn.com/image/fetch/$s_!DFmI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff5e07b4-8a65-4046-9fb4-9c9a42149f09_1024x512.png 848w, https://substackcdn.com/image/fetch/$s_!DFmI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff5e07b4-8a65-4046-9fb4-9c9a42149f09_1024x512.png 1272w, https://substackcdn.com/image/fetch/$s_!DFmI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff5e07b4-8a65-4046-9fb4-9c9a42149f09_1024x512.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DFmI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff5e07b4-8a65-4046-9fb4-9c9a42149f09_1024x512.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ff5e07b4-8a65-4046-9fb4-9c9a42149f09_1024x512.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!DFmI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff5e07b4-8a65-4046-9fb4-9c9a42149f09_1024x512.png 424w, https://substackcdn.com/image/fetch/$s_!DFmI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff5e07b4-8a65-4046-9fb4-9c9a42149f09_1024x512.png 848w, https://substackcdn.com/image/fetch/$s_!DFmI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff5e07b4-8a65-4046-9fb4-9c9a42149f09_1024x512.png 1272w, https://substackcdn.com/image/fetch/$s_!DFmI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff5e07b4-8a65-4046-9fb4-9c9a42149f09_1024x512.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a><figcaption class="image-caption">Leetcode</figcaption></figure></div><p>Recently, I was discussing interview experiences with a junior, and one thing became very clear&#8202;&#8212;&#8202;SDE interviews are evolving.</p><p>It&#8217;s no longer just about solving DSA problems in isolation.<br>The focus is shifting toward real-world engineering scenarios.</p><h3>The Assessment Structure</h3><p>The assessment typically includes two sections:</p><h3>1. DSA&nbsp;Problem</h3><p>The problem isn&#8217;t always based on a single pattern.<br>It can involve a mix of concepts like <strong>Graph + Map</strong>,&nbsp;where:</p><ul><li><p>Identifying the right approach quickly is&nbsp;crucial</p></li><li><p>Modeling the problem correctly matters more than brute&nbsp;force</p></li><li><p>Time pressure plays a big&nbsp;role</p></li></ul><h3>2. Repository-Based Question (Repo&nbsp;Round)</h3><p>This is where things get interesting.</p><p>Instead of coding from scratch, candidates may be given a <strong>complete project (Frontend + Backend, often Spring Boot)</strong> and asked to fix a broken&nbsp;feature.</p><p>For example:</p><ul><li><p>A Notification Service not working properly in a&nbsp;system</p></li><li><p>Emails or alerts not being triggered due to a failed event&nbsp;flow</p></li><li><p>Caching issues causing stale or incorrect data to be&nbsp;served</p></li></ul><p>This round&nbsp;tests:</p><ul><li><p>Navigating an unfamiliar codebase</p></li><li><p>Understanding end-to-end flow (controller &#8594; service &#8594; integration)</p></li><li><p>Debugging issues efficiently</p></li><li><p>Making precise fixes without breaking existing functionality</p></li></ul><h3>Key Takeaways</h3><ul><li><p>Strong DSA is important, but not sufficient</p></li><li><p>Reading and debugging existing codebases is a critical&nbsp;skill</p></li><li><p>Backend fundamentals (Spring Boot, APIs, system design flow) matter a&nbsp;lot</p></li><li><p>Practicing on real repositories is a game&nbsp;changer</p></li></ul><h3>What This&nbsp;Means</h3><p>Interviews are clearly shifting:</p><ul><li><p>Less focus on writing everything from&nbsp;scratch</p></li><li><p>More focus on how effectively you can work within a real&nbsp;system</p></li></ul><h3>Final Thought</h3><p>The real skill is not just solving problems.<br>It&#8217;s understanding systems.</p><p><strong>See you at the deployment. &#128640;</strong></p>]]></content:encoded></item><item><title><![CDATA[Salesforce Experience: (TSE) Role]]></title><description><![CDATA[The Interview Process]]></description><link>https://hrithikchandok.substack.com/p/my-salesforce-interview-experience-tse-role-1ed9a75b5929</link><guid isPermaLink="false">https://hrithikchandok.substack.com/p/my-salesforce-interview-experience-tse-role-1ed9a75b5929</guid><dc:creator><![CDATA[HrithikChandok]]></dc:creator><pubDate>Sun, 19 Apr 2026 07:12:34 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/0410a6d3-ba32-4c05-87c6-d9740ac06198_1024x768.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SGap!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb7e30d6-19fe-45c2-a06c-a309cc2a42c8_1024x768.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SGap!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb7e30d6-19fe-45c2-a06c-a309cc2a42c8_1024x768.jpeg 424w, https://substackcdn.com/image/fetch/$s_!SGap!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb7e30d6-19fe-45c2-a06c-a309cc2a42c8_1024x768.jpeg 848w, https://substackcdn.com/image/fetch/$s_!SGap!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb7e30d6-19fe-45c2-a06c-a309cc2a42c8_1024x768.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!SGap!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb7e30d6-19fe-45c2-a06c-a309cc2a42c8_1024x768.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!SGap!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb7e30d6-19fe-45c2-a06c-a309cc2a42c8_1024x768.jpeg" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/db7e30d6-19fe-45c2-a06c-a309cc2a42c8_1024x768.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!SGap!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb7e30d6-19fe-45c2-a06c-a309cc2a42c8_1024x768.jpeg 424w, https://substackcdn.com/image/fetch/$s_!SGap!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb7e30d6-19fe-45c2-a06c-a309cc2a42c8_1024x768.jpeg 848w, https://substackcdn.com/image/fetch/$s_!SGap!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb7e30d6-19fe-45c2-a06c-a309cc2a42c8_1024x768.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!SGap!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb7e30d6-19fe-45c2-a06c-a309cc2a42c8_1024x768.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><h3>The Interview Process</h3><h4>Round 1: The Online Assessment (OA)</h4><p>The OA was a mix of core fundamentals and problem-solving. It wasn&#8217;t just about &#8220;coding&#8221;; it was about how you think through a&nbsp;system.</p><ul><li><p><strong>Java OOPs:</strong> Two questions focused heavily on Object-Oriented programming principles (Inheritance, Polymorphism, etc.).</p></li><li><p><strong>Debugging:</strong> You are given snippets of broken code and asked to identify the logical or syntax errors. This is crucial for a TSE&nbsp;role.</p></li><li><p><strong>DSA:</strong> One standard Data Structures and Algorithms question. It wasn&#8217;t LeetCode Hard, but you need your basics (Strings/Arrays) to be rock&nbsp;solid.</p></li></ul><h4>Rounds 2 &amp; 3: Technical &amp; Scenario-Based</h4><p>These rounds move away from the IDE and into the &#8220;real world&#8221; of support engineering.</p><ul><li><p><strong>Customer Handling:</strong> How do you deal with an angry enterprise client? How do you prioritize a &#8220;Priority 1&#8221;&nbsp;ticket?</p></li><li><p><strong>Bug Management:</strong> Scenario questions on identifying if a problem is a configuration issue, a platform bug, or a custom code&nbsp;error.</p></li><li><p><strong>The &#8220;Disengagement&#8221; Strategy:</strong> How do you handle a situation where a customer is asking for something out of scope or refusing to follow technical advice?</p></li><li><p><strong>Salesforce Ecosystem:</strong> Questions about specific Salesforce products. You don&#8217;t need to be a certified admin, but knowing the cloud landscape (Sales, Service, Marketing Cloud) is a huge&nbsp;plus.</p></li></ul><h3>The Perks: The &#8220;Salesforce Life&#8221;</h3><p>Let&#8217;s be real&#8202;&#8212;&#8202;the benefits at Salesforce are top-tier. If you get the offer, you can look forward&nbsp;to:</p><ul><li><p><strong>The Gear:</strong> A top-of-the-line MacBook and a high-end monitor for your home/office setup.</p></li><li><p><strong>The Office Experience:</strong> In-house <strong>Baristas</strong> making custom coffee, excellent food, and reliable cab services for commuters.</p></li><li><p><strong>Well-being:</strong> They truly invest in making the workspace feel like a community.</p></li></ul><p><strong>The Cons:</strong></p><ul><li><p><strong>The Nature of the Work:</strong> It is a support role. You spend more time troubleshooting and communicating than building.</p></li><li><p><strong>Technical Growth:</strong> For someone who lives and breathes code, you might find it lacking. There isn&#8217;t much &#8220;heavy lifting&#8221; in terms of development.</p></li><li><p><strong>WLB &amp; Pay:</strong> While the pay is good, it doesn&#8217;t match the <strong>AMTS (Associate Member of Technical Staff)</strong> or <strong>MTS</strong> tracks. The Work-Life Balance in support can also be unpredictable due to shifts and urgent&nbsp;tickets.</p></li></ul><h3>Final Verdict</h3><p>If you are a hardcore technical person&#8202;&#8212;&#8202;a backend specialist, a frontend wizard, or a system design enthusiast&#8202;&#8212;&#8202;I would suggest aiming for the <strong>AMTS or MTS</strong> roles instead. The pay is significantly higher, the WLB is generally better, and you&#8217;ll actually be building the systems rather than just fixing&nbsp;them.</p><p>Thank you&nbsp;! <br>&#8220;See you at the Deployment.&#8221;- Hrithik</p>]]></content:encoded></item><item><title><![CDATA[Python Developer Interview Experience — Elastiq.ai]]></title><description><![CDATA[I recently interviewed with Elastiq.ai for a Python Developer role.]]></description><link>https://hrithikchandok.substack.com/p/python-developer-interview-experience-elastiq-ai-06a48e8821a7</link><guid isPermaLink="false">https://hrithikchandok.substack.com/p/python-developer-interview-experience-elastiq-ai-06a48e8821a7</guid><dc:creator><![CDATA[HrithikChandok]]></dc:creator><pubDate>Tue, 31 Mar 2026 06:17:37 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/98f71126-f796-4707-8123-a1479de907f9_1024x576.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I recently interviewed with Elastiq.ai for a Python Developer role. The process consisted of <strong>3 rounds</strong>, and here&#8217;s a summary of the <strong>first&nbsp;round</strong>:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NQRT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e65e540-4a91-4113-bb3f-91c745917d7a_1024x576.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NQRT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e65e540-4a91-4113-bb3f-91c745917d7a_1024x576.jpeg 424w, https://substackcdn.com/image/fetch/$s_!NQRT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e65e540-4a91-4113-bb3f-91c745917d7a_1024x576.jpeg 848w, https://substackcdn.com/image/fetch/$s_!NQRT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e65e540-4a91-4113-bb3f-91c745917d7a_1024x576.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!NQRT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e65e540-4a91-4113-bb3f-91c745917d7a_1024x576.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NQRT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e65e540-4a91-4113-bb3f-91c745917d7a_1024x576.jpeg" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4e65e540-4a91-4113-bb3f-91c745917d7a_1024x576.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!NQRT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e65e540-4a91-4113-bb3f-91c745917d7a_1024x576.jpeg 424w, https://substackcdn.com/image/fetch/$s_!NQRT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e65e540-4a91-4113-bb3f-91c745917d7a_1024x576.jpeg 848w, https://substackcdn.com/image/fetch/$s_!NQRT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e65e540-4a91-4113-bb3f-91c745917d7a_1024x576.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!NQRT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e65e540-4a91-4113-bb3f-91c745917d7a_1024x576.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><h3>Round 1: Technical Screening</h3><h4>1. Data Structures &amp; Algorithms</h4><p>I was asked to solve two standard DSA problems:</p><ul><li><p><strong>Find Minimum in Rotated Sorted&nbsp;Array</strong></p></li><li><p><strong>Longest Substring Without Repeating Characters</strong></p></li></ul><p>The focus was on <strong>optimal approaches, time complexity, and edge&nbsp;cases</strong>.</p><h4>2. SQL Questions</h4><ul><li><p>I was given <strong>3 tables</strong> and asked&nbsp;to:</p></li><li><p>Perform joins and aggregations</p></li><li><p>Retrieve combined data from all&nbsp;tables</p></li><li><p>The interviewer emphasized <strong>query optimization and correctness</strong></p></li></ul><h4>3. System Design &amp;&nbsp;Concepts</h4><p>Basic conceptual questions were asked&nbsp;on:</p><ul><li><p>CDN (Content Delivery&nbsp;Network)</p></li><li><p>Load Balancer</p></li><li><p>API Gateway</p></li><li><p>DynamoDB</p></li></ul><h4>4. DynamoDB Deep&nbsp;Dive</h4><ul><li><p>How data is stored in <strong>Amazon&nbsp;DynamoDB</strong></p></li><li><p>Understanding of:</p></li><li><p>Partition keys</p></li><li><p>Sorting mechanism</p></li><li><p>Scalability and distributed storage</p></li></ul><h4>5. Python Fundamentals</h4><ul><li><p>Differences between <strong>List vs&nbsp;Tuple</strong></p></li><li><p>Basic Python concepts and use&nbsp;cases</p></li></ul><h3>Overall Experience</h3><p>The round focused on a <strong>balanced evaluation</strong> of:</p><ul><li><p>Problem-solving skills&nbsp;(DSA)</p></li><li><p>Database knowledge (SQL)</p></li><li><p>System design fundamentals</p></li><li><p>Python core&nbsp;concepts</p></li></ul>]]></content:encoded></item><item><title><![CDATA[LSI vs GSI in DynamoDB: Key Differences, Advantages, and Use Cases]]></title><description><![CDATA[When working with Amazon DynamoDB, you often need to design your tables with future access patterns in mind.]]></description><link>https://hrithikchandok.substack.com/p/lsi-vs-gsi-in-dynamodb-key-differences-advantages-and-use-cases-e828022266c6</link><guid isPermaLink="false">https://hrithikchandok.substack.com/p/lsi-vs-gsi-in-dynamodb-key-differences-advantages-and-use-cases-e828022266c6</guid><dc:creator><![CDATA[HrithikChandok]]></dc:creator><pubDate>Sun, 17 Aug 2025 13:24:12 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!HwKs!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7662c0b0-f1e9-400d-a1b5-85bb39764171_1280x1280.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When working with <strong>Amazon DynamoDB</strong>, you often need to design your tables with future access patterns in mind. Primary keys help in efficient lookups, but what if you want to query data in a completely different way? That&#8217;s where <strong>indexes</strong> come&nbsp;in.</p><p>DynamoDB provides two types of secondary indexes:</p><ul><li><p><strong>Local Secondary Index&nbsp;(LSI)</strong></p></li><li><p><strong>Global Secondary Index&nbsp;(GSI)</strong></p></li></ul><p>Both serve to extend your query capabilities, but they differ significantly in terms of flexibility, performance, and use&nbsp;cases.</p><h3>&#128313; What is an LSI (Local Secondary Index)?</h3><p>An <strong>LSI</strong> allows you to create an alternative sort key for queries while keeping the <strong>same partition key</strong> as the base&nbsp;table.</p><p>For example:</p><ul><li><p><strong>Base Table</strong>: CustomerId (PK) + OrderId&nbsp;(SK)</p></li><li><p><strong>LSI</strong>: CustomerId (PK) + OrderDate (SK)</p></li></ul><p>This means you can still query all orders for a customer, but now sort or filter them by date (or another attribute).</p><p>Great question &#128077; This is where many people get confused. Let&#8217;s clear it&nbsp;up:</p><h3>&#128313; How LSI&nbsp;Works</h3><p>When you create a table in <strong>DynamoDB</strong>, you&nbsp;define:</p><ul><li><p><strong>Partition Key (PK)</strong> &#8594;&nbsp;required</p></li><li><p><strong>Sort Key (SK)</strong> &#8594;&nbsp;optional</p></li></ul><p>Now, with an <strong>LSI (Local Secondary Index)</strong>:</p><ul><li><p>The <strong>Partition Key stays the same</strong> as the base&nbsp;table.</p></li><li><p>You can define a <strong>different Sort Key</strong> (up to 5 LSIs per&nbsp;table).</p></li></ul><p>So yes&#8202;&#8212;&#8202;effectively, <strong>an item can be queried using multiple sort keys</strong> depending on which LSI you&nbsp;use.</p><h3>&#128204; Example</h3><h4>Base Table</h4><ul><li><p><strong>Partition Key (PK)</strong>: CustomerId</p></li><li><p><strong>Sort Key (SK)</strong>:&nbsp;OrderId</p></li></ul><p>This means you can query by CustomerId and order results by&nbsp;OrderId.</p><h4>Add LSI&nbsp;#1</h4><ul><li><p><strong>Partition Key (PK)</strong>: CustomerId</p></li><li><p><strong>Sort Key (SK)</strong>: OrderDate</p></li></ul><p>Now you can query all orders for a customer but sort/filter by OrderDate.</p><h4>Add LSI&nbsp;#2</h4><ul><li><p><strong>Partition Key (PK)</strong>: CustomerId</p></li><li><p><strong>Sort Key (SK)</strong>:&nbsp;Price</p></li></ul><p>Now you can query all orders for a customer but sort/filter by&nbsp;Price.</p><h3>&#128273; Important Notes</h3><ul><li><p>You don&#8217;t literally add a &#8220;second sort key&#8221; <strong>to the base table schema</strong>.<br>Instead, DynamoDB maintains <strong>separate index structures</strong> for each&nbsp;LSI.</p></li><li><p>Each LSI still points back to the <strong>same base item</strong> but organizes them differently for querying.</p></li><li><p>You can create <strong>up to 5 LSIs per&nbsp;table</strong>.</p></li></ul><p>&#128073; Think of it this way:<br>The <strong>base table has only one sort key</strong>, but <strong>LSIs give you alternate &#8220;views&#8221; of the data</strong>, each sorted by a different attribute.</p><h3>&#128313; What is a GSI (Global Secondary Index)?</h3><p>A <strong>GSI</strong> lets you create a completely new partition key (and optionally a sort key). It&#8217;s not restricted to the base table&#8217;s partition key.</p><p>For example:</p><ul><li><p><strong>Base Table</strong>: CustomerId (PK) + OrderId&nbsp;(SK)</p></li><li><p><strong>GSI</strong>: ProductId (PK) + OrderDate (SK)</p></li></ul><p>Now, instead of looking up by customer, you can query by&nbsp;product</p><h3>&#9989; Advantages and Disadvantages</h3><h3>Local Secondary Index&nbsp;(LSI)</h3><p><strong>Advantages:</strong></p><ul><li><p>Can return <strong>strongly consistent reads</strong>.</p></li><li><p>Useful for queries where partition key remains the same but you need a new sort&nbsp;order.</p></li><li><p>No extra cost for throughput (shares base table&#8217;s RCU/WCU).</p></li></ul><p><strong>Disadvantages:</strong></p><ul><li><p>Must be defined <strong>at table creation time</strong> (not flexible).</p></li><li><p>Limited to <strong>10GB per partition</strong>.</p></li><li><p>Dependent on base table&#8217;s throughput (no independent scaling).</p></li></ul><h3>Global Secondary Index&nbsp;(GSI)</h3><p><strong>Advantages:</strong></p><ul><li><p>Can be added <strong>anytime after table creation</strong>.</p></li><li><p>Allows <strong>completely new partition and sort&nbsp;keys</strong>.</p></li><li><p>Scales independently of the base table with its own capacity&nbsp;units.</p></li></ul><p><strong>Disadvantages:</strong></p><ul><li><p>Only supports <strong>eventually consistent reads</strong>.</p></li><li><p>Involves <strong>additional cost</strong> (separate RCU/WCU).</p></li><li><p>More complex maintenance compared to&nbsp;LSI.</p></li></ul><h3>&#128273; When to Use LSI vs&nbsp;GSI</h3><ul><li><p><strong>Use LSI</strong>&nbsp;when:</p></li><li><p>You need different sorting or filtering on the <strong>same partition key</strong>.</p></li><li><p>Strongly consistent reads are important.</p></li><li><p><strong>Use GSI</strong>&nbsp;when:</p></li><li><p>You need <strong>completely new access patterns</strong>.</p></li><li><p>Your queries are based on attributes other than the base partition key.</p></li><li><p>You want indexes that scale independently of the base&nbsp;table.</p></li></ul><h3>&#128221; Conclusion</h3><p>Both <strong>LSI</strong> and <strong>GSI</strong> are powerful features in DynamoDB, but their use cases are different.</p><ul><li><p>Choose <strong>LSI</strong> if you want additional sort keys with the same partition key and need strong consistency.</p></li><li><p>Choose <strong>GSI</strong> if you need new partition keys, more flexibility, or want to add indexes after the table is&nbsp;created.</p></li></ul><p>Designing your indexes upfront with the right strategy ensures your DynamoDB table is efficient, cost-effective, and scalable for future access patterns.</p>]]></content:encoded></item></channel></rss>