<?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[Skilled Coder]]></title><description><![CDATA[Programming & Software Development Newsletter]]></description><link>https://newsletter.theskilledcoder.com</link><image><url>https://substackcdn.com/image/fetch/$s_!NZCp!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77debe9e-5df7-4db1-90e8-049123837686_500x500.png</url><title>Skilled Coder</title><link>https://newsletter.theskilledcoder.com</link></image><generator>Substack</generator><lastBuildDate>Fri, 24 Apr 2026 12:29:59 GMT</lastBuildDate><atom:link href="https://newsletter.theskilledcoder.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Skilled Coder]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[skilledcoder@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[skilledcoder@substack.com]]></itunes:email><itunes:name><![CDATA[Skilled Coder]]></itunes:name></itunes:owner><itunes:author><![CDATA[Skilled Coder]]></itunes:author><googleplay:owner><![CDATA[skilledcoder@substack.com]]></googleplay:owner><googleplay:email><![CDATA[skilledcoder@substack.com]]></googleplay:email><googleplay:author><![CDATA[Skilled Coder]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[AI Benchmarks Explained: What Every Score Actually Means]]></title><description><![CDATA[What Every Score Actually Means (And Why You Should Care)]]></description><link>https://newsletter.theskilledcoder.com/p/ai-benchmarks-explained-what-every</link><guid isPermaLink="false">https://newsletter.theskilledcoder.com/p/ai-benchmarks-explained-what-every</guid><dc:creator><![CDATA[Skilled Coder]]></dc:creator><pubDate>Sun, 12 Apr 2026 13:05:08 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!wY9i!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F584b6bb9-68f4-495f-8739-468f320745d0_1802x876.webp" 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_!wY9i!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F584b6bb9-68f4-495f-8739-468f320745d0_1802x876.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wY9i!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F584b6bb9-68f4-495f-8739-468f320745d0_1802x876.webp 424w, https://substackcdn.com/image/fetch/$s_!wY9i!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F584b6bb9-68f4-495f-8739-468f320745d0_1802x876.webp 848w, https://substackcdn.com/image/fetch/$s_!wY9i!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F584b6bb9-68f4-495f-8739-468f320745d0_1802x876.webp 1272w, https://substackcdn.com/image/fetch/$s_!wY9i!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F584b6bb9-68f4-495f-8739-468f320745d0_1802x876.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wY9i!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F584b6bb9-68f4-495f-8739-468f320745d0_1802x876.webp" width="1456" height="708" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/584b6bb9-68f4-495f-8739-468f320745d0_1802x876.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:708,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:74808,&quot;alt&quot;:null,&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;:&quot;https://newsletter.theskilledcoder.com/i/193963547?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F584b6bb9-68f4-495f-8739-468f320745d0_1802x876.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wY9i!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F584b6bb9-68f4-495f-8739-468f320745d0_1802x876.webp 424w, https://substackcdn.com/image/fetch/$s_!wY9i!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F584b6bb9-68f4-495f-8739-468f320745d0_1802x876.webp 848w, https://substackcdn.com/image/fetch/$s_!wY9i!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F584b6bb9-68f4-495f-8739-468f320745d0_1802x876.webp 1272w, https://substackcdn.com/image/fetch/$s_!wY9i!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F584b6bb9-68f4-495f-8739-468f320745d0_1802x876.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><p>Imagine hiring a software engineer. You wouldn&#8217;t just ask them to recite textbook definitions - you&#8217;d give them real bugs to fix, systems to design, and deadlines to hit. AI benchmarks work the same way. Each one is a different job interview for a machine mind, testing whether it can actually do the work - not just talk about it.</p><p>This guide breaks down every major AI benchmark in plain language: what it tests, why it matters, what happens when AI aces it, and what keeps researchers up at night.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.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">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><h2><strong>1. SWE-bench Verified - &#8220;Can You Actually Fix Real Bugs?&#8221;</strong></h2><p>Picture this: it&#8217;s 2 a.m., your production server is down, and the bug is buried somewhere in a 50,000-line Django codebase. You need someone who can read the issue report, navigate the repo, understand the architecture, write the patch, and make sure the tests pass - all without hand-holding.</p><p>That&#8217;s SWE-bench.</p><h3><strong>What It Actually Tests</strong></h3><p>SWE-bench pulls real GitHub issues from popular open-source projects (Django, Flask, scikit-learn, sympy, etc.) and asks the AI to produce a working code patch. The &#8220;Verified&#8221; variant means every problem has been human-reviewed to confirm it has a clear, unambiguous solution.</p><ul><li><p>The AI gets: an issue description and the full repository.</p></li><li><p>The AI must: produce a code diff that fixes the issue.</p></li><li><p>Success is measured by: whether the existing test suite passes after applying the patch.</p></li></ul><h3><strong>Current Score: 93.9%</strong></h3><p>This means the AI can now fix 94 out of 100 real software bugs from production open-source projects. A year ago, the best models were stuck around 30%.</p><h3><strong>What Happens When This Hits 100%</strong></h3><p><strong>Automated bug triage at scale</strong> - Companies could route incoming GitHub issues directly to an AI agent that fixes and opens a PR within minutes.</p><ul><li><p><strong>10x reduction in maintenance cost</strong> - The bulk of any engineering team&#8217;s time is spent on bug fixes and incremental changes, not greenfield features.</p></li><li><p><strong>Open source acceleration</strong> - Projects with thousands of stale issues (like CPython, Linux) could be systematically cleaned up.</p></li></ul><p><strong>Example</strong>: Imagine every <code>good-first-issue</code> on GitHub getting an automated fix PR within 5 minutes of being filed. New contributors could focus on design and architecture instead of hunting typos and edge cases.</p><h3><strong>Risks</strong></h3><ul><li><p>&#8220;Looks correct, isn&#8217;t correct&#8221; :A patch can pass tests but introduce subtle regressions. The test suite is only as good as its coverage.</p></li><li><p>Benchmark gaming :Models trained specifically on SWE-bench repos might memorize patterns rather than truly understanding code.</p></li><li><p>Job displacement anxiety :Junior developers often build their skills through bug-fix tickets. If AI handles those, how do juniors learn?</p></li></ul><h2><strong>2. SWE-bench Pro - &#8220;Can You Handle the Hard Stuff?&#8221;</strong></h2><p>SWE-bench Verified was the appetizer. SWE-bench Pro is the main course and it&#8217;s trying to choke you.</p><p>While &#8220;Verified&#8221; tests single-file fixes in Python repos, Pro throws in multi-language codebases, multi-file edits, complex dependency chains, and problems that require understanding the architecture of a system, not just its syntax.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gu4I!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68257281-ffa7-4d4f-968f-8510caf39e21_1462x836.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gu4I!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68257281-ffa7-4d4f-968f-8510caf39e21_1462x836.webp 424w, https://substackcdn.com/image/fetch/$s_!gu4I!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68257281-ffa7-4d4f-968f-8510caf39e21_1462x836.webp 848w, https://substackcdn.com/image/fetch/$s_!gu4I!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68257281-ffa7-4d4f-968f-8510caf39e21_1462x836.webp 1272w, https://substackcdn.com/image/fetch/$s_!gu4I!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68257281-ffa7-4d4f-968f-8510caf39e21_1462x836.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gu4I!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68257281-ffa7-4d4f-968f-8510caf39e21_1462x836.webp" width="1456" height="833" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/68257281-ffa7-4d4f-968f-8510caf39e21_1462x836.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:833,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:33760,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/193963547?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68257281-ffa7-4d4f-968f-8510caf39e21_1462x836.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!gu4I!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68257281-ffa7-4d4f-968f-8510caf39e21_1462x836.webp 424w, https://substackcdn.com/image/fetch/$s_!gu4I!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68257281-ffa7-4d4f-968f-8510caf39e21_1462x836.webp 848w, https://substackcdn.com/image/fetch/$s_!gu4I!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68257281-ffa7-4d4f-968f-8510caf39e21_1462x836.webp 1272w, https://substackcdn.com/image/fetch/$s_!gu4I!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68257281-ffa7-4d4f-968f-8510caf39e21_1462x836.webp 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3><strong>Current Score: 77.8%</strong></h3><p>Still very high, but the 16-point gap from Verified tells you something important: understanding architecture is harder than fixing syntax.</p><h3><strong>What This Means In Practice</strong></h3><p>If this reaches 95%+:</p><ul><li><p>AI could handle complex refactoring tasks (&#8220;migrate this codebase from REST to GraphQL&#8221;)</p></li><li><p>Pull request reviews could become fully automated not just linting, but semantic code review</p></li><li><p>Mid-level engineering tasks start becoming AI-automatable</p></li></ul><p>Example: A startup with 3 engineers could ship at the velocity of a 15-person team, with AI agents handling the bulk of feature branch work while humans focus on product direction.</p><h2><strong>3. USAMO 2026 - &#8220;Can You Think Like a Math Olympiad Champion?&#8221;</strong></h2><p>The USA Mathematical Olympiad (USAMO) isn&#8217;t your school exam. There are no multiple-choice questions. No calculators. Just six brutally hard proof-based problems spread across two 4.5-hour sessions. The best high school mathematicians in America score maybe 25 out of 42 points on a good day.</p><p>Now an AI scores 97.6%.</p><h3><strong>What It Actually Tests</strong></h3><p>USAMO problems require:</p><ul><li><p>Creative insight - You can&#8217;t brute-force a proof. You need to &#8220;see&#8221; the elegant path.</p></li><li><p>Rigorous logic - Every step must be watertight. Hand-waving gets you zero points.</p></li><li><p>Multi-step reasoning - Solutions often span 2&#8211;3 pages of dense mathematical argument.</p></li></ul><h3><strong>Why This Is Mind-Blowing</strong></h3><p>This isn&#8217;t about calculating <code>2 + 2</code>. USAMO tests the kind of abstract reasoning that was supposed to be uniquely human - the ability to stare at a problem, have an &#8220;aha!&#8221; moment, and construct an argument that didn&#8217;t exist before.</p><p>Example problem flavor: <em>&#8220;Prove that for all positive integers n, there exists a set of n points in the plane, no three collinear, such that all mutual distances are irrational, but every triangle formed has rational area.&#8221;</em></p><p>A human proving this needs geometric intuition, number theory knowledge, and creative construction. The AI now does this better than 99% of trained mathematicians.</p><h3><strong>Benefits</strong></h3><ul><li><p>Automated mathematical research - AI could generate and verify new theorems, accelerating fields like number theory, topology, and combinatorics.</p></li><li><p>Personalized math tutoring - An AI that can <em>prove</em> can also <em>explain</em> - walking students through proofs step by step, identifying exactly where their reasoning breaks down.</p></li><li><p>Engineering applications - Better formal verification of safety-critical systems (bridges, aircraft, nuclear reactors) through automated mathematical proof checking.</p></li></ul><h3><strong>Risks</strong></h3><ul><li><p>The &#8220;creativity&#8221; question :Is the AI truly being creative, or has it absorbed enough proof patterns to generate novel-looking combinations? The philosophical debate rages on.</p></li><li><p>Academic integrity :Math competitions and proof-based courses face a fundamental challenge when AI can outperform every student.</p></li></ul><h2><strong>4. GPQA Diamond - &#8220;Are You Smarter Than a PhD?&#8221;</strong></h2><p>Here&#8217;s a humbling experiment: Take 198 multiple-choice questions in biology, chemistry, and physics. Give them to smart, educated non-experts with unlimited time and full internet access. They score about 34%. Give them to PhD domain experts. They score about 65&#8211;70%.</p><p>Now give them to AI. It scores 94.6%.</p><p>The AI is outperforming the humans who <em>wrote the questions</em>.</p><h3><strong>What Makes GPQA Diamond Special</strong></h3><p>The &#8220;Google-Proof&#8221; in the name is the key: these questions are deliberately crafted so you can&#8217;t just look up the answer. They require:</p><ul><li><p>Synthesizing knowledge across sub-fields (e.g., applying quantum mechanics to a biology question)</p></li><li><p>Multi-step reasoning through complex chains of logic</p></li><li><p>Understanding at the <em>intuition</em> level, not just the <em>definition</em> level</p></li></ul><p>Example question flavor: <em>&#8220;A researcher observes anomalous spin-orbit coupling in a novel 2D material. Given the following band structure data and crystal symmetry constraints, which of these four mechanisms best explains the observed splitting pattern?&#8221;</em></p><p>You can&#8217;t Google that. You either understand condensed matter physics or you don&#8217;t.</p><h3><strong>What 94.6% Means</strong></h3><p>Practical Benefits:</p><ul><li><p>AI-assisted diagnosis - An AI that reasons at PhD level in biology and chemistry could serve as a &#8220;second opinion&#8221; for complex medical diagnoses, especially in regions with doctor shortages.</p></li><li><p>Accelerated drug discovery - Multi-disciplinary reasoning (combining chemistry, biology, and physics) is the bottleneck in pharmaceutical research. AI could propose novel drug candidates by connecting dots that siloed human teams miss.</p></li><li><p>Graduate education - PhD students could have a study partner that genuinely understands their domain at an expert level.</p></li></ul><h3><strong>Risks</strong></h3><ul><li><p>Confident but wrong : At 94.6%, the AI still gets 5.4% wrong. In medicine or materials science, that 5% could be catastrophic if humans over-trust the model.</p></li><li><p>Deskilling : If researchers rely on AI to do their reasoning, do they lose the ability to think critically themselves?</p></li></ul><h2><strong>5. Humanity&#8217;s Last Exam - &#8220;The Hardest Test Ever Created&#8221;</strong></h2><p>In late 2024, a global consortium of experts set out to create the hardest exam ever written. The rules were brutal:</p><ol><li><p>Domain experts from every field - math, literature, history, law, medicine, obscure linguistics - submitted their hardest questions.</p></li><li><p>If <em>any</em> existing AI model could answer a question, it was thrown out.</p></li><li><p>The remaining 2,500 questions were supposed to be the last frontier - the intellectual Berlin Wall that machines couldn&#8217;t breach.</p></li></ol><p>When it launched, the best AI scored 8%. Researchers celebrated. &#8220;This will keep them busy for years,&#8221; they said.</p><p>It took 16 months. We&#8217;re now at 64.7%.</p><h3><strong>What It Tests</strong></h3><p>Everything. Literally <em>everything</em> academic humans know:</p><ul><li><p>Advanced mathematics and logic</p></li><li><p>Obscure historical facts and literary analysis</p></li><li><p>Expert-level scientific reasoning</p></li><li><p>Philosophical arguments</p></li><li><p>Multilingual comprehension</p></li><li><p>Cross-domain synthesis (questions that require expertise in TWO fields simultaneously)</p></li></ul><h3><strong>The 64.7% Score (With Tools)</strong></h3><p>&#8220;With tools&#8221; means the AI was allowed to write and run code, search for information, and use calculators. Without tools, it still scored 56.8%.</p><p>Why this is significant: The exam was <em>designed to be impossible for AI</em>. Reaching 64.7% is like having someone break a world record that everyone said was physically unattainable.</p><h3><strong>Benefits</strong></h3><ul><li><p>True general intelligence indicator - Unlike narrow benchmarks, HLE tests breadth. A high score here means the AI is genuinely knowledgeable across all human domains.</p></li><li><p>Universal research assistant - An AI that can answer questions across every discipline becomes the ultimate interdisciplinary tool.</p></li></ul><h3><strong>Risks</strong></h3><ul><li><p>The &#8220;last exam&#8221; problem : If AI conquers this too, what&#8217;s the next benchmark? At what point do we run out of ways to measure whether AI is smarter than us?</p></li><li><p>False sense of superintelligence : 64.7% is impressive but still means the AI is wrong on a third of the hardest questions. Misunderstanding this as &#8220;AI knows everything&#8221; creates dangerous overconfidence.</p></li></ul><h2><strong>6. CyberGym - &#8220;Can You Hack Like a Professional?&#8221;</strong></h2><p>Cybersecurity is a cat-and-mouse game. Defenders build walls; attackers find cracks. CyberGym puts AI on both sides of that war.</p><p>The benchmark includes real-world offensive and defensive tasks:</p><ul><li><p>Finding vulnerabilities in code</p></li><li><p>Writing exploits</p></li><li><p>Detecting intrusions</p></li><li><p>Reproducing known CVEs (Common Vulnerabilities and Exposures)</p></li></ul><h3><strong>Current Score: 83.1% (vs 66.6% for previous generation)</strong></h3><p>This 16.5-point jump means the new AI can:</p><ul><li><p>Find and exploit vulnerabilities that the previous model completely missed</p></li><li><p>Chain together multi-step attacks (e.g., privilege escalation &#8594; lateral movement &#8594; data exfiltration)</p></li><li><p>Understand defense mechanisms well enough to bypass them</p></li></ul><h3><strong>Practical Benefits</strong></h3><ul><li><p>Automated penetration testing - Companies could run continuous, AI-driven security audits instead of expensive annual pen-tests.</p></li><li><p>Bug bounty automation - AI could scan open-source code for vulnerabilities before attackers find them.</p></li><li><p>National cybersecurity - Governments could deploy AI defenders that match the capabilities of the best human attackers.</p></li></ul><h3><strong>Risks</strong></h3><p>This is where the scoreboard gets dark.</p><ul><li><p>Offensive capabilities in the wrong hands : An AI that can find and exploit vulnerabilities at 83.1% accuracy is a weapon. If this technology is open-sourced or leaked, it dramatically lowers the barrier for cyberattacks.</p></li><li><p>Speed advantage : A human pen-tester might find a vulnerability in hours. An AI can find hundreds in minutes. The attacker-defender asymmetry gets worse.</p></li></ul><h2><strong>7. Firefox Exploit Writing - &#8220;Can You Write a Zero-Day?&#8221;</strong></h2><p>This is the benchmark that made Anthropic not release their model to the public.</p><p>In red-team testing against Firefox 147 (a fully patched, modern web browser), Claude Mythos Preview successfully developed working JavaScript shell exploits 181 times. The previous model? Twice.</p><p>Let that sink in. A 90x improvement in the ability to autonomously find and exploit zero-day vulnerabilities in production software used by hundreds of millions of people.</p><h3><strong>What This Actually Means</strong></h3><p>A &#8220;zero-day&#8221; is a vulnerability that the software vendor doesn&#8217;t know about - so there are zero days of advance warning. They are the nuclear weapons of cybersecurity, and historically, only elite nation-state hacking groups and a handful of expert researchers could develop them.</p><p>Now an AI can do it 181 times in a test session.</p><h3><strong>Practical Benefits (if properly controlled)</strong></h3><ul><li><p>Proactive vulnerability discovery - If the good guys use this first, every major browser, OS, and framework could be hardened before attackers find the holes.</p></li><li><p>The &#8220;immune system&#8221; model - Think of it like AI white blood cells, constantly probing your own software for weaknesses and alerting developers.</p></li></ul><h3><strong>Risks (and why this model is restricted)</strong></h3><ul><li><p>This is why Claude Mythos Preview is not publicly available. Anthropic restricted access to select security partners under &#8220;Project Glasswing&#8221; an initiative focused on securing critical software.</p></li><li><p>Proliferation risk : If this capability leaks into open-source models, the entire internet&#8217;s security model changes overnight.</p></li><li><p>Autonomous attack potential : An AI that can write browser exploits could theoretically be chained with other AI capabilities to conduct end-to-end cyberattacks without human involvement.</p></li></ul><p>This is no longer theoretical. This benchmark represents the first concrete evidence that AI has crossed the threshold from &#8220;cybersecurity tool&#8221; to &#8220;cybersecurity weapon.&#8221;</p><h2><strong>8. Cybench CTF Challenges - &#8220;Can You Win a Hacking Competition?&#8221;</strong></h2><p>Capture The Flag (CTF) competitions are the Olympics of cybersecurity. Teams of elite hackers compete to solve challenges across categories like cryptography, reverse engineering, binary exploitation, web security, and forensics. Each challenge has a hidden &#8220;flag&#8221; (a secret string) that you can only find by successfully exploiting a vulnerability or solving a puzzle.</p><p>Cybench packages professional-level CTF challenges into a standardized benchmark for AI agents.</p><h3><strong>What It Tests</strong></h3><p>Unlike CyberGym (which focuses on broader offensive/defensive tasks), Cybench is specifically about CTF-style puzzle-solving:</p><ul><li><p>Reverse engineering - Disassemble a binary, figure out what it does, extract the secret</p></li><li><p>Cryptography - Break flawed encryption schemes</p></li><li><p>Web exploitation - Find SQL injection, XSS, or authentication bypasses in a running web app</p></li><li><p>Binary exploitation - Write buffer overflow exploits, ROP chains, format string attacks</p></li><li><p>Forensics - Recover hidden data from memory dumps, network captures, or corrupted files</p></li></ul><h3><strong>Current Performance</strong></h3><p>Frontier models have been rapidly improving on Cybench, with top agents now capable of solving tasks that would take skilled human CTF players hours. While no model has achieved 100% on the full benchmark, some specialized agent configurations have demonstrated near-perfect performance on curated subsets of challenges, particularly in web exploitation and cryptography categories.</p><h3><strong>Practical Benefits</strong></h3><ul><li><p>Training the next generation - AI CTF solvers can generate unlimited practice problems and walkthroughs for cybersecurity students</p></li><li><p>Automated security audits - The same skills that crack CTF challenges (SQL injection, XSS, auth bypass) are exactly what real-world pen-testers look for</p></li><li><p>Vulnerability research - An AI that can reverse-engineer binaries and break crypto could find flaws in real software before attackers do</p></li></ul><h3><strong>Risks</strong></h3><ul><li><p>Lowered barrier to entry: CTF skills traditionally required years of training. An AI that solves them instantly could give script kiddies the power of expert hackers.</p></li><li><p>Dual-use by design : Every CTF skill maps directly to a real-world attack technique. There&#8217;s no &#8220;safe&#8221; version of binary exploitation.</p></li></ul><h2><strong>9. Terminal-Bench 2.0 - &#8220;Can You Run a Server?&#8221;</strong></h2><p>Forget writing code - can the AI actually <em>operate an entire system</em>? Terminal-Bench 2.0 drops the AI into a sandboxed Linux container with a task like:</p><ul><li><p>&#8220;Debug why this Docker container keeps crashing&#8221;</p></li><li><p>&#8220;Migrate this legacy Python 2 codebase to Python 3&#8221;</p></li><li><p>&#8220;Set up a CI/CD pipeline for this project&#8221;</p></li><li><p>&#8220;Find and fix the memory leak in this Node.js application&#8221;</p></li></ul><p>No GUI. No hand-holding. Just a terminal prompt and a job to do.</p><h3><strong>Current Score: 82.0%</strong></h3><p>This means the AI successfully completes 82% of real-world DevOps and system administration tasks by navigating file systems, reading logs, editing configs, running commands, and debugging issues - all through a terminal.</p><h3><strong>Practical Benefits</strong></h3><ul><li><p>AI DevOps engineers - On-call rotations could be supplemented (or replaced) by AI agents that diagnose and fix infrastructure issues at 3 a.m.</p></li><li><p>Automated migration projects - The dreaded &#8220;upgrade from v2 to v3&#8221; project could be handled by an agent that reads docs, updates code, and validates the result.</p></li><li><p>Small team force multiplier - A startup founder who can&#8217;t afford a dedicated SRE gets one for the cost of an API call.</p></li></ul><h3><strong>Risks</strong></h3><ul><li><p>Root access concerns : An AI operating with terminal access has enormous power. A mistyped <code>rm -rf /</code> or misconfigured firewall rule can be catastrophic.</p></li><li><p>Blind trust in automation : When the AI &#8220;says&#8221; it fixed the issue, how do you verify? The 18% failure rate means nearly 1 in 5 tasks isn&#8217;t completed correctly.</p></li></ul><blockquote><p><em>If you&#8217;re curious about <strong>Agentic AI but don&#8217;t know where to start</strong>, I&#8217;ve broken it down in the simplest possible way for beginners , <strong><a href="https://theskilledcoder.com/agentic-ai">checkout here</a></strong></em></p></blockquote><h2><strong>10. OSWorld-Verified - &#8220;Can You Use a Computer Like a Human?&#8221;</strong></h2><p>OSWorld takes it a step further than Terminal-Bench. Instead of just a terminal, the AI gets a full desktop environment - Ubuntu, Windows, or macOS - and must complete tasks by clicking buttons, navigating menus, filling out forms, and switching between applications.</p><p>Tasks like:</p><ul><li><p>&#8220;Open the spreadsheet, sort column C by date, create a pivot table, and email the results to <a href="mailto:john@example.com">john@example.com</a>&#8221;</p></li><li><p>&#8220;Install VS Code, configure the Python extension, and set up a virtual environment for this project&#8221;</p></li><li><p>&#8220;Find the file called &#8216;Q3_report.pdf&#8217; somewhere on this computer and upload it to Google Drive&#8221;</p></li></ul><h3><strong>Current Score: 79.6%</strong></h3><p>The AI can now use a computer like a human user about 80% of the time - navigating GUIs, understanding visual layouts, and performing multi-step workflows across applications.</p><h3><strong>Practical Benefits</strong></h3><ul><li><p>True digital assistants - Not chatbots, but agents that <em>operate your computer for you</em>. &#8220;Schedule a meeting, book the conference room, and send the calendar invite&#8221; - done.</p></li><li><p>Accessibility revolution - Elderly or disabled users who struggle with complex interfaces could delegate tasks to an AI that operates the computer on their behalf.</p></li><li><p>Business process automation - RPA (Robotic Process Automation) on steroids. Instead of brittle scripts that break when a button moves, AI agents that <em>understand</em> the interface.</p></li></ul><h3><strong>Risks</strong></h3><ul><li><p>Privacy and access : An AI that can operate your full desktop can also see your emails, passwords, and private files.</p></li><li><p>Shadow IT : If employees start using AI agents to automate their work, IT departments lose visibility into what&#8217;s happening on company machines.</p></li></ul><h2><strong>11. MMMLU - &#8220;Do You Understand the Whole World?&#8221;</strong></h2><p>MMMLU (Multilingual Massive Multitask Language Understanding) takes the classic MMLU knowledge test - thousands of questions across 57 subjects - and runs it in dozens of languages. It&#8217;s not enough to know the answer in English; can you explain quantum physics in Hindi? Debate philosophy in Japanese? Discuss constitutional law in Portuguese?</p><h3><strong>Current Score: 92.7%</strong></h3><p>The AI demonstrates near-expert-level knowledge across most academic subjects and in most major world languages.</p><h3><strong>Practical Benefits</strong></h3><ul><li><p>Global education access - A student in rural Indonesia gets the same quality AI tutor as a student at MIT, in their own language.</p></li><li><p>Multilingual governance - AI systems that can reason in the local language help governments serve diverse populations.</p></li><li><p>Cross-cultural research - Researchers can query AI in their native language and get domain-expert-level answers without English as a bottleneck.</p></li></ul><h3><strong>Risks</strong></h3><ul><li><p>Cultural bias - The AI might &#8220;know&#8221; many languages but still reason from a Western-centric perspective baked into its training data.</p></li><li><p>Low-resource language gap - While scores are high for major languages (English, Chinese, Spanish), performance drops significantly for languages with less training data (Swahili, Quechua, Welsh).</p></li></ul><h2><strong>The Bigger Picture: What All These Numbers Mean Together</strong></h2><p>Look at the scoreboard again. Every single benchmark shows massive year-over-year improvement. But the <em>combination</em> is what matters:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fYhR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F921175e2-9b83-4f0f-92cb-8e300238a6c6_1384x782.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fYhR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F921175e2-9b83-4f0f-92cb-8e300238a6c6_1384x782.webp 424w, https://substackcdn.com/image/fetch/$s_!fYhR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F921175e2-9b83-4f0f-92cb-8e300238a6c6_1384x782.webp 848w, https://substackcdn.com/image/fetch/$s_!fYhR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F921175e2-9b83-4f0f-92cb-8e300238a6c6_1384x782.webp 1272w, https://substackcdn.com/image/fetch/$s_!fYhR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F921175e2-9b83-4f0f-92cb-8e300238a6c6_1384x782.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fYhR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F921175e2-9b83-4f0f-92cb-8e300238a6c6_1384x782.webp" width="1384" height="782" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/921175e2-9b83-4f0f-92cb-8e300238a6c6_1384x782.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:782,&quot;width&quot;:1384,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:52488,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/193963547?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F921175e2-9b83-4f0f-92cb-8e300238a6c6_1384x782.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fYhR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F921175e2-9b83-4f0f-92cb-8e300238a6c6_1384x782.webp 424w, https://substackcdn.com/image/fetch/$s_!fYhR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F921175e2-9b83-4f0f-92cb-8e300238a6c6_1384x782.webp 848w, https://substackcdn.com/image/fetch/$s_!fYhR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F921175e2-9b83-4f0f-92cb-8e300238a6c6_1384x782.webp 1272w, https://substackcdn.com/image/fetch/$s_!fYhR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F921175e2-9b83-4f0f-92cb-8e300238a6c6_1384x782.webp 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>The Timeline</strong></h2><p>Think of each benchmark as a different subject in school:</p><ul><li><p>2023: AI was a mediocre high school student - decent at multiple choice, terrible at essays and proofs.</p></li><li><p>2024: AI graduated to college level - could write code, solve standard problems, and hold conversations about most topics.</p></li><li><p>2025: AI became a grad student - could tackle research-level problems, write production code, and reason about complex systems.</p></li><li><p>2026: AI is now a world-class expert in coding, math, science, and cybersecurity - simultaneously.</p></li></ul><p>These benchmarks aren&#8217;t just academic games. Each one represents a real-world capability that, when mastered, changes what&#8217;s possible. We&#8217;re watching AI cross threshold after threshold, and the speed of crossing is accelerating. The question is no longer <em>&#8220;Will AI get there?&#8221;</em> it&#8217;s <em>&#8220;Are we ready when it does?&#8221;</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/p/ai-benchmarks-explained-what-every?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://newsletter.theskilledcoder.com/p/ai-benchmarks-explained-what-every?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Backend Master Interview Preparation Sheet]]></title><description><![CDATA[Your one-page revision guide to crack backend interviews for DSA, System Design, LLD, and tech or leadership rounds.]]></description><link>https://newsletter.theskilledcoder.com/p/backend-master-interview-preparation</link><guid isPermaLink="false">https://newsletter.theskilledcoder.com/p/backend-master-interview-preparation</guid><dc:creator><![CDATA[Skilled Coder]]></dc:creator><pubDate>Mon, 16 Mar 2026 07:23:14 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!1G4f!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F416c2511-412e-419a-960a-89e24a5b16ab_1024x608.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_!1G4f!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F416c2511-412e-419a-960a-89e24a5b16ab_1024x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1G4f!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F416c2511-412e-419a-960a-89e24a5b16ab_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!1G4f!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F416c2511-412e-419a-960a-89e24a5b16ab_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!1G4f!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F416c2511-412e-419a-960a-89e24a5b16ab_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!1G4f!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F416c2511-412e-419a-960a-89e24a5b16ab_1024x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1G4f!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F416c2511-412e-419a-960a-89e24a5b16ab_1024x608.png" width="1024" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/416c2511-412e-419a-960a-89e24a5b16ab_1024x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:608,&quot;width&quot;:1024,&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_!1G4f!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F416c2511-412e-419a-960a-89e24a5b16ab_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!1G4f!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F416c2511-412e-419a-960a-89e24a5b16ab_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!1G4f!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F416c2511-412e-419a-960a-89e24a5b16ab_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!1G4f!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F416c2511-412e-419a-960a-89e24a5b16ab_1024x608.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"></figcaption></figure></div><p><em>Use this as your high-yield interview revision page. It is not meant to cover every topic. It is meant to cover the things that repeat across DSA, System Design, LLD, and interview rounds often enough to matter.</em></p><p><em>Pair it with the main roadmaps, then use the lists below as your last-mile revision checklist. <a href="https://theskilledcoder.com/lld-roadmap">LLD Roadmap</a> , <a href="https://theskilledcoder.com/system-design-roadmap">HLD Roadmap</a> , <a href="https://theskilledcoder.com/dsa-roadmap">DSA Roadmap</a></em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.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">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><h2><strong>What to prioritize first</strong></h2><ol><li><p><strong>DSA first - </strong>Prioritize this for internship, fresher, and SDE 1 style interviews where coding rounds dominate.</p></li><li><p><strong>System Design next - </strong>Shift here for SDE 2+, backend, platform, API, and distributed systems roles where scale and tradeoffs matter.</p></li><li><p><strong>LLD to close gaps - </strong>Practice this heavily if the company likes machine coding, object modeling, design patterns, or real-world code structure discussions.</p></li></ol><p><em><strong>Target Outcome</strong></em></p><p><em>If you can solve most of the DSA list below, explain major System Design tradeoffs clearly, and walk through 4&#8211;5 LLD problems without drifting into vague class dumping, you are already in strong shape for a large number of interviews.</em></p><div><hr></div><h2><strong>DSA: the patterns that show up again and again</strong></h2><ul><li><p>Arrays and hashing</p></li><li><p>Two pointers</p></li><li><p>Sliding window</p></li><li><p>Binary search</p></li><li><p>Stack and monotonic stack</p></li><li><p>Queue and heap</p></li><li><p>Linked list</p></li><li><p>Trees and graphs</p></li><li><p>Backtracking</p></li><li><p>Trie</p></li><li><p>Dynamic programming</p></li><li><p>Greedy</p></li></ul><h3><strong>25 must-do DSA questions</strong></h3><p><strong>Arrays, hashing, and sliding window</strong></p><ol><li><p><a href="https://theskilledcoder.com/dsa/target-sum-patterns#q-find-pair-with-sum">Find Pair With Sum</a> : Baseline hashing pattern. You should be able to compare brute force, sorting, and hash map approaches cleanly.</p></li><li><p><a href="https://theskilledcoder.com/dsa/duplicate-detection#q-duplicates-within-k-distance">Duplicates Within K Distance</a> : Simple but useful for learning set-based windows and sliding constraints.</p></li><li><p><a href="https://theskilledcoder.com/dsa/standard-math#q-rotate-image">Rotate Image</a> : Classic in-place matrix manipulation problem that tests index discipline.</p></li><li><p><a href="https://theskilledcoder.com/dsa/target-sum-patterns#q-three-sum-to-zero">3 Sum to Zero</a> : Sorting, duplicate handling, and two-pointer reasoning in one question.</p></li><li><p><a href="https://theskilledcoder.com/dsa/anagram-problems#q-find-all-anagrams">Find All Anagrams</a> : Strong sliding-window frequency-map question that appears in many variants.</p></li></ol><p><strong>Binary search, greedy, and interval thinking</strong></p><ol><li><p><a href="https://theskilledcoder.com/dsa/longest-substring#q-minimum-window-substring">Minimum Window Substring</a> : One of the most important sliding window patterns to master deeply.</p></li><li><p><a href="https://theskilledcoder.com/dsa/binary-search-basics#q-find-first-and-last-position">Find First and Last Position</a> : Teaches clean boundary-based binary search instead of just &#8220;find target&#8221;.</p></li><li><p><a href="https://theskilledcoder.com/dsa/search-rotated-array#q-search-in-rotated-array-ii">Search Rotated Array II</a> : Binary search with ambiguous duplicate cases and branching discipline.</p></li><li><p><a href="https://theskilledcoder.com/dsa/koko-eating-bananas#q-split-array-largest-sum">Split Array Largest Sum</a> : Important example of binary search on answer space.</p></li><li><p><a href="https://theskilledcoder.com/dsa/step-path-counting#q-jump-game-ii">Jump Game II</a> : Greedy range expansion question with very interview-friendly intuition.</p></li></ol><p><strong>Stack, queue, and heap</strong></p><ol><li><p><a href="https://theskilledcoder.com/dsa/parentheses-problems#q-balanced-brackets">Balanced Brackets</a> : Basic stack correctness, but still useful for edge cases and clean thinking.</p></li><li><p><a href="https://theskilledcoder.com/dsa/min-stack#q-implement-queue-using-stacks">Implement Queue Using Stacks</a> : Tests amortized analysis and data structure simulation.</p></li><li><p><a href="https://theskilledcoder.com/dsa/monotonic-stack-problems#q-largest-rectangle-in-histogram">Largest Rectangle in Histogram</a> : The classic monotonic stack problem.</p></li><li><p><a href="https://theskilledcoder.com/dsa/standard-heap#q-task-scheduler">Task Scheduler</a>: Greedy counting and cooldown reasoning with useful follow-up discussions.</p></li><li><p><a href="https://theskilledcoder.com/dsa/merging-sorting#q-merge-k-sorted-lists">Merge K Sorted Lists</a> : Heap merge pattern that generalizes to many stream-style problems.</p></li></ol><p><strong>Linked list, trees, and graphs</strong></p><ol><li><p><a href="https://theskilledcoder.com/dsa/cycle-detection-intersection#q-check-intersection">Intersection of Two Linked Lists</a> : Small problem, but excellent for pointer reasoning and explanation quality.</p></li><li><p><a href="https://theskilledcoder.com/dsa/merging-sorting#q-sort-list">Sort List</a> : Merge sort on linked lists. Common and very reusable.</p></li><li><p><a href="https://theskilledcoder.com/dsa/binary-tree-max-depth#q-diameter-of-binary-tree">Diameter of Binary Tree</a> : Bottom-up tree recursion and &#8220;answer through child state&#8221; thinking.</p></li><li><p><a href="https://theskilledcoder.com/dsa/invert-binary-tree#q-construct-tree-from-traversals">Construct Tree From Traversals</a> : Recursion plus indexing map. Great for testing tree reconstruction logic.</p></li><li><p><a href="https://theskilledcoder.com/dsa/island-grid-problems#q-count-islands">Count Islands</a> : Core DFS/BFS connected-component foundation problem.</p></li></ol><p><strong>Backtracking, trie, DP, and DSU</strong></p><ol><li><p><a href="https://theskilledcoder.com/dsa/tree-validation-components#q-find-redundant-connection">Find Redundant Connection</a> : Union-find basics and cycle detection in an elegant format.</p></li><li><p><a href="https://theskilledcoder.com/dsa/combinatorial-search#q-combination-sum">Combination Sum</a> : Backtracking template, branching choices, and pruning.</p></li><li><p><a href="https://theskilledcoder.com/dsa/standard-trie#q-design-add-and-search-words-data-structure">Add and Search Words</a> : Trie plus wildcard branching. Good for pattern-matching structures.</p></li><li><p><a href="https://theskilledcoder.com/dsa/step-path-counting#q-count-ways-to-climb">Count Ways to Climb</a> : The cleanest entry point into one-dimensional dynamic programming.</p></li><li><p><a href="https://theskilledcoder.com/dsa/longest-subsequence#q-longest-common-subsequence">Longest Common Subsequence</a> : One of the essential two-dimensional DP problems.</p></li></ol><p><em><strong>DSA revision rule</strong></em></p><ul><li><p><em><strong>State the brute-force solution first.</strong> Interviewers want to know that you can reason from baseline to optimized.</em></p></li><li><p><em><strong>Explain why the optimized structure works.</strong> Do not just say &#8220;use a map&#8221; or &#8220;use DP&#8221; without the invariant.</em></p></li><li><p><em><strong>Call out time and space complexity clearly.</strong> Say it before the interviewer has to ask.</em></p></li><li><p><em><strong>Walk through one edge case.</strong> Empty input, duplicates, overflow, off-by-one, or single-element cases usually reveal whether you really understand the solution.</em></p></li><li><p><em><strong>Practice verbalizing while coding.</strong> Silent solving does not prepare you for real rounds.</em></p></li></ul><div><hr></div><h2><strong>System Design: what actually matters in interviews</strong></h2><ul><li><p><em><strong>Clarify requirements.</strong> Separate functional requirements from scale, latency, consistency, and reliability expectations.</em></p></li><li><p><em><strong>Estimate rough scale.</strong> Users, QPS, storage, peak traffic, and read/write ratio shape the design.</em></p></li><li><p><em><strong>Define APIs and data model.</strong> This forces your design to become concrete early.</em></p></li><li><p><em><strong>Draw high-level components.</strong> Client, gateway, services, cache, database, async workers, and storage.</em></p></li><li><p><em><strong>Deep dive into the real bottleneck.</strong> Pick the place where the design gets interesting instead of staying generic.</em></p></li><li><p><em><strong>Handle failures and observability.</strong> Retries, DLQs, fallback behavior, metrics, logs, tracing, and alerts matter.</em></p></li><li><p><em><strong>End with tradeoffs.</strong> Good design interviews end with constraints, not false certainty.</em></p></li></ul><h3>High-yield System Design topics</h3><ul><li><p><strong><a href="https://theskilledcoder.com/posts/system-design/back-of-envelope">Back-of-the-Envelope</a></strong> : EstimationPractice quick reasoning about QPS, storage, bandwidth, and latency budgets.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/system-design/cap-theorem">CAP Theorem</a></strong> : Foundational language for distributed tradeoffs.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/system-design/consistency-models">Consistency Models</a></strong> : Know strong, eventual, causal, and when each is acceptable.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/system-design/l4-vs-l7-load-balancing">L4 vs L7 Load Balancing</a></strong> : A very common scaling and routing discussion.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/system-design/cache-invalidation-strategies">Cache Invalidation Strategies</a></strong> : One of the most practical topics in real systems.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/system-design/database-replication">Database Replication</a></strong> : Leader-replica basics, lag, and failover thinking.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/system-design/database-sharding">Database Sharding</a> : </strong>When single-node storage stops being enough.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/system-design/message-brokers">Message Brokers</a></strong> : Queues, fan-out, decoupling, and async workflow design.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/system-design/retry-backoff-strategies">Retry and Backoff Strategies</a></strong> : Critical for resilience and client behavior under failure.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/system-design/dead-letter-queues">Dead Letter Queues</a></strong> : What happens when retries keep failing.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/system-design/distributed-tracing">Distributed Tracing</a></strong> : Observability is part of good design, not a side note.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/system-design/how-do-you-ensure-exactly-once-payment-processing">Exactly-Once Payment Processing</a></strong> : Idempotency and correctness under retries.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/system-design/multi-region">Multi-Region Design</a></strong> : Latency, failover, routing, and cross-region data decisions.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/system-design/disaster-recovery">Disaster Recovery</a></strong> : RPO, RTO, backups, restore testing, and operational realism.</p></li></ul><h3>Classic System Design problems you should be ready for</h3><ul><li><p><strong><a href="https://theskilledcoder.com/posts/system-design/how-would-you-design-a-url-shortener-that-handles-500-million-redirects-per-day">Design a URL Shortener</a></strong> : Hashing, key generation, storage, redirects, hot keys, and analytics.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/system-design/how-would-you-design-a-news-feed-for-1-billion-users">Design a News Feed</a></strong> : Fan-out, ranking, caching, and read/write tradeoffs.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/system-design/notification-system-design">Design a Notification System</a></strong> : Retries, templates, preferences, rate limits, and delivery guarantees.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/system-design/how-would-you-build-a-rate-limiter-for-1m-requestssecond">Design a Rate Limiter</a></strong> : Fixed window, sliding window, counters, and distributed fairness.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/system-design/how-would-you-design-a-ticket-booking-system-for-100k-concurrent-users">Design a Ticket Booking System</a></strong> : Seat holds, locking, contention, timeout expiry, and payment correctness.</p></li></ul><blockquote><p><em><strong><a href="https://theskilledcoder.com/system-design-roadmap#systems">Complete list of 50+ HLD questions</a></strong></em></p></blockquote><p><strong>What interviewers want to hear in System Design</strong></p><ul><li><p><em><strong>Where the data lives.</strong> Not just &#8220;use a database,&#8221; but which store holds which truth.</em></p></li><li><p><em><strong>Where the bottleneck appears first.</strong> Cache hot keys, database contention, queue lag, fan-out pressure, or storage throughput.</em></p></li><li><p><em><strong>How reads and writes scale differently.</strong> Caches, replicas, queues, batching, or partitioning should come up naturally.</em></p></li><li><p><em><strong>How duplicate work is prevented.</strong> Idempotency, dedupe keys, exactly-once semantics, and safe retries matter.</em></p></li><li><p><em><strong>How failures degrade.</strong> What happens when a dependency is slow, down, or partially failing.</em></p></li><li><p><em><strong>What tradeoff you are making on purpose.</strong> Strong answers are explicit about the cost of simplicity, latency, consistency, or freshness.</em></p></li></ul><div><hr></div><h2><strong>Low Level Design: the parts that separate average answers from strong ones</strong></h2><p><em>The goal is not to create many classes. The goal is to model the domain cleanly, keep invariants close to where they belong, and leave space for future requirements without collapsing into a God object.</em></p><h3>High-yield LLD topics</h3><ul><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/solid-real-world">SOLID in Real World</a></strong> : Know where each principle helps and where over-application makes code worse.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/composition-vs-inheritance">Composition vs Inheritance</a></strong> : Composition should usually be your default.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/encapsulation">Encapsulation</a></strong> : Keep invariants inside objects instead of scattering checks.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/abstraction">Abstraction</a></strong> : Expose what matters, hide what changes.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/dependency-injection">Dependency Injection</a></strong>: Cleaner wiring, easier tests, lower coupling.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/dependency-inversion">Dependency Inversion</a></strong> : Depend on contracts instead of concrete implementations.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/repository">Repository Pattern</a></strong> : Separate persistence details from domain behavior.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/service-layer">Service Layer</a></strong> : Coordinate workflows without bloating controllers or entities.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/thread-safety">Thread Safety</a></strong> : Essential whenever shared mutable state exists.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/synchronization-primitives">Synchronization Primitives</a></strong> : Know locks, semaphores, and coordination basics.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/strategy-pattern">Strategy Pattern</a></strong> : Great when behavior varies cleanly behind an interface.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/observer-pattern">Observer Pattern</a></strong> : Useful for event-driven updates and decoupled notifications.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/factory-method">Factory Method</a></strong> : Hide creation complexity and keep callers clean.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/decorator-pattern">Decorator Pattern</a></strong> : Extend behavior without subclass explosion.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/state-pattern">State Pattern</a></strong> : Perfect when behavior changes with lifecycle stages.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/clean-architecture">Clean Architecture</a></strong> : Boundaries, use cases, and dependency direction.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/hexagonal-architecture">Hexagonal Architecture</a></strong>: Ports-and-adapters thinking for clean change boundaries.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/unit-testing">Unit Testing</a></strong> : Interview code should be testable even if you do not write every test.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/long-methods-god-classes">Long Methods and God Classes</a></strong> : Recognize the smell before you produce it.</p></li></ul><h3>A strong LLD answer usually includes</h3><ul><li><p><em><strong>Core entities and responsibilities.</strong> Every important domain object should have a reason to exist.</em></p></li><li><p><em><strong>Interfaces where behavior varies.</strong> Do not hardwire future variation into conditionals if an abstraction is cleaner.</em></p></li><li><p><em><strong>A clear workflow for the main use case.</strong> Walk through the request path from input to state change.</em></p></li><li><p><em><strong>A state model when lifecycle matters.</strong> Booking, payment, order, and approval flows usually benefit from explicit state thinking.</em></p></li><li><p><em><strong>Validation and invariant ownership.</strong> Decide which object is responsible for enforcing correctness.</em></p></li><li><p><em><strong>Concurrency handling.</strong> If two users can update shared state, you need a strategy for correctness.</em></p></li><li><p><em><strong>Extension points.</strong> Think about how the design evolves when a new rule or variant appears.</em></p></li><li><p><em><strong>Tests you would write first.</strong> This reveals whether the design is actually usable.</em></p></li></ul><h3>Classic LLD problems you should practice</h3><ul><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/design-parking-lot">Design Parking Lot</a></strong> : Entities, spot assignment, ticketing, pricing, and entry/exit flow.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/design-lru-cache">Design LRU Cache</a></strong> : Hash map + doubly linked list with strict O(1) operations.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/design-splitwise">Design Splitwise</a></strong> : Domain modeling, expense strategies, and simplification choices.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/design-elevator">Design Elevator</a></strong> : Scheduling, state transitions, and directional logic.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/design-vending-machine">Design Vending Machine</a></strong> : Inventory, payment, state handling, and rollback cases.</p></li><li><p><strong><a href="https://theskilledcoder.com/posts/low-level-design/design-atm">Design ATM</a></strong> : Workflow modeling, validation, security, and state machine thinking.</p></li></ul><blockquote><p><em><strong><a href="https://theskilledcoder.com/lld-roadmap#lld-problems">Complete list of 35+ LLD questions</a></strong></em></p></blockquote><p>If you can explain the topics on this page clearly and solve most of the linked DSA questions without major hints, you already cover a large chunk of what many interviews expect.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/p/backend-master-interview-preparation?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/p/backend-master-interview-preparation?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://newsletter.theskilledcoder.com/p/backend-master-interview-preparation?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p>]]></content:encoded></item><item><title><![CDATA[9 Pieces of Dev Wisdom You Only Learn After Building Real Systems]]></title><description><![CDATA[Wisdom you will only gain once you are in production]]></description><link>https://newsletter.theskilledcoder.com/p/9-pieces-of-dev-wisdom-you-only-learn</link><guid isPermaLink="false">https://newsletter.theskilledcoder.com/p/9-pieces-of-dev-wisdom-you-only-learn</guid><dc:creator><![CDATA[Skilled Coder]]></dc:creator><pubDate>Thu, 05 Mar 2026 07:13:57 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!oS5L!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72d532c1-019b-4eba-9889-3c40984079e9_1024x608.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_!oS5L!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72d532c1-019b-4eba-9889-3c40984079e9_1024x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oS5L!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72d532c1-019b-4eba-9889-3c40984079e9_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!oS5L!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72d532c1-019b-4eba-9889-3c40984079e9_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!oS5L!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72d532c1-019b-4eba-9889-3c40984079e9_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!oS5L!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72d532c1-019b-4eba-9889-3c40984079e9_1024x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oS5L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72d532c1-019b-4eba-9889-3c40984079e9_1024x608.png" width="1024" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/72d532c1-019b-4eba-9889-3c40984079e9_1024x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:608,&quot;width&quot;:1024,&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_!oS5L!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72d532c1-019b-4eba-9889-3c40984079e9_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!oS5L!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72d532c1-019b-4eba-9889-3c40984079e9_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!oS5L!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72d532c1-019b-4eba-9889-3c40984079e9_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!oS5L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72d532c1-019b-4eba-9889-3c40984079e9_1024x608.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"></figcaption></figure></div><p>Every engineer collects scars. The kind that don&#8217;t show up in your resume but live rent-free in your head every time you write a similar piece of code.</p><p>These nine lessons aren&#8217;t theoretical. Each one was learned inside a war room, a Slack thread during outage, or a post-mortem doc written in collective shame. If any of these sounds painfully familiar - you&#8217;re in good company.</p><p><strong>Let&#8217;s get into them - with real examples.</strong></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.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">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><p><em>The Coupling Rule</em></p><h2>1) If two modules talk too much &#8594; merge them</h2><p>Assume at one company, you had a <strong>billing module</strong> and a <strong>pricing module</strong>.</p><p>In theory, they were separate concerns. Clean architecture, nice diagrams, everyone clapped in the design meeting.</p><p>In reality? Every billing call needed pricing data. Every pricing change required a billing update. They were calling each other constantly - <em>like a couple fighting but refusing to break up.</em></p><p><strong>What life looked like every sprint</strong></p><ul><li><p>Pricing team deploys &#8594; billing breaks</p></li><li><p>Billing team deploys &#8594; pricing edge cases surface</p></li><li><p>Both teams stop and blame the interface contract</p></li><li><p>Everyone writes more tests. Nothing fundamentally changes.</p></li></ul><p>One afternoon the team sat in a conference room and said the quiet part out loud: <em>&#8220;These aren&#8217;t two modules. They&#8217;re two halves of one responsibility.&#8221;</em></p><p>We merged them into a single service. Now: fewer deploy issues, simpler tests, no circular dependencies, cleaner ownership.</p><p><strong>Warning sign:</strong> If you're maintaining a shared interface document just so two modules don't break each other - the abstraction is lying to you.</p><p><strong>Lesson: Chatter = coupling. If two parts can&#8217;t live without each other, don&#8217;t force the separation. Merge is not defeat - it&#8217;s clarity.</strong></p><div><hr></div><p><em>The Silence Rule</em></p><h2>2) If they talk too little &#8594; introduce an event</h2><p>The opposite problem showed up in another system.</p><p>The User Profile Service updated a user&#8217;s email address. Quietly. No ceremony, no announcements.</p><p>The Notification Service? It never heard a thing.</p><p><strong>What users experienced</strong></p><ul><li><p>Changed email &#8594; no verification email sent to new address</p></li><li><p>No security alert about the email change</p></li><li><p>Old email (possibly compromised) no longer gets any notifications</p></li><li><p>Support tickets: &#8220;I never got any emails after updating my address&#8221;</p></li></ul><p>You dug in and found the two modules had zero connection. No API call, no event, nothing. They just lived in separate repos doing their own thing, blissfully unaware of each other.</p><p><em>&#8220;The bug isn&#8217;t in either module - the bug is in the gap between them.&#8221;</em></p><p>You fixed it by publishing a simple event: <code>user.email_updated</code>.</p><p>Now the Notification Service subscribed and sent a verification. The Auth Service listened and invalidated sessions. The Audit Log captured the change. Everything downstream became consistent - without any module knowing about the others.</p><p><strong>Lesson: Silence creates invisible bugs. If modules need awareness but not coupling - events fill the gap. The event bus is not overhead, it's connective tissue.</strong></p><div><hr></div><p><em>The Velocity Rule</em></p><h2>3) If your logic changes often &#8594; use a rules engine</h2><p>Assume you had a fraud detection system. Classic stuff - block suspicious transactions, flag risky merchants, apply region-specific policies.</p><p>Week 1: the logic fit in a single function. Clean, readable, nice.</p><p>Week 6: the product team wanted a new exception for enterprise clients. </p><p>Week 8: a region-specific override. </p><p>Week 10: a time-of-day condition. </p><p>By week 16, the function had 11 nested <code>if</code> blocks and nobody could read it without a whiteboard session.</p><p><strong>The quarterly product meeting, every quarter</strong></p><ul><li><p>PM: &#8220;Small change - just add an exception for users over $50k spend&#8221;</p></li><li><p>Dev: &#8220;That&#8217;s a deploy. Full QA cycle. 2 weeks.&#8221;</p></li><li><p>PM: &#8220;For one condition?&#8221;</p></li><li><p>Dev: &#8220;...yes.&#8221;</p></li></ul><p>In this case you had to switched to a rules engine. Business analysts wrote YAML-based rules, you loaded them dynamically at runtime, and 90% of changes stopped requiring a deploy entirely. QA tested rule files, not application builds.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7axg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff21896d8-ef49-4348-bd60-4198a7a6b5d5_1562x340.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7axg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff21896d8-ef49-4348-bd60-4198a7a6b5d5_1562x340.png 424w, https://substackcdn.com/image/fetch/$s_!7axg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff21896d8-ef49-4348-bd60-4198a7a6b5d5_1562x340.png 848w, https://substackcdn.com/image/fetch/$s_!7axg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff21896d8-ef49-4348-bd60-4198a7a6b5d5_1562x340.png 1272w, https://substackcdn.com/image/fetch/$s_!7axg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff21896d8-ef49-4348-bd60-4198a7a6b5d5_1562x340.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7axg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff21896d8-ef49-4348-bd60-4198a7a6b5d5_1562x340.png" width="1456" height="317" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f21896d8-ef49-4348-bd60-4198a7a6b5d5_1562x340.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:317,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:82298,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/189964132?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff21896d8-ef49-4348-bd60-4198a7a6b5d5_1562x340.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7axg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff21896d8-ef49-4348-bd60-4198a7a6b5d5_1562x340.png 424w, https://substackcdn.com/image/fetch/$s_!7axg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff21896d8-ef49-4348-bd60-4198a7a6b5d5_1562x340.png 848w, https://substackcdn.com/image/fetch/$s_!7axg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff21896d8-ef49-4348-bd60-4198a7a6b5d5_1562x340.png 1272w, https://substackcdn.com/image/fetch/$s_!7axg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff21896d8-ef49-4348-bd60-4198a7a6b5d5_1562x340.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><strong>Lesson: Fast-changing logic doesn&#8217;t belong in code. Put it in data. Interpret it at runtime. Your future self will thank you at the next product planning meeting.</strong></p><div><hr></div><p><em>The Invisibility Rule</em></p><h2>4) If your data changes often &#8594; use DB triggers carefully</h2><p>Now we tracked customer loyalty points. Every transaction updated a running balance - inserts, updates, refunds, all of it.</p><p>Instead of recalculating the balance on every read, a clever dev set up a database trigger. It updated a denormalized <code>points_balance</code> column automatically on every transaction insert. Elegant. Fast. Very clever.</p><p>It worked beautifully&#8230; for three months.</p><p>Then someone added a business rule inside the trigger (a rule that should have lived in the application layer). Then another person added logging to the trigger. Then a third added a conditional.</p><p><em>"Why did this row update?" - "Oh, the trigger ran."<br>"Why didn't staging behave the same?" - "Different trigger version."<br>"Where is the trigger defined?" - silence.</em></p><p>Triggers are invisible code. They don&#8217;t show up in git blame. They don&#8217;t appear in your IDE search. Most devs don&#8217;t know they exist until something breaks in a way that makes no sense.</p><p><em>Good trigger use cases: Maintaining a </em><code>last_updated_at</code><em> timestamp. Enforcing a referential invariant. Logging raw inserts to an audit table. These are bookkeeping jobs - not business logic.</em></p><p><strong>Lesson: Triggers are powerful - but invisible. Use them for bookkeeping and invariants, never for business rules. What lives in the DB, stays in the DB - and haunts future engineers.</strong></p><div><hr></div><p><em>The Cold Start Rule</em></p><h2>5) If a cache miss hurts &#8594; precompute</h2><p>If you have to build an analytics dashboard. Revenue per segment, top products, user cohort breakdowns. The kind that executives open first thing Monday morning, click frantically, and then send a message to engineering because it&#8217;s slow.</p><p>You cached it. But on a cache miss - a new day, a freshly deployed service, a cache eviction - the system had to recalculate everything from scratch across millions of rows. Every cache miss caused a CPU spike that slowed down <em>every other service on the same host.</em></p><p><strong>Monday 9:03 AM, every week</strong></p><ul><li><p>CFO opens dashboard &#8594; cold cache &#8594; 4-second spinner</p></li><li><p>Clicks &#8220;Refresh&#8221; (mistake) &#8594; triggers the calculation again</p></li><li><p>CPU spikes &#8594; API latency rises across the board</p></li><li><p>On-call engineer gets paged everytime</p></li></ul><p>The fix wasn&#8217;t more Redis tuning. The fix was removing the heavy computation from the request path entirely. You have to run a background job every hour that precomputed all summaries and stored them. The dashboard read from a <code>summary_snapshots</code> table-&#8212; always pre-warmed, always fast.</p><p>Dashboard load time: <strong>4 seconds &#8594; 100ms.</strong> The CFO stopped messaging engineering.</p><p><strong>Lesson: If the fallback computation is expensive, move it out of the request path entirely. Caching defers work - precomputing eliminates it.</strong></p><div><hr></div><p><em>The Truth Rule</em></p><h2>6) If staleness hurts &#8594; invalidate aggressively</h2><p>E-commerce inventory is the opposite of the dashboard problem. Here, stale data doesn&#8217;t just slow things down - it breaks trust with the customer.</p><p>Your inventory cache had a 30-second TTL. Seemed reasonable. For most data, it is.</p><p>But inventory is not &#8220;most data.&#8221; Ten seconds of a stale cache meant a customer could see <strong>&#8220;Only 1 left!&#8221;</strong>, add the item to their cart, go through checkout, enter payment details, and then hit a hard wall: <em>&#8220;Sorry, this item is no longer available.&#8221;</em></p><p><em>"We're a technology company losing revenue because of a 30-second cache."<br>- Someone's post-mortem, probably.</em></p><p>You tore out the TTL-based invalidation and replaced it with event-driven invalidation. Every purchase, restock, and cancellation published an <code>inventory.changed</code> event. The cache entry died the moment the stock did.</p><p><em>Caches are not slower databases. They are temporary agreements about what truth looks like. When the underlying truth changes, the agreement is void.</em></p><p><strong>Lesson: In some systems, correctness beats speed. If the cost of a stale read is a user who can't trust your product - kill stale entries the moment the source of truth changes.</strong></p><div><hr></div><p><em>The Boundary Rule</em></p><h2>7) If two services share a DB &#8594; they&#8217;re one service wearing two badges</h2><p>I watched a team celebrate their &#8220;microservices migration.&#8221; They had split their monolith into a <strong>User Service</strong> and an <strong>Account Service</strong>. Two repos. Two deploy pipelines. Two Slack channels for on-call. Everyone felt modern.</p><p>Both services read and wrote to the same <code>users</code> table in the same database.</p><p><strong>What happened every schema change</strong></p><ul><li><p>&#8220;We need to rename this column&#8221; &#8594; 2 PRs, 2 code reviews, 2 test suites</p></li><li><p>Migration runs &#8594; sometimes only one service gets the update</p></li><li><p>Rollback one &#8594; breaks the other</p></li><li><p>Neither team wants to own the migration; both blame the other</p></li></ul><p>This isn&#8217;t a microservices architecture. It&#8217;s a distributed monolith - all the operational complexity of microservices, none of the data isolation benefits.</p><p>A real service boundary is defined by <strong>data ownership</strong>, not repository count. If you can&#8217;t change one service&#8217;s schema without modifying the other - they are one service. Merge them, or properly separate the data.</p><p><strong>Lesson: Shared data = shared fate. You can have separate codebases and still be a monolith at the data layer. True microservices have strict data ownership - not just separate repos.</strong></p><blockquote><p><em>Before you read further</em></p><p><em>I write content like this in much more depth on <strong><a href="https://theskilledcoder.com">Skilled Coder</a></strong></em></p><ul><li><p><em>150+ Handpicked DSA problems</em></p></li><li><p><em>Complete System Design Roadmap and 40+ HLD deep dives</em></p></li><li><p><em>Complete LLD topics with Practical classical problems approaches </em></p></li><li><p><em>Complete SQL + Data Engineering</em></p></li><li><p><em>End to End Java Interview Preparation</em></p></li><li><p><em>New Agentic AI foundation<br> </em></p><p><em>Single Library. Yours forever &#8594; <a href="https://theskilledcoder.com/">theskilledcoder.com</a></em></p></li></ul></blockquote><div><hr></div><p><em>The Root Cause Rule</em></p><h2><em> </em>8)<em> </em>If &#8220;just one more index&#8221; fixes it &#8594; fix the query shape, not the hardware.</h2><p>A dashboard at a fintech startup kept timing out. The on-call rotation for that feature was becoming someone&#8217;s full-time job.</p><p>The first engineer added an index. Fast again. Everyone cheered.</p><p>A month later, another slow query - another index. Then another. Then another. Six months in, the <code>transactions</code> table had 14 indexes. Write operations noticeably slowed down because every insert was now maintaining 14 separate B-trees.</p><p><em>&#8220;We didn&#8217;t have a query problem. We had an index addiction.&#8221;</em></p><p>You finally sat down and profiled the queries seriously. Here&#8217;s what you found:</p><p><strong>The actual problems, none of which needed an index</strong></p><ul><li><p>Query joined on a non-selective UUID column (wrong join key)</p></li><li><p>Filtered on <code>status</code> - only 3 possible values over 50M rows</p></li><li><p><code>SELECT *</code> fetching 40 columns when the UI used 4</p></li><li><p>Wildcard <code>LIKE '%keyword%'</code> preventing index usage anyway</p></li></ul><p>Now rewrote the queries. Dropped 9 of the 14 indexes. Performance improved. Write throughput improved.</p><p><em><strong>How to actually fix it:</strong> Run </em><code>EXPLAIN ANALYZE</code><em>. Look for sequential scans on large tables. Fix the join key first. Then selectivity. Then column projection. Indexes are the last resort.</em></p><p><strong>Lesson: Indexes are a bandaid. Query shape is the cure. Before adding another index, ask what the query is actually doing - and whether it should be doing it at all.</strong></p><div><hr></div><p><em>The Courage Rule</em></p><h2>9) If every feature needs a flag &#8594; your release process is broken, not your code</h2><p>You built a new onboarding flow. Clean design, better UX, everyone was proud of it. But to &#8220;reduce risk,&#8221; every step got wrapped in a feature flag.</p><p><strong>The flag graveyard, after 6 weeks</strong></p><ul><li><p><code>show_new_onboarding_form</code> - on in prod, off in staging (no one knows why)</p></li><li><p><code>enable_new_analytics_events</code> - on, but the dashboard reading them is off</p></li><li><p><code>new_validation_rules</code> - off, because of a bug that was fixed 3 weeks ago</p></li><li><p><code>enable_final_submission</code> - nobody remembers what this was for</p></li></ul><p>Toggling flags for each deploy was its own ceremony. QA had to test every flag combination. New engineers asked which flags were &#8220;safe&#8221; and got answers like: <em>&#8220;...probably these ones?&#8221;</em></p><p><em>&#8220;We thought we were being safe. We were being afraid.&#8221;</em></p><p>The fix wasn&#8217;t better flag naming. It was fixing the conditions that made you afraid to ship without them. Once you had proper automated tests, proper staging parity, and gradual rollout infrastructure - you deleted most of the flags and never looked back.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BBN1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d6cc599-db08-4d2f-809b-1bcf6a3ea68b_1568x332.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BBN1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d6cc599-db08-4d2f-809b-1bcf6a3ea68b_1568x332.png 424w, https://substackcdn.com/image/fetch/$s_!BBN1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d6cc599-db08-4d2f-809b-1bcf6a3ea68b_1568x332.png 848w, https://substackcdn.com/image/fetch/$s_!BBN1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d6cc599-db08-4d2f-809b-1bcf6a3ea68b_1568x332.png 1272w, https://substackcdn.com/image/fetch/$s_!BBN1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d6cc599-db08-4d2f-809b-1bcf6a3ea68b_1568x332.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BBN1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d6cc599-db08-4d2f-809b-1bcf6a3ea68b_1568x332.png" width="1456" height="308" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6d6cc599-db08-4d2f-809b-1bcf6a3ea68b_1568x332.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:308,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:84410,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/189964132?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d6cc599-db08-4d2f-809b-1bcf6a3ea68b_1568x332.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!BBN1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d6cc599-db08-4d2f-809b-1bcf6a3ea68b_1568x332.png 424w, https://substackcdn.com/image/fetch/$s_!BBN1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d6cc599-db08-4d2f-809b-1bcf6a3ea68b_1568x332.png 848w, https://substackcdn.com/image/fetch/$s_!BBN1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d6cc599-db08-4d2f-809b-1bcf6a3ea68b_1568x332.png 1272w, https://substackcdn.com/image/fetch/$s_!BBN1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d6cc599-db08-4d2f-809b-1bcf6a3ea68b_1568x332.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><strong>Lesson: Feature flags are tools for confidence - not substitutes for it. If everything needs a flag, invest in your test coverage and your deploy pipeline. Ship with intent, not with hedges.</strong></p><div><hr></div><p>The best engineers aren&#8217;t the ones who never break things.<br>They&#8217;re the ones who break things once - and build something wiser in its place.</p><p><em>Every system scar is a lesson that no course could have taught you.</em></p><p><em>Thanks for reading :)</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/p/9-pieces-of-dev-wisdom-you-only-learn?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://newsletter.theskilledcoder.com/p/9-pieces-of-dev-wisdom-you-only-learn?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[How Do You Design a System Where Most Writes Will Never Be Read?]]></title><description><![CDATA[The Art of Storing Data You&#8217;ll Probably Never Look At]]></description><link>https://newsletter.theskilledcoder.com/p/how-do-you-design-a-system-where-a87</link><guid isPermaLink="false">https://newsletter.theskilledcoder.com/p/how-do-you-design-a-system-where-a87</guid><dc:creator><![CDATA[Skilled Coder]]></dc:creator><pubDate>Wed, 18 Feb 2026 08:51:41 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!UU5w!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a71e6b4-c7cd-4567-91dc-9d514d63c20d_2136x1224.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_!UU5w!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a71e6b4-c7cd-4567-91dc-9d514d63c20d_2136x1224.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UU5w!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a71e6b4-c7cd-4567-91dc-9d514d63c20d_2136x1224.png 424w, https://substackcdn.com/image/fetch/$s_!UU5w!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a71e6b4-c7cd-4567-91dc-9d514d63c20d_2136x1224.png 848w, https://substackcdn.com/image/fetch/$s_!UU5w!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a71e6b4-c7cd-4567-91dc-9d514d63c20d_2136x1224.png 1272w, https://substackcdn.com/image/fetch/$s_!UU5w!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a71e6b4-c7cd-4567-91dc-9d514d63c20d_2136x1224.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UU5w!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a71e6b4-c7cd-4567-91dc-9d514d63c20d_2136x1224.png" width="1456" height="834" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9a71e6b4-c7cd-4567-91dc-9d514d63c20d_2136x1224.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:834,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2730458,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/188356206?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a71e6b4-c7cd-4567-91dc-9d514d63c20d_2136x1224.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UU5w!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a71e6b4-c7cd-4567-91dc-9d514d63c20d_2136x1224.png 424w, https://substackcdn.com/image/fetch/$s_!UU5w!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a71e6b4-c7cd-4567-91dc-9d514d63c20d_2136x1224.png 848w, https://substackcdn.com/image/fetch/$s_!UU5w!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a71e6b4-c7cd-4567-91dc-9d514d63c20d_2136x1224.png 1272w, https://substackcdn.com/image/fetch/$s_!UU5w!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a71e6b4-c7cd-4567-91dc-9d514d63c20d_2136x1224.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><p>Your app just logged this:</p><pre><code>{
  "timestamp": "2024-01-15T14:32:47.892Z",
  "level": "INFO",
  "service": "checkout",
  "user_id": "u_8a7f3b",
  "action": "page_view",
  "page": "/products/shoes/running",
  "duration_ms": 47,
  "request_id": "req_9x8c7v6b"
}</code></pre><p>Will anyone ever read this log entry? Probably not.</p><p>But you still wrote it. Indexed it. Replicated it. Paid to store it. Along with the other 47<em> </em>million logs your system generated today.</p><p><em><strong>This is the paradox of write-mostly systems</strong>: You must capture everything while knowing almost nothing will be read. The question isn&#8217;t IF you should store it, but HOW you store data optimized for writing, not reading.</em></p><h3><strong>Write-Mostly Systems in the Wild</strong></h3><ul><li><p><strong>Application logs</strong>: 99.9% never viewed, critical for debugging that 0.1%</p></li><li><p><strong>Audit trails</strong>: Written for compliance, read only during audits</p></li><li><p><strong>Telemetry/metrics</strong>: Millions of data points, dashboards show aggregates</p></li><li><p><strong>Security events</strong>: Stored for forensics, queried during incidents</p></li><li><p><strong>IoT sensor data</strong>: Written constantly, analyzed in batches</p></li><li><p><strong>Backup/archive</strong>: Written once, hopefully never restored</p></li></ul><p>This chapter is about designing systems that optimize for write throughput, minimize storage costs, and still provide fast access to the tiny fraction of data you&#8217;ll actually need - without knowing which fraction that is.</p><h2><strong>The Fundamental Principle: Stop Paying for Reads You&#8217;ll Never Do</strong></h2><p>Every traditional database feature that speeds up reads has a cost at write time:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2245!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9e3af-22c7-4179-9e3c-a8f167ac1ad4_2420x1512.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2245!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9e3af-22c7-4179-9e3c-a8f167ac1ad4_2420x1512.png 424w, https://substackcdn.com/image/fetch/$s_!2245!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9e3af-22c7-4179-9e3c-a8f167ac1ad4_2420x1512.png 848w, https://substackcdn.com/image/fetch/$s_!2245!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9e3af-22c7-4179-9e3c-a8f167ac1ad4_2420x1512.png 1272w, https://substackcdn.com/image/fetch/$s_!2245!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9e3af-22c7-4179-9e3c-a8f167ac1ad4_2420x1512.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2245!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9e3af-22c7-4179-9e3c-a8f167ac1ad4_2420x1512.png" width="1456" height="910" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/81a9e3af-22c7-4179-9e3c-a8f167ac1ad4_2420x1512.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:910,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:442005,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/188356206?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9e3af-22c7-4179-9e3c-a8f167ac1ad4_2420x1512.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2245!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9e3af-22c7-4179-9e3c-a8f167ac1ad4_2420x1512.png 424w, https://substackcdn.com/image/fetch/$s_!2245!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9e3af-22c7-4179-9e3c-a8f167ac1ad4_2420x1512.png 848w, https://substackcdn.com/image/fetch/$s_!2245!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9e3af-22c7-4179-9e3c-a8f167ac1ad4_2420x1512.png 1272w, https://substackcdn.com/image/fetch/$s_!2245!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a9e3af-22c7-4179-9e3c-a8f167ac1ad4_2420x1512.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>If you&#8217;re writing millions of records that will rarely be queried, you&#8217;re paying the &#8220;read optimization tax&#8221; millions of times for essentially zero benefit.</p><h3><strong>Why We Ignore Traditional Database Design Here</strong></h3><p>Traditional databases optimize for balanced workloads. They assume you&#8217;ll query your data. For write-mostly systems, we deliberately break several &#8220;best practices&#8221;:</p><ul><li><p>No indexes at write time - We&#8217;ll build them later, if ever</p></li><li><p>Eventual consistency is fine - We don&#8217;t need immediate reads</p></li><li><p>Denormalization is expected - No joins means no foreign keys</p></li><li><p>Data loss is acceptable (sometimes) - Sampling reduces volume</p></li></ul><h2><strong>Principle 1: Append-Only Beats Random Writes</strong></h2><p>The fastest way to write data is to never update, only append. This isn&#8217;t just an optimization - it&#8217;s a fundamental shift in how we think about storage.</p><h3><strong>Why Append-Only is 10&#8211;100x Faster</strong></h3><p>Traditional databases do random writes: when you insert a row, it may go anywhere in the file based on indexes and ordering. This means:</p><ul><li><p>Disk seeks to find the right location</p></li><li><p>Page splits when blocks are full</p></li><li><p>Index rebalancing (B-tree rotations)</p></li><li><p>Transaction logging for each operation</p></li></ul><p>Append-only storage does sequential writes: new data always goes at the end. This means:</p><ul><li><p>No disk seeks (write head never moves backward)</p></li><li><p>No page management (just append to the end)</p></li><li><p>No index updates (we&#8217;re not indexing)</p></li><li><p>Batched logging (bulk commit)</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_!VvWG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F875d057f-b24e-44e0-b85d-a642e1b90711_2628x1176.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VvWG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F875d057f-b24e-44e0-b85d-a642e1b90711_2628x1176.png 424w, https://substackcdn.com/image/fetch/$s_!VvWG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F875d057f-b24e-44e0-b85d-a642e1b90711_2628x1176.png 848w, https://substackcdn.com/image/fetch/$s_!VvWG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F875d057f-b24e-44e0-b85d-a642e1b90711_2628x1176.png 1272w, https://substackcdn.com/image/fetch/$s_!VvWG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F875d057f-b24e-44e0-b85d-a642e1b90711_2628x1176.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VvWG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F875d057f-b24e-44e0-b85d-a642e1b90711_2628x1176.png" width="1456" height="652" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/875d057f-b24e-44e0-b85d-a642e1b90711_2628x1176.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:652,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1133402,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/188356206?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F875d057f-b24e-44e0-b85d-a642e1b90711_2628x1176.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VvWG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F875d057f-b24e-44e0-b85d-a642e1b90711_2628x1176.png 424w, https://substackcdn.com/image/fetch/$s_!VvWG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F875d057f-b24e-44e0-b85d-a642e1b90711_2628x1176.png 848w, https://substackcdn.com/image/fetch/$s_!VvWG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F875d057f-b24e-44e0-b85d-a642e1b90711_2628x1176.png 1272w, https://substackcdn.com/image/fetch/$s_!VvWG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F875d057f-b24e-44e0-b85d-a642e1b90711_2628x1176.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>Principle 2: Store by Column, Not by Row</strong></h2><p>This is perhaps the most counterintuitive principle. Why would storing data in columns instead of rows make such a difference for write-mostly systems?</p><h3><strong>The Compression Advantage</strong></h3><p>In row-based storage, each row contains mixed data types: timestamps, strings, numbers, booleans. Mixed data compresses poorly.</p><p>In columnar storage, each column contains the same type of data. And here&#8217;s the key insight: log data is highly repetitive within columns.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!c5rI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f1eaf9-f0c9-45f1-bdc0-e9938f2a545c_2646x1402.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!c5rI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f1eaf9-f0c9-45f1-bdc0-e9938f2a545c_2646x1402.png 424w, https://substackcdn.com/image/fetch/$s_!c5rI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f1eaf9-f0c9-45f1-bdc0-e9938f2a545c_2646x1402.png 848w, https://substackcdn.com/image/fetch/$s_!c5rI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f1eaf9-f0c9-45f1-bdc0-e9938f2a545c_2646x1402.png 1272w, https://substackcdn.com/image/fetch/$s_!c5rI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f1eaf9-f0c9-45f1-bdc0-e9938f2a545c_2646x1402.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!c5rI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f1eaf9-f0c9-45f1-bdc0-e9938f2a545c_2646x1402.png" width="1456" height="771" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/61f1eaf9-f0c9-45f1-bdc0-e9938f2a545c_2646x1402.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:771,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1089148,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/188356206?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f1eaf9-f0c9-45f1-bdc0-e9938f2a545c_2646x1402.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!c5rI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f1eaf9-f0c9-45f1-bdc0-e9938f2a545c_2646x1402.png 424w, https://substackcdn.com/image/fetch/$s_!c5rI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f1eaf9-f0c9-45f1-bdc0-e9938f2a545c_2646x1402.png 848w, https://substackcdn.com/image/fetch/$s_!c5rI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f1eaf9-f0c9-45f1-bdc0-e9938f2a545c_2646x1402.png 1272w, https://substackcdn.com/image/fetch/$s_!c5rI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f1eaf9-f0c9-45f1-bdc0-e9938f2a545c_2646x1402.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em><strong>Result</strong>: Columnar formats like Parquet achieve 10&#8211;50x compression on log data. What would be 500GB in JSON becomes 15&#8211;50GB in Parquet.</em></p><p><strong>Why This Matters for Costs</strong></p><p>At scale, storage dominates costs. Consider 1 billion logs per day:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Otng!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9277a1d-acf1-46b2-be7b-2e63609ee614_2622x818.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Otng!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9277a1d-acf1-46b2-be7b-2e63609ee614_2622x818.png 424w, https://substackcdn.com/image/fetch/$s_!Otng!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9277a1d-acf1-46b2-be7b-2e63609ee614_2622x818.png 848w, https://substackcdn.com/image/fetch/$s_!Otng!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9277a1d-acf1-46b2-be7b-2e63609ee614_2622x818.png 1272w, https://substackcdn.com/image/fetch/$s_!Otng!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9277a1d-acf1-46b2-be7b-2e63609ee614_2622x818.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Otng!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9277a1d-acf1-46b2-be7b-2e63609ee614_2622x818.png" width="1456" height="454" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d9277a1d-acf1-46b2-be7b-2e63609ee614_2622x818.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:454,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:469901,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/188356206?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9277a1d-acf1-46b2-be7b-2e63609ee614_2622x818.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Otng!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9277a1d-acf1-46b2-be7b-2e63609ee614_2622x818.png 424w, https://substackcdn.com/image/fetch/$s_!Otng!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9277a1d-acf1-46b2-be7b-2e63609ee614_2622x818.png 848w, https://substackcdn.com/image/fetch/$s_!Otng!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9277a1d-acf1-46b2-be7b-2e63609ee614_2622x818.png 1272w, https://substackcdn.com/image/fetch/$s_!Otng!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9277a1d-acf1-46b2-be7b-2e63609ee614_2622x818.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CxLg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcbe29d1-fb61-4dda-9d5b-b0e2059e0d93_2628x1138.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CxLg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcbe29d1-fb61-4dda-9d5b-b0e2059e0d93_2628x1138.png 424w, https://substackcdn.com/image/fetch/$s_!CxLg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcbe29d1-fb61-4dda-9d5b-b0e2059e0d93_2628x1138.png 848w, https://substackcdn.com/image/fetch/$s_!CxLg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcbe29d1-fb61-4dda-9d5b-b0e2059e0d93_2628x1138.png 1272w, https://substackcdn.com/image/fetch/$s_!CxLg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcbe29d1-fb61-4dda-9d5b-b0e2059e0d93_2628x1138.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CxLg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcbe29d1-fb61-4dda-9d5b-b0e2059e0d93_2628x1138.png" width="1456" height="630" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bcbe29d1-fb61-4dda-9d5b-b0e2059e0d93_2628x1138.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:630,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1038205,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/188356206?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcbe29d1-fb61-4dda-9d5b-b0e2059e0d93_2628x1138.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CxLg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcbe29d1-fb61-4dda-9d5b-b0e2059e0d93_2628x1138.png 424w, https://substackcdn.com/image/fetch/$s_!CxLg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcbe29d1-fb61-4dda-9d5b-b0e2059e0d93_2628x1138.png 848w, https://substackcdn.com/image/fetch/$s_!CxLg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcbe29d1-fb61-4dda-9d5b-b0e2059e0d93_2628x1138.png 1272w, https://substackcdn.com/image/fetch/$s_!CxLg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcbe29d1-fb61-4dda-9d5b-b0e2059e0d93_2628x1138.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>Principle 3: Data Value Decays Over Time</strong></h2><p>Here&#8217;s a truth about write-mostly data: its value decreases exponentially with age. Today&#8217;s logs are critical for debugging a live issue. Last month&#8217;s logs are useful for trend analysis. Last year&#8217;s logs exist only for compliance.</p><p>Yet most systems store all data the same way, paying hot-storage prices for data that&#8217;s essentially frozen.</p><h3><strong>Tiered Storage: Match Cost to Value</strong></h3><p>The principle is simple: move data to cheaper storage as it ages. Accept slower query times for data that&#8217;s rarely queried.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-ZR8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5930516b-bf1c-4866-84de-0ecebf799de3_2856x1490.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-ZR8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5930516b-bf1c-4866-84de-0ecebf799de3_2856x1490.png 424w, https://substackcdn.com/image/fetch/$s_!-ZR8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5930516b-bf1c-4866-84de-0ecebf799de3_2856x1490.png 848w, https://substackcdn.com/image/fetch/$s_!-ZR8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5930516b-bf1c-4866-84de-0ecebf799de3_2856x1490.png 1272w, https://substackcdn.com/image/fetch/$s_!-ZR8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5930516b-bf1c-4866-84de-0ecebf799de3_2856x1490.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-ZR8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5930516b-bf1c-4866-84de-0ecebf799de3_2856x1490.png" width="1456" height="760" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5930516b-bf1c-4866-84de-0ecebf799de3_2856x1490.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:760,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:992279,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/188356206?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5930516b-bf1c-4866-84de-0ecebf799de3_2856x1490.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-ZR8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5930516b-bf1c-4866-84de-0ecebf799de3_2856x1490.png 424w, https://substackcdn.com/image/fetch/$s_!-ZR8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5930516b-bf1c-4866-84de-0ecebf799de3_2856x1490.png 848w, https://substackcdn.com/image/fetch/$s_!-ZR8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5930516b-bf1c-4866-84de-0ecebf799de3_2856x1490.png 1272w, https://substackcdn.com/image/fetch/$s_!-ZR8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5930516b-bf1c-4866-84de-0ecebf799de3_2856x1490.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>The Hidden Cost: Retrieval Fees</strong></p><p>Cold storage is cheap to store but expensive to retrieve. Before archiving:</p><p>Glacier Instant: $0.03/GB retrieval</p><p>Deep Archive: $0.02/GB retrieval + 12-hour wait</p><p>Design implication: If you expect frequent ad-hoc queries on historical data, cold storage may cost more than warm storage. Do the math for YOUR access patterns.</p><h2><strong>Principle 4: Index Later, Not Sooner</strong></h2><p>Traditional databases index at write time because they assume you&#8217;ll query immediately. For write-mostly systems, this is backwards.</p><h3><strong>The Lazy Indexing Philosophy</strong></h3><p>Don&#8217;t index what you won&#8217;t search. Since 99% of your data won&#8217;t be queried, indexing 99% is waste. Instead:</p><ol><li><p>Write everything unindexed &#8212; Pure append, maximum speed</p></li><li><p>Index only high-value data &#8212; Errors, anomalies, specific transactions</p></li><li><p>Build indexes on-demand &#8212; When a query pattern emerges, create the index</p><p></p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NOEH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedfca6d3-4f0f-4d24-b15c-56de244aec89_1292x1626.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NOEH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedfca6d3-4f0f-4d24-b15c-56de244aec89_1292x1626.png 424w, https://substackcdn.com/image/fetch/$s_!NOEH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedfca6d3-4f0f-4d24-b15c-56de244aec89_1292x1626.png 848w, https://substackcdn.com/image/fetch/$s_!NOEH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedfca6d3-4f0f-4d24-b15c-56de244aec89_1292x1626.png 1272w, https://substackcdn.com/image/fetch/$s_!NOEH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedfca6d3-4f0f-4d24-b15c-56de244aec89_1292x1626.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NOEH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedfca6d3-4f0f-4d24-b15c-56de244aec89_1292x1626.png" width="1292" height="1626" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/edfca6d3-4f0f-4d24-b15c-56de244aec89_1292x1626.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1626,&quot;width&quot;:1292,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:451543,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/188356206?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedfca6d3-4f0f-4d24-b15c-56de244aec89_1292x1626.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!NOEH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedfca6d3-4f0f-4d24-b15c-56de244aec89_1292x1626.png 424w, https://substackcdn.com/image/fetch/$s_!NOEH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedfca6d3-4f0f-4d24-b15c-56de244aec89_1292x1626.png 848w, https://substackcdn.com/image/fetch/$s_!NOEH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedfca6d3-4f0f-4d24-b15c-56de244aec89_1292x1626.png 1272w, https://substackcdn.com/image/fetch/$s_!NOEH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedfca6d3-4f0f-4d24-b15c-56de244aec89_1292x1626.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Why this works</strong>: Modern columnar formats (Parquet) are surprisingly fast to scan. Querying 1 billion rows in a well-partitioned columnar dataset takes seconds, not hours. For rare queries, scanning beats the cost of maintaining indexes.</p><h2><strong>Principle 5: Accept That Some Data Can Be Lost</strong></h2><p>This is the most controversial principle. Traditional systems treat every record as sacred. But for many write-mostly use cases, statistical accuracy matters more than individual records.</p><h3><strong>When Sampling Makes Sense</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZdUm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ab6776-88e0-4775-aadd-8d1d2975326d_2200x1382.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZdUm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ab6776-88e0-4775-aadd-8d1d2975326d_2200x1382.png 424w, https://substackcdn.com/image/fetch/$s_!ZdUm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ab6776-88e0-4775-aadd-8d1d2975326d_2200x1382.png 848w, https://substackcdn.com/image/fetch/$s_!ZdUm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ab6776-88e0-4775-aadd-8d1d2975326d_2200x1382.png 1272w, https://substackcdn.com/image/fetch/$s_!ZdUm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ab6776-88e0-4775-aadd-8d1d2975326d_2200x1382.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZdUm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ab6776-88e0-4775-aadd-8d1d2975326d_2200x1382.png" width="1456" height="915" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/42ab6776-88e0-4775-aadd-8d1d2975326d_2200x1382.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:915,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1051250,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/188356206?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ab6776-88e0-4775-aadd-8d1d2975326d_2200x1382.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ZdUm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ab6776-88e0-4775-aadd-8d1d2975326d_2200x1382.png 424w, https://substackcdn.com/image/fetch/$s_!ZdUm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ab6776-88e0-4775-aadd-8d1d2975326d_2200x1382.png 848w, https://substackcdn.com/image/fetch/$s_!ZdUm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ab6776-88e0-4775-aadd-8d1d2975326d_2200x1382.png 1272w, https://substackcdn.com/image/fetch/$s_!ZdUm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42ab6776-88e0-4775-aadd-8d1d2975326d_2200x1382.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><blockquote><p>A 10% sample of 100 million events (10 million rows) gives you statistically valid results for almost any aggregate query. You save 90% of storage and processing costs.</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eNNT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cea3b4-55d5-4db5-b7e9-346b1be2d0d5_2198x878.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eNNT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cea3b4-55d5-4db5-b7e9-346b1be2d0d5_2198x878.png 424w, https://substackcdn.com/image/fetch/$s_!eNNT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cea3b4-55d5-4db5-b7e9-346b1be2d0d5_2198x878.png 848w, https://substackcdn.com/image/fetch/$s_!eNNT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cea3b4-55d5-4db5-b7e9-346b1be2d0d5_2198x878.png 1272w, https://substackcdn.com/image/fetch/$s_!eNNT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cea3b4-55d5-4db5-b7e9-346b1be2d0d5_2198x878.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eNNT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cea3b4-55d5-4db5-b7e9-346b1be2d0d5_2198x878.png" width="1456" height="582" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/37cea3b4-55d5-4db5-b7e9-346b1be2d0d5_2198x878.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:582,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:953673,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/188356206?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cea3b4-55d5-4db5-b7e9-346b1be2d0d5_2198x878.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!eNNT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cea3b4-55d5-4db5-b7e9-346b1be2d0d5_2198x878.png 424w, https://substackcdn.com/image/fetch/$s_!eNNT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cea3b4-55d5-4db5-b7e9-346b1be2d0d5_2198x878.png 848w, https://substackcdn.com/image/fetch/$s_!eNNT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cea3b4-55d5-4db5-b7e9-346b1be2d0d5_2198x878.png 1272w, https://substackcdn.com/image/fetch/$s_!eNNT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cea3b4-55d5-4db5-b7e9-346b1be2d0d5_2198x878.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><blockquote><p><strong>Related (Before you read further)</strong></p><p><em>This article scratched the surface. The real interview goes 10 levels deeper.</em></p><p><em>How do you handle hot partitions?</em></p><p><em>What if the cache goes down during a spike?</em></p><p><em>How do you handle compliance requirements?</em></p><p>You don&#8217;t need 10 scattered resources anymore to prepare.</p><p>I&#8217;ve put <strong>HLD, LLD, DSA, Java, DBMS + real system-design scenario </strong>like this article<strong> </strong>plus real system-design questions broken down the way they&#8217;re actually asked in interviews.</p><p><em><strong>&#128073; <a href="https://theskilledcoder.com/system-design-roadmap#systems">Check it out here</a></strong></em></p></blockquote><h2><strong>Putting It Together: The Write-Mostly Architecture</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vFsR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff19a84b5-3fa0-4387-9ecb-19e4ef7a468f_566x1212.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vFsR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff19a84b5-3fa0-4387-9ecb-19e4ef7a468f_566x1212.webp 424w, https://substackcdn.com/image/fetch/$s_!vFsR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff19a84b5-3fa0-4387-9ecb-19e4ef7a468f_566x1212.webp 848w, https://substackcdn.com/image/fetch/$s_!vFsR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff19a84b5-3fa0-4387-9ecb-19e4ef7a468f_566x1212.webp 1272w, https://substackcdn.com/image/fetch/$s_!vFsR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff19a84b5-3fa0-4387-9ecb-19e4ef7a468f_566x1212.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vFsR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff19a84b5-3fa0-4387-9ecb-19e4ef7a468f_566x1212.webp" width="566" height="1212" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f19a84b5-3fa0-4387-9ecb-19e4ef7a468f_566x1212.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1212,&quot;width&quot;:566,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:16374,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/188356206?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff19a84b5-3fa0-4387-9ecb-19e4ef7a468f_566x1212.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vFsR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff19a84b5-3fa0-4387-9ecb-19e4ef7a468f_566x1212.webp 424w, https://substackcdn.com/image/fetch/$s_!vFsR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff19a84b5-3fa0-4387-9ecb-19e4ef7a468f_566x1212.webp 848w, https://substackcdn.com/image/fetch/$s_!vFsR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff19a84b5-3fa0-4387-9ecb-19e4ef7a468f_566x1212.webp 1272w, https://substackcdn.com/image/fetch/$s_!vFsR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff19a84b5-3fa0-4387-9ecb-19e4ef7a468f_566x1212.webp 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3><strong>Case: When NOT to Use These Patterns</strong></h3><p><strong>Don&#8217;t Apply Write-Mostly Patterns When:</strong></p><ul><li><p><strong>You need immediate reads</strong>: User activity feeds, real-time analytics where users see their own data</p></li><li><p><strong>Data requires updates</strong>: Status tracking, state machines, records that change over time</p></li><li><p><strong>Query patterns are unpredictable</strong>: BI tools where users slice data in arbitrary ways</p></li><li><p><strong>Consistency matters</strong>: Financial ledgers, inventory counts, anything where &#8220;eventually consistent&#8221; isn&#8217;t acceptable</p></li></ul><h2><strong>What&#8217;s Next?</strong></h2><p>This problem can have variety of follow up questions</p><ul><li><p>How do you query data across tiers?</p></li><li><p>What if you need to find a specific log entry?</p></li><li><p>How do you handle compliance requirements?</p></li><li><p>How do you decide retention periods?</p></li></ul><p>We&#8217;ll cover similar real-world scenarios in upcoming articles or resource mentioned above.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/p/how-do-you-design-a-system-where-a87?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://newsletter.theskilledcoder.com/p/how-do-you-design-a-system-where-a87?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Signs You’re Thinking Like an Architect, Not Just a Developer]]></title><description><![CDATA[How seasoned engineers evolve from builders to visionaries]]></description><link>https://newsletter.theskilledcoder.com/p/signs-youre-thinking-like-an-architect</link><guid isPermaLink="false">https://newsletter.theskilledcoder.com/p/signs-youre-thinking-like-an-architect</guid><dc:creator><![CDATA[Skilled Coder]]></dc:creator><pubDate>Sat, 31 Jan 2026 15:18:11 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1637073849667-91120a924221?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxkZXZlbG9wZXJzfGVufDB8fHx8MTc2OTg3MjI4OXww&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080" 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://images.unsplash.com/photo-1637073849667-91120a924221?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxkZXZlbG9wZXJzfGVufDB8fHx8MTc2OTg3MjI4OXww&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://images.unsplash.com/photo-1637073849667-91120a924221?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxkZXZlbG9wZXJzfGVufDB8fHx8MTc2OTg3MjI4OXww&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1637073849667-91120a924221?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxkZXZlbG9wZXJzfGVufDB8fHx8MTc2OTg3MjI4OXww&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1637073849667-91120a924221?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxkZXZlbG9wZXJzfGVufDB8fHx8MTc2OTg3MjI4OXww&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1637073849667-91120a924221?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxkZXZlbG9wZXJzfGVufDB8fHx8MTc2OTg3MjI4OXww&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080 1456w" sizes="100vw"><img src="https://images.unsplash.com/photo-1637073849667-91120a924221?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxkZXZlbG9wZXJzfGVufDB8fHx8MTc2OTg3MjI4OXww&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080" width="5616" height="3744" data-attrs="{&quot;src&quot;:&quot;https://images.unsplash.com/photo-1637073849667-91120a924221?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxkZXZlbG9wZXJzfGVufDB8fHx8MTc2OTg3MjI4OXww&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:3744,&quot;width&quot;:5616,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;two men sitting in front of a laptop computer&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpg&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="two men sitting in front of a laptop computer" title="two men sitting in front of a laptop computer" srcset="https://images.unsplash.com/photo-1637073849667-91120a924221?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxkZXZlbG9wZXJzfGVufDB8fHx8MTc2OTg3MjI4OXww&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1637073849667-91120a924221?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxkZXZlbG9wZXJzfGVufDB8fHx8MTc2OTg3MjI4OXww&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1637073849667-91120a924221?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxkZXZlbG9wZXJzfGVufDB8fHx8MTc2OTg3MjI4OXww&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1637073849667-91120a924221?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxkZXZlbG9wZXJzfGVufDB8fHx8MTc2OTg3MjI4OXww&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@flipsnack">Flipsnack</a> on <a href="https://unsplash.com">Unsplash</a></figcaption></figure></div><p>There&#8217;s a quiet shift that happens as you grow in your engineering career.<br>You stop asking <em>&#8220;How do I make this work?&#8221;</em> and start asking <em>&#8220;What happens when this breaks?&#8221;</em></p><p>You begin to care less about clever one-liners of code and more about how a thousand moving parts talk to each other.<br>That&#8217;s when you stop thinking like &#8220;a developer&#8221; and start thinking like &#8220;an architect.&#8221;</p><p>Let&#8217;s look at the signs</p><div><hr></div><h3><strong>1. You Think in Terms of Flows, Not Just Functions</strong></h3><p>Early in your career, you zoom into individual functions.<br>But an architect zooms out asking, <em>&#8220;Where does this data go next? Who depends on it? What triggers it?&#8221;</em></p><p>A developer builds a &#8220;Send Invoice&#8221; function.<br>An architect asks, &#8220;When the invoice is sent, should we trigger a notification to finance? Should we update billing metrics? Should retries kick in if email fails?&#8221;</p><p>Architects see flows, not functions. They think in systems, not snippets.</p><h3><strong>2. You Optimize for Long-Term Change, Not Short-Term Speed</strong></h3><p>A developer says, &#8220;Let&#8217;s hack this and ship fast.&#8221;<br>An architect says, &#8220;This quick hack will haunt us every quarter.&#8221;</p><p>It&#8217;s not about slowing down it&#8217;s about building momentum that doesn&#8217;t collapse later.</p><p>You could hardcode a config today and save 30 minutes.<br>But you know six months later, marketing will need to change it weekly.<br>So you externalize it now. Because shipping fast is great shipping clean is better.</p><h3><strong>3. You Ask: &#8220;What Happens If It Fails?&#8221;</strong></h3><p>This is a big mindset jump.</p><p>When designing a feature, you&#8217;re not done when it works.<br>You&#8217;re done when you know what happens when it doesn&#8217;t.</p><p>You design a payment flow. An architect asks:</p><ul><li><p>What if payment API times out?</p></li><li><p>What if webhook retries twice?</p></li><li><p>What if user closes browser mid-transaction?</p></li></ul><p>You plan graceful degradation not graceful ignorance.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://newsletter.theskilledcoder.com/subscribe?"><span>Subscribe now</span></a></p><p></p><h3><strong>4. You Embrace Constraints, Not Just Features</strong></h3><p>Architects don&#8217;t see constraints as blockers. They see them as design boundaries.</p><p>You&#8217;re building a search API.<br>You don&#8217;t say, &#8220;We&#8217;ll return all results.&#8221;<br>You say, &#8220;We have a 200ms SLA and a 100MB memory cap how do we stay inside that box?&#8221;</p><p>Real-world architecture is art within limits, not freedom without trade-offs.</p><h3><strong>5. You Design for Team Boundaries, Not Just Code Boundaries</strong></h3><p>Good code is modular.<br>Great architecture is organizationally modular.</p><p>If 3 teams touch the same service to deploy, you&#8217;ve built a bottleneck, not a service.<br>Architects design for ownership so teams can ship without stepping on each other&#8217;s toes.</p><p>Clean boundaries create independent velocity.</p><h3><strong>6. You Think in Contracts &amp; Interfaces</strong></h3><p>In an architect&#8217;s world, APIs are contracts, not handshakes.<br>You don&#8217;t just say &#8220;call this endpoint&#8221; you define what&#8217;s guaranteed, what&#8217;s optional, and what&#8217;s versioned.</p><p>When you change a field name in a schema, you don&#8217;t &#8220;just fix it&#8221; you create a new version.<br>Because backward compatibility isn&#8217;t optional it&#8217;s respect for other systems.</p><h3><strong>7. You Separate What Changes from What Doesn&#8217;t</strong></h3><p>Architects spot volatility early.<br>They ask: &#8220;What&#8217;s likely to change?&#8221; and isolate it.</p><p>If your pricing logic keeps changing, don&#8217;t bury it deep inside order processing.<br>Put it in a strategy layer or a config-driven rule so the rest of the system stays stable.</p><p>It&#8217;s not about predicting the future. It&#8217;s about shielding yourself from it.</p><h3><strong>8. You Question Dependencies Before Adding Them</strong></h3><p>Every new library is a future meeting with your past self.<br>Architects ask: &#8220;Will this still be maintained in 2 years? Does it fit our stack? Can we remove it easily?&#8221;</p><p>You might pick a fancy caching library today but if it blocks Java 22 migration later, was it worth it?</p><p>Architects treat dependencies like guests, not roommates.</p><h3><strong>9. You Build for Observability Upfront</strong></h3><p>If a system fails and nobody can explain why, that&#8217;s not a bug that&#8217;s bad design.</p><p>You don&#8217;t add logs after an outage. You design with logs, metrics, and traces from day one.<br>You know every critical path should leave breadcrumbs.</p><p>Because good systems talk back when they&#8217;re in trouble.</p><h3><strong>10. You Default to Asynchronous Where It Makes Sense</strong></h3><p>Architects understand the power of decoupling.</p><p>Instead of making a user wait for an email to send, you enqueue a job.<br>Instead of chaining 5 API calls, you publish an event and let subscribers act.</p><p>You build for scale, not sequence.</p><h3><strong>11. You Care About Data Contracts</strong></h3><p>Data isn&#8217;t &#8220;just stored&#8221; it&#8217;s a living interface between services.</p><p>You don&#8217;t just alter a table column. You think:</p><ul><li><p>What breaks downstream ETL?</p></li><li><p>Are old events still valid?</p></li><li><p>Should I add a new column instead of mutating old one?</p></li></ul><p>Architects know data is forever, so they tread carefully.</p><h3><strong>12. You Minimize Coordination, Not Just Code</strong></h3><p>Architecture isn&#8217;t about reducing lines of code it&#8217;s about reducing lines of communication.</p><p>If two teams need a sync meeting every time they deploy, your design failed.<br>Independent deployability &gt; shared spreadsheets.</p><p>You aim for loosely coupled teams, not just loosely coupled code.</p><h3><strong>13. You Think in Layers</strong></h3><p>Architects layer systems like cities:</p><ul><li><p><strong>Infrastructure</strong> &#8594; Roads</p></li><li><p><strong>Business logic</strong> &#8594; Buildings</p></li><li><p><strong>Interfaces</strong> &#8594; Doors &amp; Windows</p></li><li><p><strong>Observability</strong> &#8594; CCTV</p></li></ul><p>Each layer has purpose, boundaries, and rules. You don&#8217;t mix roads with roofs.</p><p>Your logging config doesn&#8217;t live in your controller logic it lives where it belongs: infra.</p><h3><strong>14. You Know Simplicity Is the Hardest Part</strong></h3><p>Anyone can add complexity.<br>Architects earn their stripes by removing it.</p><p>You resist the urge to use 4 queues, 3 caches, and a quantum database.<br>You ask, &#8220;Can this be a cron job instead?&#8221;</p><p>Because elegance isn&#8217;t about how much you can build it&#8217;s about how little you need to.</p><div><hr></div><p>Becoming an architect isn&#8217;t a title. It&#8217;s a mindset.</p><p>It&#8217;s when you stop thinking about features and start thinking about systems.<br>It&#8217;s when you stop coding for today&#8217;s demo and start designing for tomorrow&#8217;s change.</p><blockquote><p><em><strong>Related</strong></em></p><p><em>If you enjoy digging into how things actually work, I&#8217;ve been working on something larger.</em></p><p><em>I wrote an ebook that walks through <strong>35 real engineering problems and system designs</strong>, focusing on how decisions break down at scale, what trade-offs actually matter, and the kinds of follow-up questions engineers run into in interviews and real systems.</em></p><p><em>It&#8217;s less about memorizing solutions, and more about learning the <strong>principles behind solving problems at scale</strong> - so you can reason through new situations, not just familiar ones.</em></p><p><em><strong>&#128073; <a href="https://skilledcoder.gumroad.com/l/system-design">Check it out here</a></strong></em></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/p/signs-youre-thinking-like-an-architect?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://newsletter.theskilledcoder.com/p/signs-youre-thinking-like-an-architect?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[How Do You Design a System Where Reads Are Cheap But Writes Are Expensive?]]></title><description><![CDATA[The Art of Trading Write Complexity for Read Speed]]></description><link>https://newsletter.theskilledcoder.com/p/how-do-you-design-a-system-where</link><guid isPermaLink="false">https://newsletter.theskilledcoder.com/p/how-do-you-design-a-system-where</guid><dc:creator><![CDATA[Skilled Coder]]></dc:creator><pubDate>Tue, 13 Jan 2026 13:35:49 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!enWv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5459b78-3e33-4e91-9c61-a937f22a4b49_1370x602.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_!enWv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5459b78-3e33-4e91-9c61-a937f22a4b49_1370x602.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!enWv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5459b78-3e33-4e91-9c61-a937f22a4b49_1370x602.png 424w, https://substackcdn.com/image/fetch/$s_!enWv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5459b78-3e33-4e91-9c61-a937f22a4b49_1370x602.png 848w, https://substackcdn.com/image/fetch/$s_!enWv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5459b78-3e33-4e91-9c61-a937f22a4b49_1370x602.png 1272w, https://substackcdn.com/image/fetch/$s_!enWv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5459b78-3e33-4e91-9c61-a937f22a4b49_1370x602.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!enWv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5459b78-3e33-4e91-9c61-a937f22a4b49_1370x602.png" width="1370" height="602" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b5459b78-3e33-4e91-9c61-a937f22a4b49_1370x602.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:602,&quot;width&quot;:1370,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:182860,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/184432548?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5459b78-3e33-4e91-9c61-a937f22a4b49_1370x602.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!enWv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5459b78-3e33-4e91-9c61-a937f22a4b49_1370x602.png 424w, https://substackcdn.com/image/fetch/$s_!enWv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5459b78-3e33-4e91-9c61-a937f22a4b49_1370x602.png 848w, https://substackcdn.com/image/fetch/$s_!enWv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5459b78-3e33-4e91-9c61-a937f22a4b49_1370x602.png 1272w, https://substackcdn.com/image/fetch/$s_!enWv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5459b78-3e33-4e91-9c61-a937f22a4b49_1370x602.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><p>Taylor Swift posts a single tweet: &#8220;<em>New album at midnight</em>&#8221;</p><p>That&#8217;s one write. One row inserted.</p><p>Within 30 seconds, 90 million followers need to see it in their timeline. That&#8217;s 90 million reads. For every single tweet.</p><blockquote><p><em>When reads outnumber writes 1000:1, you can&#8217;t afford to compute anything at read time. The answer must already be waiting.</em></p></blockquote><p>This chapter is about systems where you intentionally make writes slow and expensive so that reads become blazingly fast.</p><p>The economics are simple: if you read 1000x more than you write, spend 1000x more effort on the write.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.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">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></p><div><hr></div><h2><strong>First Attempts (and Why They Don&#8217;t Scale)</strong></h2><h3><strong>Attempt 1: Query at Read Time</strong></h3><pre><code>-- Get user&#8217;s feed: JOIN everything at read time
SELECT posts.*
FROM posts
JOIN follows ON posts.author_id = follows.following_id
WHERE follows.follower_id = :user_id
ORDER BY posts.created_at DESC
LIMIT 50;</code></pre><p><em>Why it seems right:</em></p><ul><li><p>Normalized data - no duplication</p></li><li><p>Always fresh - up to the second</p></li><li><p>Simple to understand</p></li></ul><p><em>Why it fails at scale:</em></p><ul><li><p>Massive JOINs: User follows 500 people &#215; 100 posts each = scanning 50,000 rows</p></li><li><p>Repeated work: 10 users follow the same celebrity? Same computation 10 times</p></li><li><p>Read latency: 200ms+ per request when database is under load</p></li><li><p>Database meltdown: Can&#8217;t scale reads without replication lag issues</p></li></ul><h3><strong>Attempt 2: Add a Cache</strong></h3><pre><code>def get_feed(user_id):
    cached = redis.get(f&#8221;feed:{user_id}&#8221;)
    if cached:
        return cached
    
    # Cache miss - do the expensive query
    feed = expensive_feed_query(user_id)
    redis.setex(f&#8221;feed:{user_id}&#8221;, 300, feed)  # 5 min TTL
    return feed</code></pre><p><em>Why it fails:</em></p><ul><li><p>Cache stampede: When cache expires, 1000 users hit DB simultaneously</p></li><li><p>Stale data: New posts don&#8217;t appear for 5 minutes</p></li><li><p>Cold start: New users or cache eviction = slow first load</p></li><li><p>The underlying problem persists: Still doing the expensive query, just less often</p></li></ul><blockquote><p><em><strong>The Cache is a Band-aid : </strong>Caching a slow query doesn&#8217;t fix the query. It just hides the problem&#8230; until the cache misses. The real solution is to never run the slow query at all.</em></p></blockquote><div><hr></div><h2><strong>The Patterns That Actually Work</strong></h2><h3><strong>Pattern 1: Fan-Out on Write</strong></h3><p>Instead of computing the feed at read time, push posts to followers at write time.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ggfx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F319f11a4-75d6-4d97-ac45-2dc8eac80dab_1360x1510.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ggfx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F319f11a4-75d6-4d97-ac45-2dc8eac80dab_1360x1510.png 424w, https://substackcdn.com/image/fetch/$s_!Ggfx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F319f11a4-75d6-4d97-ac45-2dc8eac80dab_1360x1510.png 848w, https://substackcdn.com/image/fetch/$s_!Ggfx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F319f11a4-75d6-4d97-ac45-2dc8eac80dab_1360x1510.png 1272w, https://substackcdn.com/image/fetch/$s_!Ggfx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F319f11a4-75d6-4d97-ac45-2dc8eac80dab_1360x1510.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ggfx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F319f11a4-75d6-4d97-ac45-2dc8eac80dab_1360x1510.png" width="1360" height="1510" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/319f11a4-75d6-4d97-ac45-2dc8eac80dab_1360x1510.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1510,&quot;width&quot;:1360,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:287210,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/184432548?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F319f11a4-75d6-4d97-ac45-2dc8eac80dab_1360x1510.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Ggfx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F319f11a4-75d6-4d97-ac45-2dc8eac80dab_1360x1510.png 424w, https://substackcdn.com/image/fetch/$s_!Ggfx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F319f11a4-75d6-4d97-ac45-2dc8eac80dab_1360x1510.png 848w, https://substackcdn.com/image/fetch/$s_!Ggfx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F319f11a4-75d6-4d97-ac45-2dc8eac80dab_1360x1510.png 1272w, https://substackcdn.com/image/fetch/$s_!Ggfx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F319f11a4-75d6-4d97-ac45-2dc8eac80dab_1360x1510.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Trade-offs:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4g5N!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5dea641-2011-4e46-903a-995670c0893f_1346x434.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4g5N!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5dea641-2011-4e46-903a-995670c0893f_1346x434.png 424w, https://substackcdn.com/image/fetch/$s_!4g5N!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5dea641-2011-4e46-903a-995670c0893f_1346x434.png 848w, https://substackcdn.com/image/fetch/$s_!4g5N!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5dea641-2011-4e46-903a-995670c0893f_1346x434.png 1272w, https://substackcdn.com/image/fetch/$s_!4g5N!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5dea641-2011-4e46-903a-995670c0893f_1346x434.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4g5N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5dea641-2011-4e46-903a-995670c0893f_1346x434.png" width="1346" height="434" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a5dea641-2011-4e46-903a-995670c0893f_1346x434.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:434,&quot;width&quot;:1346,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:210923,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/184432548?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5dea641-2011-4e46-903a-995670c0893f_1346x434.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4g5N!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5dea641-2011-4e46-903a-995670c0893f_1346x434.png 424w, https://substackcdn.com/image/fetch/$s_!4g5N!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5dea641-2011-4e46-903a-995670c0893f_1346x434.png 848w, https://substackcdn.com/image/fetch/$s_!4g5N!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5dea641-2011-4e46-903a-995670c0893f_1346x434.png 1272w, https://substackcdn.com/image/fetch/$s_!4g5N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5dea641-2011-4e46-903a-995670c0893f_1346x434.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3><strong>Pattern 2: Hybrid Fan-Out (The Twitter Solution)</strong></h3><p>For celebrities with millions of followers, pure fan-out is too expensive. Solution: fan-out for regular users, pull for celebrities.</p><pre><code>def post_tweet(author_id, content):
    tweet = db.insert(author_id=author_id, content=content)
    follower_count = get_follower_count(author_id)
    
    if follower_count &lt; 10000:  # Regular user
        # Fan out to all followers
        for follower_id in get_followers(author_id):
            redis.lpush(f&#8221;feed:{follower_id}&#8221;, tweet.id)
    else:  # Celebrity - don&#8217;t fan out
        # Just mark the tweet as from a celebrity
        redis.sadd(&#8221;celebrity_tweets&#8221;, tweet.id)

def get_feed(user_id):
    # 1. Get pre-built feed (from regular users)
    feed = redis.lrange(f&#8221;feed:{user_id}&#8221;, 0, 50)
    
    # 2. Merge in celebrity tweets (computed at read time)
    celebrity_ids = get_followed_celebrities(user_id)
    for celeb_id in celebrity_ids:
        recent_tweets = get_recent_tweets(celeb_id)
        feed = merge_and_sort(feed, recent_tweets)
    
    return feed[:50]</code></pre><p><strong>Why this works</strong>: 99% of users have &lt; 10K followers. Fan-out handles them. The 1% of celebrities require a small read-time merge, which is acceptable.</p><h3><strong>Pattern 3: Denormalization</strong></h3><p>Store data redundantly so reads don&#8217;t require JOINs.</p><pre><code>// Normalized: Requires JOIN to get author name
{
  &#8220;post_id&#8221;: 123,
  &#8220;author_id&#8221;: 456,
  &#8220;content&#8221;: &#8220;Hello world&#8221;
}

// Denormalized: Everything needed is in one place
{
  &#8220;post_id&#8221;: 123,
  &#8220;author_id&#8221;: 456,
  &#8220;author_name&#8221;: &#8220;Taylor Swift&#8221;,
  &#8220;author_avatar&#8221;: &#8220;https://...&#8221;,
  &#8220;author_verified&#8221;: true,
  &#8220;content&#8221;: &#8220;Hello world&#8221;,
  &#8220;like_count&#8221;: 47000000,
  &#8220;reply_count&#8221;: 890000
}</code></pre><p><strong>The cost</strong>: When Taylor changes her avatar, you update millions of posts.</p><p><strong>The benefit</strong>: Every read is a single key lookup. No JOINs. Ever.</p><p><strong>When to Denormalize</strong></p><ul><li><p>Data is read 100x more than written</p></li><li><p>The denormalized fields rarely change (names, avatars)</p></li><li><p>Read latency is critical</p></li><li><p>You can tolerate eventual consistency (old avatar for a few minutes)</p></li></ul><h3><strong>Pattern 4: Materialized Views</strong></h3><p>Pre-compute and store query results. Update them when underlying data changes.</p><p><strong>Use cases:</strong></p><ul><li><p>Dashboard aggregations (daily sales, weekly signups)</p></li><li><p>Leaderboards (top sellers, trending content)</p></li><li><p>Recommendation scores (pre-computed similarity)</p></li></ul><pre><code>-- Create a materialized view of product stats
CREATE MATERIALIZED VIEW product_stats AS
SELECT 
    product_id,
    COUNT(*) AS review_count,
    AVG(rating) AS avg_rating,
    SUM(helpful_votes) AS total_helpful
FROM reviews
GROUP BY product_id;

-- Read: instant (no aggregation)
SELECT * FROM product_stats WHERE product_id = 123;

-- Refresh periodically or on trigger
REFRESH MATERIALIZED VIEW product_stats;</code></pre><h3><strong>Pattern 5: CQRS (Command Query Responsibility Segregation)</strong></h3><p>Separate the write model from the read model entirely. Two different databases, optimized for their specific purpose. (image in header)</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bX22!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe80be0-0de0-466b-a472-3e6c7a60e133_1346x554.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bX22!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe80be0-0de0-466b-a472-3e6c7a60e133_1346x554.png 424w, https://substackcdn.com/image/fetch/$s_!bX22!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe80be0-0de0-466b-a472-3e6c7a60e133_1346x554.png 848w, https://substackcdn.com/image/fetch/$s_!bX22!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe80be0-0de0-466b-a472-3e6c7a60e133_1346x554.png 1272w, https://substackcdn.com/image/fetch/$s_!bX22!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe80be0-0de0-466b-a472-3e6c7a60e133_1346x554.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bX22!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe80be0-0de0-466b-a472-3e6c7a60e133_1346x554.png" width="1346" height="554" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/abe80be0-0de0-466b-a472-3e6c7a60e133_1346x554.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:554,&quot;width&quot;:1346,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:247978,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/184432548?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe80be0-0de0-466b-a472-3e6c7a60e133_1346x554.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!bX22!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe80be0-0de0-466b-a472-3e6c7a60e133_1346x554.png 424w, https://substackcdn.com/image/fetch/$s_!bX22!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe80be0-0de0-466b-a472-3e6c7a60e133_1346x554.png 848w, https://substackcdn.com/image/fetch/$s_!bX22!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe80be0-0de0-466b-a472-3e6c7a60e133_1346x554.png 1272w, https://substackcdn.com/image/fetch/$s_!bX22!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe80be0-0de0-466b-a472-3e6c7a60e133_1346x554.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>The key insight</strong>: The read model is a projection. It can be deleted and rebuilt from the write model anytime. This frees you to optimize it purely for reads.</p><h3><strong>Architecture: Putting It Together</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nCQP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3de6f37-8335-49b8-989c-3bae98190aa7_842x1540.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nCQP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3de6f37-8335-49b8-989c-3bae98190aa7_842x1540.png 424w, https://substackcdn.com/image/fetch/$s_!nCQP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3de6f37-8335-49b8-989c-3bae98190aa7_842x1540.png 848w, https://substackcdn.com/image/fetch/$s_!nCQP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3de6f37-8335-49b8-989c-3bae98190aa7_842x1540.png 1272w, https://substackcdn.com/image/fetch/$s_!nCQP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3de6f37-8335-49b8-989c-3bae98190aa7_842x1540.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nCQP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3de6f37-8335-49b8-989c-3bae98190aa7_842x1540.png" width="618" height="1130.308788598575" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a3de6f37-8335-49b8-989c-3bae98190aa7_842x1540.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1540,&quot;width&quot;:842,&quot;resizeWidth&quot;:618,&quot;bytes&quot;:104228,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/184432548?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3de6f37-8335-49b8-989c-3bae98190aa7_842x1540.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!nCQP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3de6f37-8335-49b8-989c-3bae98190aa7_842x1540.png 424w, https://substackcdn.com/image/fetch/$s_!nCQP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3de6f37-8335-49b8-989c-3bae98190aa7_842x1540.png 848w, https://substackcdn.com/image/fetch/$s_!nCQP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3de6f37-8335-49b8-989c-3bae98190aa7_842x1540.png 1272w, https://substackcdn.com/image/fetch/$s_!nCQP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3de6f37-8335-49b8-989c-3bae98190aa7_842x1540.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>Data Flow: Write Path</h3><ol><li><p>User creates a post &#8594; write to primary database</p></li><li><p>Publish event to message queue</p></li><li><p>Fan-out worker: push to followers&#8217; feed caches</p></li><li><p>Denormalization worker: update cached objects with new data</p></li></ol><h3>Data Flow: Read Path</h3><ol><li><p>User opens app &#8594; hit CDN for static content</p></li><li><p>API request &#8594; check Redis cache first</p></li><li><p>Cache hit (99% of time) &#8594; return immediately</p></li><li><p>Cache miss &#8594; read from replica, populate cache, return</p></li></ol><h2>Interview Pivot (How to Explain It)</h2><p>If asked:</p><p><strong>&#8220;How do you design a system where reads are cheap but writes are expensive?&#8221;</strong></p><blockquote><p><em>&#8220;The core principle is to move computation from read time to write time. If data is read 1000x for every write, I should do the expensive work once during the write, not 1000 times during reads.</em></p><p><em>For a feed system, I&#8217;d use fan-out on write. When a user posts, I push the post ID to every follower&#8217;s pre-built feed list in Redis. Reads become a simple list retrieval - O(1) instead of complex JOINs.</em></p><p><em>For celebrities with millions of followers, I&#8217;d use hybrid fan-out: push for regular users, pull for celebrities. We merge celebrity tweets at read time, which is acceptable for the small percentage of celebrity follows.</em></p><p><em>I&#8217;d also denormalize aggressively. Store author name and avatar with every post so reads don&#8217;t require JOINs. Yes, updating a user&#8217;s avatar means updating millions of posts, but that&#8217;s a background job - it doesn&#8217;t affect read latency.</em></p><p><em>For complex aggregations, I&#8217;d use materialized views or CQRS - separate read and write models entirely. The read model is denormalized and optimized purely for query patterns. It&#8217;s eventually consistent with the write model, but for most use cases that&#8217;s fine.&#8221;</em></p></blockquote><h2><strong>What&#8217;s Next?</strong></h2><p>Every fast read is backed by expensive writes. There&#8217;s no magic - just a choice of when to pay the cost.</p><blockquote><p><em>For read-heavy systems, pay at write time. Pre-compute feeds, denormalize data, maintain materialized views. Your writes become complex, but your reads become trivial. And at 1000:1 read/write ratio, that&#8217;s exactly the trade you want.</em></p></blockquote><p><strong>Read-heavy systems lead to deeper questions:</strong></p><ul><li><p>How do you handle a user unfollowing someone?</p></li><li><p>What if the write model and read model get out of sync?</p></li><li><p>How do you handle a new user with no pre-built feed?</p></li><li><p>How much storage does fan-out actually use?</p></li></ul><p><strong>Related</strong></p><p><em>This article scratched the surface. The real interview goes 10 levels deeper.</em></p><ul><li><p><em>How do you handle hot partitions?</em></p></li><li><p><em>What if the cache goes down during a spike?</em></p></li><li><p><em>How do you avoid counting the same view twice?</em></p></li></ul><p><em>I&#8217;ve written an ebook that prepares you for <strong>all of it</strong>. (In detail with follow ups)</em></p><p><em>35 real problems. The patterns that solve them. The follow-ups you&#8217;ll actually face. The principles behind solving problems at scale, not just the final answers.</em></p><p><em><strong>&#128073; <a href="https://skilledcoder.gumroad.com/l/system-design">Check it out here</a></strong></em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/p/how-do-you-design-a-system-where?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://newsletter.theskilledcoder.com/p/how-do-you-design-a-system-where?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Stop Using Kafka Everywhere]]></title><description><![CDATA[when message queues save your system and when they quietly make everything worse]]></description><link>https://newsletter.theskilledcoder.com/p/stop-using-kafka-everywhere</link><guid isPermaLink="false">https://newsletter.theskilledcoder.com/p/stop-using-kafka-everywhere</guid><dc:creator><![CDATA[Skilled Coder]]></dc:creator><pubDate>Tue, 06 Jan 2026 08:17:37 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!8t1Q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3406ef38-3f3b-461e-b803-0b83af6e39d7_1410x1104.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_!8t1Q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3406ef38-3f3b-461e-b803-0b83af6e39d7_1410x1104.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8t1Q!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3406ef38-3f3b-461e-b803-0b83af6e39d7_1410x1104.png 424w, https://substackcdn.com/image/fetch/$s_!8t1Q!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3406ef38-3f3b-461e-b803-0b83af6e39d7_1410x1104.png 848w, https://substackcdn.com/image/fetch/$s_!8t1Q!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3406ef38-3f3b-461e-b803-0b83af6e39d7_1410x1104.png 1272w, https://substackcdn.com/image/fetch/$s_!8t1Q!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3406ef38-3f3b-461e-b803-0b83af6e39d7_1410x1104.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8t1Q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3406ef38-3f3b-461e-b803-0b83af6e39d7_1410x1104.png" width="1410" height="1104" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3406ef38-3f3b-461e-b803-0b83af6e39d7_1410x1104.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1104,&quot;width&quot;:1410,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1888487,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/183642532?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3406ef38-3f3b-461e-b803-0b83af6e39d7_1410x1104.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8t1Q!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3406ef38-3f3b-461e-b803-0b83af6e39d7_1410x1104.png 424w, https://substackcdn.com/image/fetch/$s_!8t1Q!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3406ef38-3f3b-461e-b803-0b83af6e39d7_1410x1104.png 848w, https://substackcdn.com/image/fetch/$s_!8t1Q!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3406ef38-3f3b-461e-b803-0b83af6e39d7_1410x1104.png 1272w, https://substackcdn.com/image/fetch/$s_!8t1Q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3406ef38-3f3b-461e-b803-0b83af6e39d7_1410x1104.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><p>Every engineering team reaches a moment where things start to creak. Requests spike unpredictably. Background jobs lag behind. One slow dependency begins dragging everything else down. That's usually the moment someone says: <strong>"Should we introduce Kafka?"</strong></p><p>Sometimes that suggestion saves the system. Other times, it quietly makes everything worse. To know the difference, you need to understand the fundamental principle behind message queues.</p><p>Before Kafka, before brokers and partitions, there is a simple truth: <strong>Different parts of a system run at different speeds.</strong> The moment you force them to move at the same pace, you create fragility.</p><p>Think about it this way: Your API server can accept 50,000 requests per second because it's just receiving data. But your database can only write 5,000 records per second because it needs to persist data to disk, maintain indexes, and ensure consistency. When you directly connect the fast component to the slow component, the slow one becomes a bottleneck that drags everything down.</p><p><strong>Queues exist to decouple time</strong>: Producers move fast, consumers move at their own pace, and the system survives bursts, failures, and change. Kafka is one powerful way to achieve this decoupling - but power only helps when you're solving the right problem.</p><div><hr></div><h2><strong>When You SHOULD Use Kafka</strong></h2><h3>1. When Producer Speed &#8800; Consumer Speed</h3><p>This is the most fundamental use case for any message queue, and it's where Kafka truly shines.</p><blockquote><p><em><strong>The Real-World Scenario:</strong> Imagine you&#8217;re running an e-commerce platform. Your API servers are designed to handle high concurrency - they accept HTTP requests, validate input, and return responses quickly. On a normal day, you might receive 50,000 requests per second during peak hours.</em></p><p><em>But here&#8217;s the problem: Your downstream systems aren&#8217;t that fast. Your database needs time to write records (disk I/O, index updates, replication). Your payment processor has rate limits. Your inventory service checks stock levels against a database. Each of these can only handle perhaps 5,000-10,000 operations per second.</em></p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Gz2o!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbecfb6d-217d-4b35-9089-11edc9640f74_1372x676.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Gz2o!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbecfb6d-217d-4b35-9089-11edc9640f74_1372x676.png 424w, https://substackcdn.com/image/fetch/$s_!Gz2o!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbecfb6d-217d-4b35-9089-11edc9640f74_1372x676.png 848w, https://substackcdn.com/image/fetch/$s_!Gz2o!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbecfb6d-217d-4b35-9089-11edc9640f74_1372x676.png 1272w, https://substackcdn.com/image/fetch/$s_!Gz2o!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbecfb6d-217d-4b35-9089-11edc9640f74_1372x676.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Gz2o!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbecfb6d-217d-4b35-9089-11edc9640f74_1372x676.png" width="1372" height="676" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fbecfb6d-217d-4b35-9089-11edc9640f74_1372x676.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:676,&quot;width&quot;:1372,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:80226,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/183642532?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbecfb6d-217d-4b35-9089-11edc9640f74_1372x676.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Gz2o!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbecfb6d-217d-4b35-9089-11edc9640f74_1372x676.png 424w, https://substackcdn.com/image/fetch/$s_!Gz2o!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbecfb6d-217d-4b35-9089-11edc9640f74_1372x676.png 848w, https://substackcdn.com/image/fetch/$s_!Gz2o!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbecfb6d-217d-4b35-9089-11edc9640f74_1372x676.png 1272w, https://substackcdn.com/image/fetch/$s_!Gz2o!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbecfb6d-217d-4b35-9089-11edc9640f74_1372x676.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7yr8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1726f59c-7117-4cfa-a40f-db0c9cd1b972_1384x596.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7yr8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1726f59c-7117-4cfa-a40f-db0c9cd1b972_1384x596.png 424w, https://substackcdn.com/image/fetch/$s_!7yr8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1726f59c-7117-4cfa-a40f-db0c9cd1b972_1384x596.png 848w, https://substackcdn.com/image/fetch/$s_!7yr8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1726f59c-7117-4cfa-a40f-db0c9cd1b972_1384x596.png 1272w, https://substackcdn.com/image/fetch/$s_!7yr8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1726f59c-7117-4cfa-a40f-db0c9cd1b972_1384x596.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7yr8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1726f59c-7117-4cfa-a40f-db0c9cd1b972_1384x596.png" width="1384" height="596" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1726f59c-7117-4cfa-a40f-db0c9cd1b972_1384x596.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:596,&quot;width&quot;:1384,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:130999,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/183642532?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1726f59c-7117-4cfa-a40f-db0c9cd1b972_1384x596.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7yr8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1726f59c-7117-4cfa-a40f-db0c9cd1b972_1384x596.png 424w, https://substackcdn.com/image/fetch/$s_!7yr8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1726f59c-7117-4cfa-a40f-db0c9cd1b972_1384x596.png 848w, https://substackcdn.com/image/fetch/$s_!7yr8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1726f59c-7117-4cfa-a40f-db0c9cd1b972_1384x596.png 1272w, https://substackcdn.com/image/fetch/$s_!7yr8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1726f59c-7117-4cfa-a40f-db0c9cd1b972_1384x596.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Kafka uses an append-only log structure. Writing to Kafka is essentially just appending bytes to a file, which is incredibly fast. Your API can acknowledge 50,000 requests per second because it's not waiting for slow downstream processing. The consumers then read from Kafka at whatever pace they can sustain.</p><blockquote><p><strong>Any time one side of your system is faster than the other, a queue acts as a buffer that absorbs the difference.</strong></p></blockquote><h3>2. When Traffic Spikes Are Unpredictable</h3><p>Some systems experience steady, predictable traffic. Others face dramatic spikes that can appear without warning. Kafka excels at the latter.</p><blockquote><p><em><strong>The Flash Sale Scenario:</strong> Your e-commerce platform announces a flash sale at noon. At 11:59, you're handling 1,000 requests per second. At 12:00:01, it jumps to 100,000 requests per second as eager shoppers rush to grab deals. Three minutes later, it's back to 5,000 requests per second.</em></p></blockquote><p><em><strong>More Examples like Flash Sales, Marketing Campaigns, OTP Generation, Push Notifications, Log Ingestion etc</strong></em></p><p><strong>Why This Is Hard:</strong> If you provision infrastructure for peak load (100K/sec), you're wasting 99% of your resources during normal operation. But if you provision for normal load, you'll crash during the spike.</p><p><strong>How Kafka Helps:</strong> During the spike, Kafka absorbs all 100,000 requests per second into its log. Yes, the queue depth grows temporarily. But your consumers keep processing at their steady 10K/sec rate. Within a few minutes after the spike ends, the queue drains back to normal.</p><p>Meanwhile, you can configure auto-scaling to add more consumers when queue depth increases, but this happens gradually over minutes - not the split-second response you&#8217;d need without a queue.</p><blockquote><p><em><strong>The Math</strong>: A 3-minute spike at 100K/sec produces 18 million messages. At 10K/sec consumption, it takes 30 minutes to clear. Your system survives because Kafka holds that buffer, not because you magically scaled 10x in milliseconds.</em></p></blockquote><h3>3. When Work Is Asynchronous by Nature</h3><p>Some operations don't need to complete before responding to the user. Making users wait for these operations is both bad UX and wasteful system design.</p><blockquote><p><em><strong>The Email Scenario</strong>: A user signs up for your service. You need to send a welcome email. Should the user stare at a loading spinner while your server connects to the SMTP server, composes the email, and waits for delivery confirmation?</em></p></blockquote><p><em><strong>Similarly for Push Notifications, Image/Video Processing, PDF Generation, Analytics Events</strong></em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!osI2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3ba763-a455-4391-9e8d-790d2a700b55_1362x394.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!osI2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3ba763-a455-4391-9e8d-790d2a700b55_1362x394.png 424w, https://substackcdn.com/image/fetch/$s_!osI2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3ba763-a455-4391-9e8d-790d2a700b55_1362x394.png 848w, https://substackcdn.com/image/fetch/$s_!osI2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3ba763-a455-4391-9e8d-790d2a700b55_1362x394.png 1272w, https://substackcdn.com/image/fetch/$s_!osI2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3ba763-a455-4391-9e8d-790d2a700b55_1362x394.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!osI2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3ba763-a455-4391-9e8d-790d2a700b55_1362x394.png" width="1362" height="394" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6a3ba763-a455-4391-9e8d-790d2a700b55_1362x394.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:394,&quot;width&quot;:1362,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:50747,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/183642532?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3ba763-a455-4391-9e8d-790d2a700b55_1362x394.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!osI2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3ba763-a455-4391-9e8d-790d2a700b55_1362x394.png 424w, https://substackcdn.com/image/fetch/$s_!osI2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3ba763-a455-4391-9e8d-790d2a700b55_1362x394.png 848w, https://substackcdn.com/image/fetch/$s_!osI2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3ba763-a455-4391-9e8d-790d2a700b55_1362x394.png 1272w, https://substackcdn.com/image/fetch/$s_!osI2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3ba763-a455-4391-9e8d-790d2a700b55_1362x394.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Why Sync is Wrong Here:</strong> Sending an email might take 1-3 seconds (DNS lookup, SMTP handshake, server response). That&#8217;s 1-3 seconds the user waits unnecessarily. Worse, if the email server is slow or down, the user&#8217;s signup fails - even though email delivery isn&#8217;t critical to completing signup.</p><p><strong>The Async Pattern:</strong> Your API pushes a &#8220;send welcome email&#8221; event to Kafka and immediately returns success to the user. A background worker picks up that event and handles the actual email sending. The user gets instant feedback, and the email arrives moments later.</p><blockquote><p><em><strong>If the user doesn't need the result immediately, don't make them wait. Push the work to a queue and respond instantly.</strong></em></p></blockquote><h3>4. When Reliability Matters More Than Speed</h3><p>Some events absolutely cannot be lost. A payment confirmation, an order placement, a financial transaction - these must be processed eventually, even if systems fail temporarily.</p><blockquote><p><em><strong>The Payment Scenario:</strong> A customer completes a payment. You need to: update their order status, send a confirmation email, notify the warehouse, update analytics, and trigger loyalty points. If any of these downstream services are down at that moment, what happens to the payment event?</em></p></blockquote><p><em><strong>More cases Order Confirmations, Financial Transactions, Audit Logs, Compliance Events</strong></em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!62i5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d406478-6889-43d8-accd-2a2744b4821b_1368x594.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!62i5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d406478-6889-43d8-accd-2a2744b4821b_1368x594.png 424w, https://substackcdn.com/image/fetch/$s_!62i5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d406478-6889-43d8-accd-2a2744b4821b_1368x594.png 848w, https://substackcdn.com/image/fetch/$s_!62i5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d406478-6889-43d8-accd-2a2744b4821b_1368x594.png 1272w, https://substackcdn.com/image/fetch/$s_!62i5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d406478-6889-43d8-accd-2a2744b4821b_1368x594.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!62i5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d406478-6889-43d8-accd-2a2744b4821b_1368x594.png" width="1368" height="594" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4d406478-6889-43d8-accd-2a2744b4821b_1368x594.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:594,&quot;width&quot;:1368,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:127034,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/183642532?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d406478-6889-43d8-accd-2a2744b4821b_1368x594.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!62i5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d406478-6889-43d8-accd-2a2744b4821b_1368x594.png 424w, https://substackcdn.com/image/fetch/$s_!62i5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d406478-6889-43d8-accd-2a2744b4821b_1368x594.png 848w, https://substackcdn.com/image/fetch/$s_!62i5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d406478-6889-43d8-accd-2a2744b4821b_1368x594.png 1272w, https://substackcdn.com/image/fetch/$s_!62i5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d406478-6889-43d8-accd-2a2744b4821b_1368x594.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Kafka's Durability:</strong> When you produce a message to Kafka with proper acknowledgment settings, that message is written to disk and replicated across multiple brokers. Even if the consumer is down for hours, the message waits patiently. When the consumer comes back, it picks up right where it left off.</p><blockquote><p><em><strong>If losing an event is unacceptable, a durable queue like Kafka provides the safety net. The event is guaranteed to be processed eventually, even through failures.</strong></em></p></blockquote><h3>5. When Multiple Consumers Need the Same Event</h3><p>This is where Kafka&#8217;s pub/sub model truly shines - the ability to broadcast one event to many independent consumers without the producer knowing or caring about them.</p><blockquote><p><em><strong>The Order Scenario:</strong> When a customer places an order, multiple systems need to react: Inventory needs to reserve stock, Notifications needs to send confirmation, Analytics needs to track the sale, Fraud Detection needs to evaluate risk, Warehouse needs to prepare shipping, and Loyalty needs to add points.</em></p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iBRe!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c18c387-0354-45ff-b1af-f35956936214_1370x1234.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iBRe!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c18c387-0354-45ff-b1af-f35956936214_1370x1234.png 424w, https://substackcdn.com/image/fetch/$s_!iBRe!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c18c387-0354-45ff-b1af-f35956936214_1370x1234.png 848w, https://substackcdn.com/image/fetch/$s_!iBRe!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c18c387-0354-45ff-b1af-f35956936214_1370x1234.png 1272w, https://substackcdn.com/image/fetch/$s_!iBRe!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c18c387-0354-45ff-b1af-f35956936214_1370x1234.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iBRe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c18c387-0354-45ff-b1af-f35956936214_1370x1234.png" width="1370" height="1234" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7c18c387-0354-45ff-b1af-f35956936214_1370x1234.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1234,&quot;width&quot;:1370,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:117363,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/183642532?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c18c387-0354-45ff-b1af-f35956936214_1370x1234.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!iBRe!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c18c387-0354-45ff-b1af-f35956936214_1370x1234.png 424w, https://substackcdn.com/image/fetch/$s_!iBRe!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c18c387-0354-45ff-b1af-f35956936214_1370x1234.png 848w, https://substackcdn.com/image/fetch/$s_!iBRe!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c18c387-0354-45ff-b1af-f35956936214_1370x1234.png 1272w, https://substackcdn.com/image/fetch/$s_!iBRe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c18c387-0354-45ff-b1af-f35956936214_1370x1234.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Without Kafka:</strong> The Order Service would need to know about every downstream service. Adding Loyalty Points? Change Order Service code. Adding Fraud Detection? Change Order Service code again. Each addition increases coupling and deployment risk.</p><p><strong>With Kafka:</strong> Order Service publishes one event to the &#8220;orders&#8221; topic and walks away. Each downstream service subscribes to that topic independently. Adding a new consumer? Zero changes to Order Service. Each team owns their own consumer.</p><blockquote><p><em>One event, many independent consumers, zero producer changes. Teams can evolve independently, deploy independently, and scale independently.</em></p></blockquote><h3>Other Scenarios Where Kafka Fits</h3><ul><li><p><strong>When consumers evolve independently:</strong> Different teams work on different consumers with different release cycles.</p></li><li><p><strong>When ordering matters:</strong> Kafka guarantees order within a partition - critical for state machines and sequential processing.</p></li><li><p><strong>When retry logic would be ugly:</strong> Instead of implementing retry everywhere, let Kafka handle redelivery.</p></li><li><p><strong>When you need horizontal scaling:</strong> Add more consumers to a consumer group to handle more load.</p></li><li><p><strong>When you want replay capability:</strong> Kafka retains messages, letting you reprocess historical events for debugging or recomputation.</p></li></ul><p><em><strong>If direct service-to-service calls feel fragile, slow, or scary - you likely need a queue.</strong></em></p><p></p><blockquote><p><em><strong>Related (Before reading further)</strong></em></p><p><em>If you enjoy digging into how things actually work, I&#8217;ve been working on something larger.</em></p><p><em>I wrote an ebook that walks through <strong>35 real engineering problems and system designs</strong>, focusing on how decisions break down at scale, what trade-offs actually matter, and the kinds of follow-up questions engineers run into in interviews and real systems.</em></p><p><em>It&#8217;s less about memorizing solutions, and more about learning the <strong>principles behind solving problems at scale</strong> - so you can reason through new situations, not just familiar ones.</em></p><p><strong><a href="https://skilledcoder.gumroad.com/l/system-design">Check System Design Book Here</a></strong></p></blockquote><div><hr></div><h2><strong>When You Should NOT Use Kafka</strong></h2><p>This is the part people skip and later regret. Kafka adds complexity. Using it when you don't need it creates operational burden without corresponding benefit.</p><h3>1. When You Need Immediate Request-Response</h3><p>Kafka is fundamentally asynchronous. It&#8217;s built for &#8220;fire and forget&#8221; patterns, not for &#8220;call and wait for response&#8221; patterns.</p><blockquote><p><em><strong>The Login Scenario:</strong> A user enters their username and password and clicks "Login". They need an immediate answer: Are credentials valid? What's their session token? This must happen in milliseconds.</em></p></blockquote><p><em><strong>Similarly User Profile Fetch, Balance Check, Search Queries, Real-time Validation</strong></em></p><p><strong>Why Kafka Fails Here:</strong> To use Kafka for request-response, you&#8217;d need to: publish a request to Topic A, have a consumer process it, publish a response to Topic B, and have the original requester consume from Topic B. This adds 100-500ms of latency, requires correlation IDs to match responses, and creates complex error handling.</p><blockquote><p><strong>Use Instead:</strong> Direct HTTP/gRPC calls or database reads. If the user is staring at the screen waiting, Kafka is the wrong tool.</p></blockquote><h3>2. When Traffic Is Low and Predictable</h3><p>Kafka&#8217;s power comes from handling scale and unpredictability. At low, steady traffic, it&#8217;s just overhead.</p><blockquote><p><em><strong>The Small App Scenario:</strong> Your internal tool handles 50-200 requests per second. Traffic is steady during business hours and drops to zero at night. You have a few background jobs that run every few minutes.</em></p></blockquote><p><em><strong>Internal Tools, Admin Dashboards, Small B2B Apps, MVPs etc</strong></em></p><p><strong>The Kafka Tax:</strong> Running Kafka means: managing a broker cluster (minimum 3 for production), configuring partitions and replication, monitoring consumer lag, handling broker failures, managing disk space and retention, and training your team on Kafka operations.</p><p>For 50 requests per second, this operational burden far exceeds any benefit. A simple database table with a worker polling every few seconds would handle your needs with zero additional infrastructure.</p><blockquote><p><strong>Use Instead:</strong> Cron jobs, simple database-backed job queues, or lightweight queues like Redis. Save Kafka for when you actually have scale problems.</p></blockquote><h3>3. When You Only Have One Producer and One Consumer</h3><p>Kafka&#8217;s real value emerges with decoupling and fan-out. With a single producer and single consumer, you&#8217;re adding complexity without gaining the benefits.</p><p><strong>The Middleman Problem:</strong> Service A needs to send data to Service B. You add Kafka between them. Now you have: two services to debug instead of direct call tracing, additional failure mode (what if Kafka is down?), consumer lag to monitor, and no real benefit since there&#8217;s no fan-out or speed mismatch.</p><blockquote><p><strong>Use Instead:</strong> Direct async HTTP calls, or lightweight queues like SQS or RabbitMQ if you need retry/durability. Kafka's power is wasted in 1:1 scenarios.</p></blockquote><h3>4. When Durability and Replay Don&#8217;t Matter</h3><p>Kafka persists everything to disk. That&#8217;s its strength - but also overhead when you don&#8217;t need it.</p><p><strong>Ephemeral Events:</strong> You&#8217;re broadcasting cache invalidation signals. You&#8217;re sending &#8220;best effort&#8221; metrics that are fine to lose occasionally. You&#8217;re coordinating temporary state between services. In all these cases, if an event is lost, it&#8217;s not a disaster &#8212; the next event will correct things.</p><p><strong>The Overhead:</strong> Kafka writes every message to disk, replicates it across brokers, and retains it based on your configuration. For fire-and-forget events, this is wasted I/O and storage.</p><blockquote><p><strong>Use Instead:</strong> In-memory queues, Redis pub/sub or streams, or simple fire-and-forget HTTP calls. Match your tool to your durability requirements.</p></blockquote><h3>5. When Tasks Are Simple and Ordering Doesn&#8217;t Matter</h3><p>Kafka guarantees ordering within partitions, but this guarantee comes with complexity. If you don&#8217;t need ordering, simpler tools work better.</p><p><strong>Independent Tasks:</strong> You need to resize 10,000 uploaded images. Each image is independent - the order doesn&#8217;t matter. You need to send 50,000 emails - each is independent. For these &#8220;embarrassingly parallel&#8221; workloads, Kafka&#8217;s partitioning model adds unnecessary complexity.</p><blockquote><p><strong>Use Instead:</strong> Purpose-built task queues like SQS, Sidekiq, Celery, or BullMQ. These are simpler to operate and designed specifically for independent job processing.</p></blockquote><h3>More Warning Signs</h3><ul><li><p><strong>Team can&#8217;t operate Kafka:</strong> Kafka requires operational expertise. Without it, you&#8217;ll face outages.</p></li><li><p><strong>&#8220;FAANG uses it&#8221; reasoning:</strong> Cargo-culting doesn&#8217;t solve problems. FAANG operates at scales you probably don&#8217;t.</p></li><li><p><strong>Large message payloads:</strong> Kafka is optimized for events (KB), not blobs (MB). Use object storage for large files.</p></li><li><p><strong>Ultra-low latency requirements:</strong> If you need sub-millisecond latency, Kafka&#8217;s inherent latency (10-100ms) may be too high.</p></li></ul><div><hr></div><p>Kafka solves scaling pain, not design confusion. If your system is already messy, Kafka will just make the mess distributed.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/p/stop-using-kafka-everywhere?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://newsletter.theskilledcoder.com/p/stop-using-kafka-everywhere?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[How to Handle 10,000 Concurrent Users]]></title><description><![CDATA[Every system eventually hits this moment.]]></description><link>https://newsletter.theskilledcoder.com/p/how-to-handle-10000-concurrent-users</link><guid isPermaLink="false">https://newsletter.theskilledcoder.com/p/how-to-handle-10000-concurrent-users</guid><dc:creator><![CDATA[Skilled Coder]]></dc:creator><pubDate>Mon, 29 Dec 2025 12:24:43 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!jtDd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe58608a3-f300-49e2-a48b-f23c71d7eb9c_1024x608.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_!jtDd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe58608a3-f300-49e2-a48b-f23c71d7eb9c_1024x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jtDd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe58608a3-f300-49e2-a48b-f23c71d7eb9c_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!jtDd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe58608a3-f300-49e2-a48b-f23c71d7eb9c_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!jtDd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe58608a3-f300-49e2-a48b-f23c71d7eb9c_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!jtDd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe58608a3-f300-49e2-a48b-f23c71d7eb9c_1024x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jtDd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe58608a3-f300-49e2-a48b-f23c71d7eb9c_1024x608.png" width="1024" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e58608a3-f300-49e2-a48b-f23c71d7eb9c_1024x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:608,&quot;width&quot;:1024,&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_!jtDd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe58608a3-f300-49e2-a48b-f23c71d7eb9c_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!jtDd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe58608a3-f300-49e2-a48b-f23c71d7eb9c_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!jtDd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe58608a3-f300-49e2-a48b-f23c71d7eb9c_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!jtDd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe58608a3-f300-49e2-a48b-f23c71d7eb9c_1024x608.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"></figcaption></figure></div><p>One quiet Friday you ship your new app, close the laptop, and head out for coffee. Suddenly a celebrity tweets your link. In ten minutes 10,000 people smash the Sign Up button - and your single&#8209;box server starts doing its best impression of a pressure cooker.</p><p>At first, it sounds like a capacity question.</p><p>In reality, it&#8217;s a systems thinking question.</p><p>Let&#8217;s start with the approaches that seem correct - and why they fail.</p><div><hr></div><h2>First Attempts (and Why They Break)</h2><h3>Attempt 1: Just Add More Servers</h3><p>The most common instinct. Traffic increases &#8594; add more app servers &#8594; problem solved.</p><p><em>Why it feels right:</em></p><ul><li><p>Horizontal scaling is industry standard</p></li><li><p>Cloud makes it easy</p></li><li><p>Works at low to medium traffic</p></li></ul><p><em>Why it fails:</em></p><ul><li><p>Shared bottlenecks don&#8217;t scale automatically</p></li><li><p>Database, cache, auth service, third-party APIs all become choke points</p></li><li><p>One slow downstream service can stall thousands of requests</p></li></ul><p><strong>You scaled the frontend, not the system.</strong></p><blockquote><p><strong>Lesson</strong> :Concurrency pressure usually breaks dependencies, not CPU.</p></blockquote><h3>Attempt 2: Increase Thread Pool Size</h3><p>Another classic fix. &#8220;Let&#8217;s increase the thread pool from 200 to 2,000.&#8221;</p><p><em>Why it feels right:</em></p><ul><li><p>More threads = more users handled</p></li><li><p>Easy config change</p></li><li><p>Looks like progress</p></li></ul><p><em>Why it fails:</em></p><ul><li><p>Threads consume memory and context-switching time</p></li><li><p>CPU spends more time scheduling than doing work</p></li><li><p>Latency gets worse, not better</p></li><li><p>JVM / runtime starts thrashing</p></li></ul><p><strong>Concurrency is not free just because threads exist.</strong></p><blockquote><p><strong>Lesson</strong> : More threads don&#8217;t mean more throughput.</p></blockquote><h3>Attempt 3: Cache Everything</h3><p>Okay, let&#8217;s cache aggressively. Cache DB responses, API calls, user sessions.</p><p><em>Why it feels right:</em></p><ul><li><p>Reduces load</p></li><li><p>Improves latency</p></li><li><p>Caching works - until it doesn&#8217;t</p></li></ul><p><em>Why it fails:</em></p><ul><li><p>Cache stampedes under concurrent misses</p></li><li><p>Hot keys get hammered</p></li><li><p>Cache invalidation logic becomes fragile</p></li><li><p>Memory pressure increases fast</p></li></ul><p><strong>Caching helps load, but it doesn&#8217;t control concurrency.</strong></p><blockquote><p><strong>Lesson</strong> : Cache reduces work, it doesn&#8217;t manage access.</p></blockquote><h3>Attempt 4: Let Requests Queue Up</h3><p>Another tempting idea: &#8220;If users come faster than we can handle, let them wait.&#8221;</p><p><em>Why it feels right:</em></p><ul><li><p>No requests dropped</p></li><li><p>Everything is eventually processed</p></li></ul><p><em>Why it fails:</em></p><ul><li><p>Queues grow without bound</p></li><li><p>Latency explodes</p></li><li><p>Timeouts cascade across services</p></li><li><p>Users retry &#8594; doubling traffic</p></li></ul><p><strong>Unbounded queues turn traffic spikes into outages.</strong></p><h2>The Real Problem</h2><p>10,000 concurrent users is not about <em>users</em>.</p><p>It&#8217;s about how many things your system can do at the same time without stepping on itself.</p><p>The real questions are:</p><ul><li><p>Which operations are <strong>blocking</strong>?</p></li><li><p>Which resources are <strong>shared</strong>?</p></li><li><p>Which paths must be <strong>fast</strong>, and which can be <strong>delayed</strong>?</p></li></ul><p>Once you answer those, the solution becomes clearer.</p><p>Lets see step by step how to build such system</p><div><hr></div><blockquote><p><em><strong>Related </strong>[Before reading further]</em></p><p><em>This article scratched the surface. The real interview goes 10 levels deeper.</em></p><ul><li><p><em>How do you handle hot partitions?</em></p></li><li><p><em>What if the cache goes down during a spike?</em></p></li><li><p><em>How do you avoid counting the same view twice?</em></p></li></ul><p><em>I&#8217;ve written an ebook that prepares you for all of it.</em></p><p><em>35 real problems. The patterns that solve them. The follow-ups you&#8217;ll actually face. The principles behind solving problems at scale, not just the final answers.</em></p><p><em><strong>&#128073; <a href="https://skilledcoder.gumroad.com/l/system-design">Check it out here</a></strong></em></p></blockquote><div><hr></div><h2>The Correct Architecture</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5Qn8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F831e1887-2649-41b7-b3d1-4cab71d40bba_1636x1326.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5Qn8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F831e1887-2649-41b7-b3d1-4cab71d40bba_1636x1326.png 424w, https://substackcdn.com/image/fetch/$s_!5Qn8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F831e1887-2649-41b7-b3d1-4cab71d40bba_1636x1326.png 848w, https://substackcdn.com/image/fetch/$s_!5Qn8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F831e1887-2649-41b7-b3d1-4cab71d40bba_1636x1326.png 1272w, https://substackcdn.com/image/fetch/$s_!5Qn8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F831e1887-2649-41b7-b3d1-4cab71d40bba_1636x1326.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5Qn8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F831e1887-2649-41b7-b3d1-4cab71d40bba_1636x1326.png" width="1456" height="1180" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/831e1887-2649-41b7-b3d1-4cab71d40bba_1636x1326.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1180,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:137491,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/182853332?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F831e1887-2649-41b7-b3d1-4cab71d40bba_1636x1326.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5Qn8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F831e1887-2649-41b7-b3d1-4cab71d40bba_1636x1326.png 424w, https://substackcdn.com/image/fetch/$s_!5Qn8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F831e1887-2649-41b7-b3d1-4cab71d40bba_1636x1326.png 848w, https://substackcdn.com/image/fetch/$s_!5Qn8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F831e1887-2649-41b7-b3d1-4cab71d40bba_1636x1326.png 1272w, https://substackcdn.com/image/fetch/$s_!5Qn8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F831e1887-2649-41b7-b3d1-4cab71d40bba_1636x1326.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>1. Make the Request Path Thin</h3><p>The request thread should do <strong>as little as possible</strong>.</p><ul><li><p>Validate input</p></li><li><p>Authorize</p></li><li><p>Enqueue work</p></li><li><p>Return response</p></li></ul><p>Anything slow or non-critical moves out of band.</p><p><strong>Concurrency survives when requests finish fast.</strong></p><h3>2. Control Concurrency Explicitly</h3><p>Instead of letting everything run freely:</p><ul><li><p>Limit concurrent DB calls</p></li><li><p>Limit outbound API calls</p></li><li><p>Apply bulkheads per dependency</p></li></ul><p>When limits are hit:</p><ul><li><p>Fail fast</p></li><li><p>Return degraded responses</p></li><li><p>Don&#8217;t let pressure spread</p></li></ul><p><strong>This protects the system from itself.</strong></p><h3>3. Separate Immediate Work from Deferred Work</h3><p>Not everything needs to happen now.</p><ul><li><p>Emails</p></li><li><p>Notifications</p></li><li><p>Analytics</p></li><li><p>Logging</p></li><li><p>Recommendations</p></li></ul><p>Push these to queues and process asynchronously.</p><p><strong>Users care about response time, not background perfection.</strong></p><h3>4. Scale State, Not Just Compute</h3><p>Stateless app servers scale easily. State doesn&#8217;t.</p><ul><li><p>Partition data</p></li><li><p>Reduce shared locks</p></li><li><p>Avoid global coordination</p></li><li><p>Prefer per-user or per-shard isolation</p></li></ul><p><strong>Concurrency collapses when everyone waits on the same thing.</strong></p><h3>5. Apply Backpressure Early</h3><p>When the system is under stress:</p><ul><li><p>Reject requests early</p></li><li><p>Return 429s</p></li><li><p>Degrade features</p></li><li><p>Shed load intentionally</p></li></ul><p><strong>A fast rejection is better than a slow failure.</strong></p><h2>Why This Works</h2><p>This approach works because it accepts a hard truth:</p><div class="pullquote"><p><strong>You can&#8217;t handle infinite concurrency - but you can control it.</strong></p></div><ul><li><p>Requests finish quickly</p></li><li><p>Slow work happens elsewhere</p></li><li><p>Failures stay contained</p></li><li><p>Traffic spikes don&#8217;t turn into outages</p></li></ul><p><strong>10,000 concurrent users stop being scary. They become just another number.</strong></p><h3>Interview Pivot</h3><p>If asked:</p><p><strong>&#8220;How would you handle 10,000 concurrent users?&#8221;</strong></p><blockquote><p><em>&#8220;I&#8217;d keep the request path thin, control concurrency to shared dependencies with bulkheads, move slow work async, apply backpressure early, and scale state carefully.</em></p><p><em>That way concurrency increases without collapsing latency.&#8221;</em></p></blockquote><p>That answer shows you understand <strong>system behavior</strong>, not just scaling slogans.</p><h3>What&#8217;s Next?</h3><p>Real systems bring follow-ups:</p><ul><li><p><strong>What happens when one dependency slows down?</strong></p></li><li><p><strong>How do you prevent retry storms?</strong></p></li><li><p><strong>How do you degrade gracefully?</strong></p></li><li><p><strong>How do you observe concurrency bottlenecks?</strong></p></li></ul><p>We&#8217;ll dive deeper into these kinds of follow-ups in upcoming articles (or in ebook)- subscribe if you want more.</p><p>Thanks for reading. See you in next post.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/p/how-to-handle-10000-concurrent-users?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://newsletter.theskilledcoder.com/p/how-to-handle-10000-concurrent-users?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[How Would You Compute Trending Posts at Millions of Events per Second?]]></title><description><![CDATA[Computing "Trending Posts" Is Harder Than It Looks]]></description><link>https://newsletter.theskilledcoder.com/p/how-would-you-compute-trending-posts</link><guid isPermaLink="false">https://newsletter.theskilledcoder.com/p/how-would-you-compute-trending-posts</guid><dc:creator><![CDATA[Skilled Coder]]></dc:creator><pubDate>Mon, 22 Dec 2025 09:16:21 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Ukfs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f87fbb-d353-4411-aa8c-806b4d159f09_1978x976.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_!Ukfs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f87fbb-d353-4411-aa8c-806b4d159f09_1978x976.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ukfs!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f87fbb-d353-4411-aa8c-806b4d159f09_1978x976.png 424w, https://substackcdn.com/image/fetch/$s_!Ukfs!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f87fbb-d353-4411-aa8c-806b4d159f09_1978x976.png 848w, https://substackcdn.com/image/fetch/$s_!Ukfs!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f87fbb-d353-4411-aa8c-806b4d159f09_1978x976.png 1272w, https://substackcdn.com/image/fetch/$s_!Ukfs!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f87fbb-d353-4411-aa8c-806b4d159f09_1978x976.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ukfs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f87fbb-d353-4411-aa8c-806b4d159f09_1978x976.png" width="1456" height="718" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f0f87fbb-d353-4411-aa8c-806b4d159f09_1978x976.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:718,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2274462,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/182309157?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f87fbb-d353-4411-aa8c-806b4d159f09_1978x976.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Ukfs!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f87fbb-d353-4411-aa8c-806b4d159f09_1978x976.png 424w, https://substackcdn.com/image/fetch/$s_!Ukfs!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f87fbb-d353-4411-aa8c-806b4d159f09_1978x976.png 848w, https://substackcdn.com/image/fetch/$s_!Ukfs!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f87fbb-d353-4411-aa8c-806b4d159f09_1978x976.png 1272w, https://substackcdn.com/image/fetch/$s_!Ukfs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f87fbb-d353-4411-aa8c-806b4d159f09_1978x976.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><p>Every social platform has it. A Trending section.</p><p>The posts everyone seems to be talking about <em>right now</em> - not yesterday, not last week, but this minute.</p><p>At first glance, it sounds easy. Just count likes and sort, right?</p><p>That illusion lasts until traffic grows, events start arriving out of order, and one viral post suddenly floods your system. What felt like a simple ranking problem quickly turns into a real-time data challenge.</p><blockquote><h5>I<em>n This Chapter</em></h5><ul><li><p><em>The solutions that look correct but break at scale</em></p></li><li><p><em>Why &#8220;trending&#8221; is not a batch problem</em></p></li><li><p><em>How real systems compute it continuously using streaming data</em></p></li></ul></blockquote><p>We will solve it with first-principles thinking.</p><div><hr></div><h2>First Attempts (and Why They Break)</h2><h3>Attempt 1: Recompute Everything Every Minute</h3><p>The most obvious idea is this:</p><ol><li><p>Every minute, scan all recent likes, comments, shares, and views</p></li><li><p>Group them by post</p></li><li><p>Sort by count</p></li><li><p>Pick the top 10</p></li></ol><p>Simple SQL or Spark job. Done.</p><p>Why it feels right:</p><ul><li><p>Easy to reason about</p></li><li><p>Works fine when you have 10k posts</p></li><li><p>&#8220;Trending every minute&#8221; sounds like a batch problem</p></li></ul><p>Why it fails:</p><ul><li><p>You&#8217;re reprocessing the same data again and again</p></li><li><p>At scale, each minute means scanning millions of events</p></li><li><p>Latency creeps up &#8594; your &#8220;every minute&#8221; job takes longer than a minute</p></li><li><p>Spikes (viral posts) make jobs miss their SLA</p></li></ul><p>What looked like a clean batch job quietly turns into a runaway compute bill.</p><div class="pullquote"><p><strong>Lesson</strong> : Recomputing from scratch doesn&#8217;t scale with velocity.</p></div><h3>Attempt 2: Maintain Counters in the Database</h3><p>Okay, let&#8217;s be smarter.</p><p>Whenever a user likes or comments on a post: <strong>Increment a counter in the posts table</strong>. Use that counter to decide what&#8217;s trending.</p><p>Why it feels right:</p><ul><li><p>Constant-time updates</p></li><li><p>Data is always &#8220;fresh&#8221;</p></li><li><p>Easy queries like <code>ORDER BY score DESC</code></p></li></ul><p>Why it fails:</p><ul><li><p>High write contention on hot posts</p></li><li><p>Viral posts become bottlenecks</p></li><li><p>Locks, retries, and replication lag start showing up</p></li><li><p>Your primary DB is now handling analytics traffic</p></li></ul><p>Suddenly, your transactional database is doing real-time ranking. That never ends well.</p><div class="pullquote"><p><strong>Lesson</strong> : Databases are great at state, not high-frequency event aggregation.</p></div><h3>Attempt 3: Cache Trending Posts in Redis</h3><p>Fine. Move fast stuff to Redis.</p><ul><li><p>Increment counters in Redis</p></li><li><p>Every minute, read top keys</p></li><li><p>Redis is fast, right?</p></li></ul><p><em>Why it feels right:</em></p><ul><li><p>In-memory speed</p></li><li><p>No DB locks</p></li><li><p>Widely used pattern</p></li></ul><p><em>What&#8217;s the problem:</em></p><ul><li><p>Redis becomes a single hot spot</p></li><li><p>You lose ordering guarantees under heavy concurrency</p></li><li><p>Crash or restart = counters gone (unless heavily persisted)</p></li><li><p>Cross-region or multi-shard ranking gets messy</p></li></ul><p>Redis helps performance, but it doesn&#8217;t solve time-windowed aggregation cleanly.</p><div class="pullquote"><p><strong>Lesson</strong> : Speed alone doesn&#8217;t solve correctness at scale.</p></div><h3>Attempt 4: Trigger Jobs with Cron</h3><p>Another classic move:</p><ul><li><p>Run a cron job every minute</p></li><li><p>Compute trending posts for the last 60 seconds</p></li><li><p>Publish the result</p></li></ul><p><em>Why it feels right:</em></p><ul><li><p>Simple mental model</p></li><li><p>Clear time boundaries</p></li><li><p>Easy to debug</p></li></ul><p><em>What&#8217;s the issue:</em></p><ul><li><p>All computation spikes at the same second</p></li><li><p>Late events get dropped or miscounted</p></li><li><p>Real-time systems don&#8217;t respect clock boundaries</p></li><li><p>Users see inconsistent &#8220;trending&#8221; lists</p></li></ul><p>Trending is a <strong>flowing signal</strong>, not a punctual snapshot.</p><div class="pullquote"><p><strong>Lesson</strong> : Time-based cron jobs don&#8217;t mix well with real-time streams.</p></div><h3>Attempt 5: &#8220;Just Use Machine Learning&#8221;</h3><p>Someone always suggests this. &#8220;Why not train a model to predict trending posts?&#8221;</p><p><em>Why it feels right:</em></p><ul><li><p>Sounds sophisticated</p></li><li><p>Great for long-term ranking</p></li></ul><p><em>Why it fails (for this problem):</em></p><ul><li><p>ML still needs clean, real-time features</p></li><li><p>You still haven&#8217;t solved streaming aggregation</p></li><li><p>Latency requirements make inference tricky</p></li><li><p>Overkill for minute-level trends</p></li></ul><p>ML improves ranking. It doesn&#8217;t replace real-time computation.</p><div class="pullquote"><p><strong>Lesson</strong> : Intelligence doesn&#8217;t fix broken pipelines.</p></div><h2>The Pattern Emerging</h2><p>All these approaches fail for the same reason:</p><blockquote><p><strong>They treat trending as a static calculation.<br>In reality, trending is a moving window over a live stream of events.</strong></p></blockquote><p>To solve it properly, we need to stop thinking in <strong>rows</strong> and start thinking in <strong>flows</strong>.</p><h3>The Right Way to Think About Trending</h3><p>Once you step back, the mistake in all the earlier attempts becomes obvious.</p><div class="pullquote"><p><strong>Trending is not a number.</strong> It&#8217;s a signal changing over time.</p><p>A post doesn&#8217;t become trending because it crossed a fixed count. It becomes trending because activity around it is rising faster than others right now.</p></div><p>That immediately tells us two things:</p><ol><li><p>We must process events as they happen</p></li><li><p>We must reason in <strong>sliding time windows</strong>, not batches or cron jobs</p></li></ol><p>This is a streaming problem, not a database one.</p><h3>The Mental Model Shift</h3><p>Instead of asking:</p><p><em>&#8220;Every minute, what are the top posts?&#8221;</em></p><p>We ask:</p><p><strong>&#8220;As events flow in, how does each post&#8217;s momentum change?&#8221;</strong></p><p>Once you adopt this mindset, the architecture almost designs itself.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ruda!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c7cdd3d-616e-43e3-93e8-dd2dbf891cbf_1642x774.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ruda!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c7cdd3d-616e-43e3-93e8-dd2dbf891cbf_1642x774.png 424w, https://substackcdn.com/image/fetch/$s_!Ruda!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c7cdd3d-616e-43e3-93e8-dd2dbf891cbf_1642x774.png 848w, https://substackcdn.com/image/fetch/$s_!Ruda!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c7cdd3d-616e-43e3-93e8-dd2dbf891cbf_1642x774.png 1272w, https://substackcdn.com/image/fetch/$s_!Ruda!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c7cdd3d-616e-43e3-93e8-dd2dbf891cbf_1642x774.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ruda!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c7cdd3d-616e-43e3-93e8-dd2dbf891cbf_1642x774.png" width="1456" height="686" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3c7cdd3d-616e-43e3-93e8-dd2dbf891cbf_1642x774.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:686,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:93904,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/182309157?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c7cdd3d-616e-43e3-93e8-dd2dbf891cbf_1642x774.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Ruda!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c7cdd3d-616e-43e3-93e8-dd2dbf891cbf_1642x774.png 424w, https://substackcdn.com/image/fetch/$s_!Ruda!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c7cdd3d-616e-43e3-93e8-dd2dbf891cbf_1642x774.png 848w, https://substackcdn.com/image/fetch/$s_!Ruda!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c7cdd3d-616e-43e3-93e8-dd2dbf891cbf_1642x774.png 1272w, https://substackcdn.com/image/fetch/$s_!Ruda!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c7cdd3d-616e-43e3-93e8-dd2dbf891cbf_1642x774.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>The Architecture: Step by Step</h3><h4>Step 1: Treat Every Interaction as an Event</h4><p>Likes, comments, shares, views - they are all signals. Each interaction becomes a small event:</p><pre><code>{
  "post_id": "abc123",
  "event_type": "like",
  "timestamp": 1702999200
}</code></pre><p>Nothing is aggregated yet. Nothing is ranked yet. We simply emit events and move on.</p><p>This keeps the write path extremely fast and lets the system absorb sudden spikes when something goes viral.</p><h4>Step 2: Stream, Don&#8217;t Store First</h4><p>These events flow into a stream - <strong>Kafka</strong>, <strong>Pulsar</strong>, <strong>Kinesis</strong>, <strong>Pub/Sub</strong>.</p><p>Why a stream? Because streams:</p><ul><li><p>Preserve order within partitions</p></li><li><p>Handle burst traffic naturally</p></li><li><p>Allow multiple consumers to compute different views</p></li></ul><p>At this point, the system isn&#8217;t &#8220;computing trending&#8221; yet. It&#8217;s just <strong>recording reality as it unfolds</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3UwB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced15cb-2b83-4241-8d5e-80896111669b_1636x1168.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3UwB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced15cb-2b83-4241-8d5e-80896111669b_1636x1168.png 424w, https://substackcdn.com/image/fetch/$s_!3UwB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced15cb-2b83-4241-8d5e-80896111669b_1636x1168.png 848w, https://substackcdn.com/image/fetch/$s_!3UwB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced15cb-2b83-4241-8d5e-80896111669b_1636x1168.png 1272w, https://substackcdn.com/image/fetch/$s_!3UwB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced15cb-2b83-4241-8d5e-80896111669b_1636x1168.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3UwB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced15cb-2b83-4241-8d5e-80896111669b_1636x1168.png" width="1456" height="1039" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1ced15cb-2b83-4241-8d5e-80896111669b_1636x1168.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1039,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:144309,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/182309157?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced15cb-2b83-4241-8d5e-80896111669b_1636x1168.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3UwB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced15cb-2b83-4241-8d5e-80896111669b_1636x1168.png 424w, https://substackcdn.com/image/fetch/$s_!3UwB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced15cb-2b83-4241-8d5e-80896111669b_1636x1168.png 848w, https://substackcdn.com/image/fetch/$s_!3UwB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced15cb-2b83-4241-8d5e-80896111669b_1636x1168.png 1272w, https://substackcdn.com/image/fetch/$s_!3UwB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced15cb-2b83-4241-8d5e-80896111669b_1636x1168.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4>Step 3: Compute Trends Using Sliding Windows</h4><p>Now comes the core idea.</p><p>Instead of recomputing everything every minute, we maintain <strong>rolling windows</strong>:</p><ul><li><p>Last 1 minute</p></li><li><p>Last 5 minutes</p></li><li><p>Last 15 minutes</p></li></ul><p>As events flow in, stream processors continuously update counters per post per window.</p><p><strong>This is not batch. This is incremental math.</strong></p><p>When a new like arrives:</p><ol><li><p>Add +1 to that post&#8217;s current window</p></li><li><p>Expire events that fall out of the window</p></li><li><p>Update the score instantly</p></li></ol><p>No rescans. No cron jobs. No waiting.</p><p><strong>Trending becomes a continuously updated result.</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XiOZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6af964c2-c072-4897-a386-9b1ae5397ac3_1622x644.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XiOZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6af964c2-c072-4897-a386-9b1ae5397ac3_1622x644.png 424w, https://substackcdn.com/image/fetch/$s_!XiOZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6af964c2-c072-4897-a386-9b1ae5397ac3_1622x644.png 848w, https://substackcdn.com/image/fetch/$s_!XiOZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6af964c2-c072-4897-a386-9b1ae5397ac3_1622x644.png 1272w, https://substackcdn.com/image/fetch/$s_!XiOZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6af964c2-c072-4897-a386-9b1ae5397ac3_1622x644.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XiOZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6af964c2-c072-4897-a386-9b1ae5397ac3_1622x644.png" width="1456" height="578" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6af964c2-c072-4897-a386-9b1ae5397ac3_1622x644.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:578,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:84684,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/182309157?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6af964c2-c072-4897-a386-9b1ae5397ac3_1622x644.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XiOZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6af964c2-c072-4897-a386-9b1ae5397ac3_1622x644.png 424w, https://substackcdn.com/image/fetch/$s_!XiOZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6af964c2-c072-4897-a386-9b1ae5397ac3_1622x644.png 848w, https://substackcdn.com/image/fetch/$s_!XiOZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6af964c2-c072-4897-a386-9b1ae5397ac3_1622x644.png 1272w, https://substackcdn.com/image/fetch/$s_!XiOZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6af964c2-c072-4897-a386-9b1ae5397ac3_1622x644.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4>Step 4: Separate Scoring from Ranking</h4><p>Raw counts alone don&#8217;t tell the full story.</p><p>A post with 10 likes in 1 minute might be more interesting than one with 1,000 likes over a day.</p><p>So instead of just counting, we compute a <strong>score</strong>:</p><ul><li><p>Weight recent events higher than older ones</p></li><li><p>Give comments more weight than likes</p></li><li><p>Normalize by post age</p></li></ul><p>This scoring logic lives inside the stream processor.</p><p>The output is simple:</p><pre><code>{
  "post_id": "abc123",
  "trend_score": 847.5,
  "window": "5min"
}</code></pre><p>The heavy thinking happens once, in the stream - not on every read.</p><h4>Step 5: Maintain a Live Top-K Structure</h4><p>From these scores, we maintain a <strong>Top-K list</strong> (say top 100 posts per region or category).</p><p>This structure updates incrementally:</p><ul><li><p>When a score changes, we adjust its position</p></li><li><p>No full sorting required</p></li><li><p>No global locks</p></li></ul><p><strong>The result is always ready.</strong></p><p>When the UI asks for &#8220;trending posts&#8221;, it&#8217;s a simple read - not a computation.</p><h4>Step 6: Serve Reads Without Touching the Stream</h4><p>The final trending list is pushed to a fast store:</p><ul><li><p>Redis</p></li><li><p>DynamoDB</p></li><li><p>In-memory cache</p></li></ul><p>Reads are cheap. Writes are controlled. The stream keeps flowing independently.</p><p>If the UI goes down, streaming continues. If the stream lags, the UI still serves the last known good state.</p><p><strong>Failures don&#8217;t cascade.</strong></p><h3>Why This Works (At Scale)</h3><p>This architecture works because <strong>nothing waits</strong>.</p><ul><li><p>Events flow in once</p></li><li><p>Computation happens incrementally</p></li><li><p>Ranking updates continuously</p></li><li><p>Reads never trigger heavy work</p></li></ul><p>You&#8217;re no longer fighting time or traffic spikes.</p><p><strong>Trending stops being a periodic job and becomes a living signal.</strong></p><h3>Interview Pivot (How to Explain It)</h3><p>If someone asks:</p><p><strong>&#8220;How would you compute trending posts every minute?&#8221;</strong></p><blockquote><p><em>&#8220;I wouldn&#8217;t recompute every minute. I&#8217;d treat user interactions as a stream, aggregate them in sliding windows, compute a rolling trend score per post, and maintain a live top-K list.</em></p><p><em>The UI simply reads the latest result, while the stream updates continuously in the background.&#8221;</em></p></blockquote><p>That answer shows you understand <strong>data flow</strong>, not just data storage.</p><h3>What&#8217;s Next?</h3><p>Trending isn&#8217;t something you calculate on a schedule. It&#8217;s something you <strong>observe as it emerges</strong>.</p><p>This design opens the door to deeper questions:</p><ul><li><p><strong>How do you handle late or out-of-order events?</strong></p></li><li><p><strong>How do you avoid one viral post dominating forever?</strong></p></li><li><p><strong>How do you scale this across regions?</strong></p></li><li><p><strong>How do you debug wrong trending results?</strong></p></li></ul><blockquote><p><strong>The key insight:</strong> Trending isn&#8217;t about counting - it&#8217;s about capturing momentum. The systems that get this right don&#8217;t fight the stream of events. They ride it.</p><p><em><strong>Think in flows, not snapshots. That&#8217;s how real-time systems scale.</strong></em></p></blockquote><div><hr></div><p><strong>Related</strong></p><p>This article scratched the surface. The real interview goes 10 levels deeper.</p><ul><li><p>How do you handle hot partitions?</p></li><li><p>What if the cache goes down during a spike?</p></li><li><p>How do you avoid counting the same view twice?</p></li></ul><p>I've written an ebook that prepares you for <strong>all of it</strong>.</p><p>35 real problems. The patterns that solve them. The follow-ups you'll actually face. The principles behind solving problems at scale, not just the final answers.</p><p> &#128073; <strong><a href="https://skilledcoder.gumroad.com/l/system-design">Grab your copy here</a></strong></p><p>Thanks for reading. See you in next post.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/p/how-would-you-compute-trending-posts?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/p/how-would-you-compute-trending-posts?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://newsletter.theskilledcoder.com/p/how-would-you-compute-trending-posts?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[How to Log 1M Events/Sec Without Slowing Down Your System]]></title><description><![CDATA[Why Logging Isn&#8217;t as Simple as It Looks]]></description><link>https://newsletter.theskilledcoder.com/p/how-to-log-1m-eventssec-without-slowing</link><guid isPermaLink="false">https://newsletter.theskilledcoder.com/p/how-to-log-1m-eventssec-without-slowing</guid><dc:creator><![CDATA[Skilled Coder]]></dc:creator><pubDate>Tue, 09 Dec 2025 16:11:44 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!gg2C!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fb9253f-9833-473e-a3c8-76e3d16258b8_2876x1578.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_!gg2C!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fb9253f-9833-473e-a3c8-76e3d16258b8_2876x1578.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gg2C!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fb9253f-9833-473e-a3c8-76e3d16258b8_2876x1578.png 424w, https://substackcdn.com/image/fetch/$s_!gg2C!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fb9253f-9833-473e-a3c8-76e3d16258b8_2876x1578.png 848w, https://substackcdn.com/image/fetch/$s_!gg2C!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fb9253f-9833-473e-a3c8-76e3d16258b8_2876x1578.png 1272w, https://substackcdn.com/image/fetch/$s_!gg2C!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fb9253f-9833-473e-a3c8-76e3d16258b8_2876x1578.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gg2C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fb9253f-9833-473e-a3c8-76e3d16258b8_2876x1578.png" width="1456" height="799" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7fb9253f-9833-473e-a3c8-76e3d16258b8_2876x1578.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:799,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:397125,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/181153628?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fb9253f-9833-473e-a3c8-76e3d16258b8_2876x1578.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!gg2C!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fb9253f-9833-473e-a3c8-76e3d16258b8_2876x1578.png 424w, https://substackcdn.com/image/fetch/$s_!gg2C!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fb9253f-9833-473e-a3c8-76e3d16258b8_2876x1578.png 848w, https://substackcdn.com/image/fetch/$s_!gg2C!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fb9253f-9833-473e-a3c8-76e3d16258b8_2876x1578.png 1272w, https://substackcdn.com/image/fetch/$s_!gg2C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7fb9253f-9833-473e-a3c8-76e3d16258b8_2876x1578.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><p>Every modern system - whether it&#8217;s a fintech app processing payments, an ad-tech platform tracking impressions, or a multiplayer game updating player actions - relies on one silent backbone:</p><p>Logs</p><p>They&#8217;re the breadcrumbs of truth.</p><ul><li><p>A debit failure in banking</p></li><li><p>A player teleporting in a game</p></li><li><p>A &#8220;Buy Now&#8221; button click in e-commerce</p></li><li><p>A leaderboard refresh in a fantasy sports app</p></li></ul><p>Individually, they look tiny.</p><p>Collectively, they become millions per second.</p><p>The issue is</p><blockquote><p><em>Logging feels trivial when traffic is small.<br>At scale, logging becomes one of the most expensive operations in your system.</em></p></blockquote><p>Because logging is not &#8220;just write a line.&#8221;</p><p>It is <strong>I/O + storage + latency + durability + retention + indexing + retrieval + analytics</strong>.</p><p>And once your traffic crosses a certain threshold, the na&#239;ve approach falls apart.</p><p>Let&#8217;s break down why logging at massive scale is hard, and how to do it right.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.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">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></p><div><hr></div><h3><strong>First Attempt: Log Directly Inside App Code</strong></h3><p>Most beginners start here:</p><pre><code>log.info(&#8221;User &#8220; + userId + &#8220; clicked Buy Now&#8221;);</code></pre><p>Why it feels right:</p><ul><li><p>Easy to write</p></li><li><p>Works in dev</p></li><li><p>Shows logs instantly</p></li></ul><p>Why it fails at scale:</p><ul><li><p>Logging is blocking IO</p></li><li><p>Every write competes with CPU cycles meant for business logic</p></li><li><p>If logs go to disk &#8594; disk bandwidth becomes bottleneck</p></li><li><p>If logs go to external system &#8594; network latency kills throughput</p></li><li><p>If logs are synchronous &#8594; one slow write pauses the entire request</p></li></ul><p>At 1M events/sec, this model collapses.</p><p>Even a 1ms logging cost means:</p><pre><code>1,000,000 events &#215; 1ms = 1,000,000ms = 1000 seconds latency &#8594; impossible.</code></pre><p>Direct synchronous logging couples application performance with logging performance and that&#8217;s dangerous.</p><div><hr></div><h3><strong>Attempt 2: Batch Logs and Write Periodically</strong></h3><p>Okay, so developers try batching:</p><pre><code>buffer.append(event)
if buffer.size &gt;= 1000:
    writeToDisk(buffer)
    buffer.clear()</code></pre><p>Why it feels right:</p><ul><li><p>Fewer writes = fewer syscalls</p></li><li><p>Better throughput</p></li><li><p>Common in logging libraries like Logback, Bunyan, Serilog etc.</p></li></ul><p>Why it still breaks:</p><ul><li><p>If your process crashes &#8594; buffered logs vanish</p></li><li><p>If bursts exceed buffer capacity &#8594; logs drop</p></li><li><p>Writing periodically still requires locking, causing contention across threads</p></li><li><p>If storage slows down, buffers back up &#8594; memory explodes</p></li></ul><p>At 1M/sec, even buffering isn&#8217;t enough.</p><p>Batching helps, but doesn&#8217;t decouple logging from request handling.</p><pre><code> &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
 &#9474;   Application Code   &#9474;
 &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
             &#9474;
             &#9474;
             &#9660;
       (In-memory buffer)
        &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
        &#9474;   Log Buffer  &#9474;
        &#9474;  (Batch size) &#9474;
        &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                &#9474;
       (flush every X events/time)
                &#9660;
       &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
       &#9474;  Disk/DB/HTTP   &#9474;
       &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;</code></pre><div><hr></div><h3><strong>Attempt 3: Log to Database</strong></h3><p>Idea: store logs in SQL or NoSQL since it&#8217;s durable and queryable.</p><p>Sounds nice.</p><p>Until things break:</p><ul><li><p>DB inserts become bottleneck</p></li><li><p>Locks + indexes kill write throughput</p></li><li><p>Querying logs affects real app data</p></li><li><p>Storage cost skyrockets</p></li><li><p>Retention becomes a nightmare</p></li></ul><p>A typical database can handle:</p><ul><li><p>MySQL: ~10k writes/sec (with tuning)</p></li><li><p>MongoDB: 50k&#8211;200k writes/sec (clustered)</p></li><li><p>Cassandra: high write throughput but still expensive at scale</p></li></ul><p>1M/sec destroys it - financially and operationally.</p><p><strong>Databases are for structured data, not firehose-scale telemetry.</strong></p><div><hr></div><h3><strong>Attempt 4: Send Logs Directly to Elasticsearch / OpenSearch</strong></h3><p>This is where many companies fail.</p><p>Elasticsearch gives:</p><ul><li><p>Searchability</p></li><li><p>Visual dashboards</p></li><li><p>Indexing</p></li><li><p>Alerting</p></li></ul><p>Feels perfect.</p><p>Until indexing overhead hits.</p><p>Indexing every event means:</p><ul><li><p>Tokenization</p></li><li><p>Sharding</p></li><li><p>Replication</p></li><li><p>Compression</p></li><li><p>Persistence</p></li></ul><p>Even a large ES/OpenSearch cluster struggles beyond 200k&#8211;300k events/sec without: massive hardware , lots of tuning and big maintenance overhead</p><p>Lesson:<br>Elasticsearch/OpenSearch is great for querying logs - not ingesting raw firehose scale directly from apps.</p><div><hr></div><p><em><strong>Related </strong>[Before reading further]</em></p><p><em>This article scratched the surface. The real interview goes 10 levels deeper.</em></p><ul><li><p><em>How do you handle hot partitions?</em></p></li><li><p><em>What if the cache goes down during a spike?</em></p></li><li><p><em>How do you avoid counting the same view twice?</em></p></li></ul><p><em>I&#8217;ve written an ebook that prepares you for all of it.</em></p><p><em>35 real problems. The patterns that solve them. The follow-ups you&#8217;ll actually face. The principles behind solving problems at scale, not just the final answers.</em></p><p><em>&#128073; <strong><a href="https://skilledcoder.gumroad.com/l/system-design">Grab your copy here</a></strong></em></p><div><hr></div><h2><strong>The Scalable Architecture</strong></h2><p>To log 1M+ events/sec without hurting latency, you need one principle:</p><blockquote><p><em><strong>Logging must be asynchronous, streamed, and decoupled from the application.</strong></em></p></blockquote><p>Here&#8217;s the architecture that works:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yUX7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F721eb15d-f43f-4e10-8e74-b4b49100519b_2400x2409.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yUX7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F721eb15d-f43f-4e10-8e74-b4b49100519b_2400x2409.png 424w, https://substackcdn.com/image/fetch/$s_!yUX7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F721eb15d-f43f-4e10-8e74-b4b49100519b_2400x2409.png 848w, https://substackcdn.com/image/fetch/$s_!yUX7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F721eb15d-f43f-4e10-8e74-b4b49100519b_2400x2409.png 1272w, https://substackcdn.com/image/fetch/$s_!yUX7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F721eb15d-f43f-4e10-8e74-b4b49100519b_2400x2409.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yUX7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F721eb15d-f43f-4e10-8e74-b4b49100519b_2400x2409.png" width="602" height="604.0673076923077" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/721eb15d-f43f-4e10-8e74-b4b49100519b_2400x2409.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1461,&quot;width&quot;:1456,&quot;resizeWidth&quot;:602,&quot;bytes&quot;:387038,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/181153628?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F721eb15d-f43f-4e10-8e74-b4b49100519b_2400x2409.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yUX7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F721eb15d-f43f-4e10-8e74-b4b49100519b_2400x2409.png 424w, https://substackcdn.com/image/fetch/$s_!yUX7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F721eb15d-f43f-4e10-8e74-b4b49100519b_2400x2409.png 848w, https://substackcdn.com/image/fetch/$s_!yUX7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F721eb15d-f43f-4e10-8e74-b4b49100519b_2400x2409.png 1272w, https://substackcdn.com/image/fetch/$s_!yUX7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F721eb15d-f43f-4e10-8e74-b4b49100519b_2400x2409.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3><strong>1) Application Layer: Non-Blocking Logging</strong></h3><ul><li><p>Use async log appenders</p></li><li><p>Logs go to in-memory ring buffers</p></li><li><p>Logging never blocks request path</p></li></ul><p>Libraries:</p><ul><li><p>Java: Logback AsyncAppender, Disruptor logging</p></li><li><p>Go: Zerolog</p></li><li><p>Node: Pino</p></li><li><p>Rust: Tracing layer</p></li></ul><p>No waiting. No flushing. No disk writes on main thread.</p><h3><strong>2) Queue or Stream: The Shock Absorber</strong></h3><p>This absorbs bursts and smooths throughput.</p><p>Use:</p><ul><li><p>Kafka</p></li><li><p>Pulsar</p></li><li><p>Kinesis</p></li><li><p>Redpanda</p></li><li><p>Google Pub/Sub</p></li></ul><p>Benefits:</p><ul><li><p>Producers write at memory speed</p></li><li><p>Consumers scale independently</p></li><li><p>Backpressure is handled automatically</p></li><li><p>Replay and retention available</p></li></ul><p>Kafka alone can handle millions/sec with proper partitions.</p><h3><strong>3) Storage Layer: Hot + Warm + Cold</strong></h3><p>Different logs need different storage.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7czC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4d6a88-6da4-4c32-982e-abf1822898fd_1420x332.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7czC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4d6a88-6da4-4c32-982e-abf1822898fd_1420x332.png 424w, https://substackcdn.com/image/fetch/$s_!7czC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4d6a88-6da4-4c32-982e-abf1822898fd_1420x332.png 848w, https://substackcdn.com/image/fetch/$s_!7czC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4d6a88-6da4-4c32-982e-abf1822898fd_1420x332.png 1272w, https://substackcdn.com/image/fetch/$s_!7czC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4d6a88-6da4-4c32-982e-abf1822898fd_1420x332.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7czC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4d6a88-6da4-4c32-982e-abf1822898fd_1420x332.png" width="728" height="170.20845070422536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7b4d6a88-6da4-4c32-982e-abf1822898fd_1420x332.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:332,&quot;width&quot;:1420,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:67159,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/181153628?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4d6a88-6da4-4c32-982e-abf1822898fd_1420x332.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7czC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4d6a88-6da4-4c32-982e-abf1822898fd_1420x332.png 424w, https://substackcdn.com/image/fetch/$s_!7czC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4d6a88-6da4-4c32-982e-abf1822898fd_1420x332.png 848w, https://substackcdn.com/image/fetch/$s_!7czC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4d6a88-6da4-4c32-982e-abf1822898fd_1420x332.png 1272w, https://substackcdn.com/image/fetch/$s_!7czC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4d6a88-6da4-4c32-982e-abf1822898fd_1420x332.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>You don&#8217;t index everything - you promote only what&#8217;s useful.</p><h3><strong>4) Observability: Metrics Over Logs (When Possible)</strong></h3><p>Not every event needs a log line.</p><p>Sometimes counters, histograms, and traces are better.</p><p>Use:</p><ul><li><p>Prometheus</p></li><li><p>OpenTelemetry</p></li><li><p>Grafana Tempo</p></li></ul><p>The mindset:</p><blockquote><p><em><strong>&#8220;Log what matters. Aggregate what repeats.&#8221;</strong></em></p></blockquote><h3><strong>Why This Architecture Works</strong></h3><p>This architecture works because logging no longer stands in the way of real work.</p><p>The app writes once and moves on - no waiting, no blocking. As traffic grows, you don&#8217;t fight the system, you just add more consumers and partitions.</p><p>Storage becomes smart instead of expensive: fast where needed, cheap everywhere else.</p><p>Even if parts fail, the system keeps absorbing events without dropping them. In the end, logs flow like a river - not a traffic jam.</p><h3><strong>Interview Answer</strong></h3><p>If asked:</p><blockquote><p><em>How would you log 1M events/sec?</em></p></blockquote><p>You respond:</p><blockquote><p><em>I wouldn&#8217;t log directly. I&#8217;d log asynchronously, push events into an in-memory buffer, stream them through Kafka, and then store them in tiers: hot for recent searchable data, warm for analytics, and cold for long retention.</em></p><p><em>That way logging never slows requests, stays durable, and scales without rewriting the system.</em></p></blockquote><h3><strong>Potential Follow Ups</strong></h3><ul><li><p>How to avoid log duplication?</p></li><li><p>How to detect ingestion lag/remove backpressure?</p></li><li><p>What if Kafka cluster goes down?</p></li><li><p>How to avoid logging sensitive/PII data?</p></li></ul><p>We&#8217;ll dive deeper into these kinds of follow-ups in upcoming articles - subscribe if you want more.</p><p>Thanks for reading. See you in next post.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/p/how-to-log-1m-eventssec-without-slowing?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://newsletter.theskilledcoder.com/p/how-to-log-1m-eventssec-without-slowing?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Is DSA Still Worth It in the AI Era?]]></title><description><![CDATA[The Moment I Realized DSA Wasn&#8217;t the Goal]]></description><link>https://newsletter.theskilledcoder.com/p/is-dsa-still-worth-it-in-the-ai-era</link><guid isPermaLink="false">https://newsletter.theskilledcoder.com/p/is-dsa-still-worth-it-in-the-ai-era</guid><dc:creator><![CDATA[Skilled Coder]]></dc:creator><pubDate>Wed, 05 Nov 2025 10:10:35 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!YnCg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa5d5591-bac1-486c-8cd0-e235f70713ce_1024x608.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_!YnCg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa5d5591-bac1-486c-8cd0-e235f70713ce_1024x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YnCg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa5d5591-bac1-486c-8cd0-e235f70713ce_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!YnCg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa5d5591-bac1-486c-8cd0-e235f70713ce_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!YnCg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa5d5591-bac1-486c-8cd0-e235f70713ce_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!YnCg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa5d5591-bac1-486c-8cd0-e235f70713ce_1024x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YnCg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa5d5591-bac1-486c-8cd0-e235f70713ce_1024x608.png" width="1024" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/aa5d5591-bac1-486c-8cd0-e235f70713ce_1024x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:608,&quot;width&quot;:1024,&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_!YnCg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa5d5591-bac1-486c-8cd0-e235f70713ce_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!YnCg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa5d5591-bac1-486c-8cd0-e235f70713ce_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!YnCg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa5d5591-bac1-486c-8cd0-e235f70713ce_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!YnCg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa5d5591-bac1-486c-8cd0-e235f70713ce_1024x608.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"></figcaption></figure></div><p>I still remember the first time I got an &#8220;Accepted&#8221; on CodeChef.</p><p>It was past midnight. My roommate was asleep, and I was hunched over a problem called &#8220;Chef and Subsequences.&#8221;<br>I&#8217;d been stuck for hours off-by-one errors, wrong answers on hidden test cases the usual pain.</p><p>When that green checkmark finally appeared, I didn&#8217;t celebrate loudly. I just leaned back, smiled, and felt that quiet satisfaction only programmers know the kind that says you earned it.</p><p>That was 2016.<br>Back then, DSA wasn&#8217;t a skill,<strong> </strong>it was a religion<br>You solved problems to prove you could think, not just code.</p><p>Fast forward to now.<br>I gave that same problem to ChatGPT and it solved it in 10 seconds.<br>Perfect output. Clean code. Explained every step like a teacher.</p><p>And I&#8217;ll be honest I didn&#8217;t feel proud or jealous.<br>I just felt&#8230; replaced.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.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">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><h3><strong>The Autocomplete Era</strong></h3><p>Here&#8217;s what nobody tells you about AI: it didn&#8217;t just make coding easier. It made a specific type of intelligence feel obsolete.</p><p>You know that friend who memorized every LeetCode medium? The one who could implement Dijkstra&#8217;s algorithm on a napkin at lunch? Yeah, ChatGPT just made them irrelevant. The thing they spent 300 hours perfecting now comes free with a $20/month subscription.</p><p>It&#8217;s like training for years to be a human calculator, only to realize everyone has an iPhone.</p><p>Brutal? Maybe. But let&#8217;s be honest when was the last time you actually implemented a trie at work? I&#8217;ve been shipping code for ten years. I&#8217;ve used binary search twice. I&#8217;ve never once needed to color a graph outside of an interview.</p><p>So why are we still here, pretending DSA matters?</p><h3><strong>Because It Does - Just Not How You Think</strong></h3><p>Some time back, our notification feed imploded during peak hours. Users were staring at loading spinners for 3&#8211;4 seconds. Our support channel lit up. My manager sent a Slack message at 9 PM: &#8220;Fix this or we&#8217;re rolling back tomorrow.&#8221;</p><p>I opened the monitoring dashboard. Average response time: 2.8 seconds. Database queries: normal. CPU: fine. Memory: fine. What the hell?</p><p>Then I looked at the actual code. Some well-meaning engineer had added a &#8220;mark as read&#8221; feature. Sounds simple, right? Except we were checking if each notification was read by querying the database. For a user with 500 notifications, that&#8217;s 500 separate database calls. Every. Single. Time.</p><p>Classic N+1 query problem.</p><p>I didn&#8217;t need a fancy algorithm. I just loaded all the &#8220;read&#8221; notification IDs into a Set upfront one query instead of 500. Checked membership with <code>notificationIds.has(id)</code> instead of hitting the database each time.</p><p>Deployed it at midnight. Response times dropped to 180ms. Not perfect, but good enough that my manager stopped pinging me.</p><p>That&#8217;s not something you&#8217;d see on LeetCode. But it&#8217;s exactly what those hash table problems were training you for : recognizing when O(n) lookups are killing you and switching to O(1).</p><p>Here&#8217;s the thing: I could&#8217;ve asked ChatGPT to &#8220;optimize this feed endpoint.&#8221; It would&#8217;ve given me twelve different solutions Redis caching, query optimization, pagination improvements, database indexing. All technically correct.</p><p>But which one solves this specific problem without requiring a two-week refactor or convincing the infrastructure team to spin up a Redis cluster?</p><p>That&#8217;s the judgment call AI can&#8217;t make. It doesn&#8217;t know your codebase is held together with duct tape. It doesn&#8217;t know your team ships every Friday and breaking things now means working the weekend. It doesn&#8217;t know your database is already at 80% capacity and adding indexes might tip it over.</p><p>That intuition, knowing what&#8217;s actually feasible in your messy production environment, comes from pattern recognition you built grinding problems for years. You just didn&#8217;t realize you were learning how to think under constraints, not just how to code.</p><h3><strong>The Real DSA Lessons Nobody Talks About</strong></h3><p>Forget the algorithms for a second. What did grinding problems actually teach you?</p><p><strong>Constraint thinking </strong>- Every problem on LeetCode starts with limits: &#8220;n &#8804; 10&#8309;&#8221; or &#8220;must run in O(n log n).&#8221; Real systems have constraints too memory budgets, latency requirements, API rate limits. DSA taught you to start every problem by asking: &#8220;What can I not do?&#8221;</p><p><strong>Trade-offs</strong> - Should you cache this? Pre-compute that? Use more memory to save CPU? These aren&#8217;t algorithm questions they&#8217;re engineering questions. But if you&#8217;ve never wrestled with time vs. space complexity, you&#8217;ll make expensive mistakes in production.</p><p><strong>Debug instincts</strong> - When something breaks and your logs are useless, you need to think your way to the root cause. That&#8217;s the same skill you used debugging that wrong answer on Test Case 47. You just didn&#8217;t realize it was transferable.</p><p>I watched my teammate spend days tracking down a memory leak in our background job processor. He was convinced it was a database connection issue adding timeouts, tweaking pool sizes, restarting workers. Finally I looked at the code: he was loading 500k records into an array, processing them one by one, then loading another 500k. The array just kept growing. &#8220;Why not process in batches of 1000 and clear memory after each batch?&#8221; Twenty minutes later, memory usage was flat. He&#8217;d never thought about how data structures behave at scale.</p><p>That&#8217;s what happens when you skip the fundamentals.</p><h3><strong>What 2025 Actually Looks Like</strong></h3><p>Let me paint you a picture of the new reality:</p><p>You&#8217;re in a design meeting. Someone suggests using Redis for session management. Another person says, &#8220;Why not just use PostgreSQL with a TTL column?&#8221; AI can&#8217;t answer that. It&#8217;ll give you both implementations, beautifully documented. But you need to know that Redis is faster but costs more, that Postgres might bottleneck at scale, that your team doesn&#8217;t have Redis expertise.</p><p>Or imagine debugging a memory leak in production. AI will analyze your heap dumps and suggest fixes. But will you trust it blindfolded? Or do you need to understand why holding references to old objects prevents garbage collection?</p><p>The engineers crushing it in 2025 aren&#8217;t the ones with perfect LeetCode scores. They&#8217;re the ones who can:</p><ul><li><p>Look at a system design and smell the bottleneck before it happens</p></li><li><p>Read AI-generated code and spot the edge case it missed</p></li><li><p>Explain to a junior dev why we chose this approach over that one</p></li></ul><p>DSA doesn&#8217;t make you better at writing code. It makes you better at thinking about code.</p><div><hr></div><p>You don&#8217;t need to know how to implement a heap from scratch.</p><p>But you damn well better understand when a priority queue is the right tool, because that knowledge will save you when you&#8217;re optimizing a job scheduler before a product launch.</p><p>You don&#8217;t need to ace every Codeforces contest.</p><p>But if you can&#8217;t recognize that your &#8220;innovative new feature&#8221; is just a variation of the two-pointer pattern, you&#8217;re going to waste weeks reinventing wheels.</p><p>AI has commoditized syntax. It hasn&#8217;t commoditized judgment.</p><h3><strong>So What Now?</strong></h3><p>If you&#8217;re early in your career, yes grind some problems. Not because Google&#8217;s going to ask you to reverse a binary tree (though they might). But because it builds mental models you&#8217;ll use forever.</p><p>If you&#8217;re experienced, you already know: DSA isn&#8217;t your competitive advantage anymore. Your ability to apply those patterns to ambiguous, real-world problems is.</p><p>The future doesn&#8217;t belong to people who can reiterate algorithms. It belongs to people who can look at a pile of AI-generated solutions and know which one won&#8217;t fall apart under load.</p><p>AI may know all the answers.</p><p>But someone still needs to know which questions are worth asking.</p><p>And that someone better understand why hash maps exist.</p><div><hr></div><p><strong>Related</strong></p><p>If you enjoy digging into how things actually work, I&#8217;ve been working on something larger alongside these articles.</p><p>I wrote an ebook that walks through <strong>35 real engineering problems</strong>, focusing on how decisions break down at scale, what trade-offs actually matter, and the kinds of follow-up questions engineers run into in interviews and real systems.</p><p>It&#8217;s less about memorizing solutions, and more about learning the <strong>principles behind solving problems at scale</strong> - so you can reason through new situations, not just familiar ones.</p><p>&#128073; <strong><a href="https://skilledcoder.gumroad.com/l/system-design">Grab your copy here</a></strong></p><p>Thanks for reading. See you in the next post.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/p/is-dsa-still-worth-it-in-the-ai-era?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://newsletter.theskilledcoder.com/p/is-dsa-still-worth-it-in-the-ai-era?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p>]]></content:encoded></item><item><title><![CDATA[How would you design a system to send 100,000 notifications?]]></title><description><![CDATA[Designing a Notification System That Actually Scales]]></description><link>https://newsletter.theskilledcoder.com/p/how-would-you-design-a-system-to</link><guid isPermaLink="false">https://newsletter.theskilledcoder.com/p/how-would-you-design-a-system-to</guid><dc:creator><![CDATA[Skilled Coder]]></dc:creator><pubDate>Wed, 01 Oct 2025 05:10:52 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1685381949388-bb0402fbe133?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw1fHxub3RpZmljYXRpb258ZW58MHx8fHwxNzU5Mjk1MzEwfDA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080" 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://images.unsplash.com/photo-1685381949388-bb0402fbe133?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw1fHxub3RpZmljYXRpb258ZW58MHx8fHwxNzU5Mjk1MzEwfDA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://images.unsplash.com/photo-1685381949388-bb0402fbe133?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw1fHxub3RpZmljYXRpb258ZW58MHx8fHwxNzU5Mjk1MzEwfDA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1685381949388-bb0402fbe133?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw1fHxub3RpZmljYXRpb258ZW58MHx8fHwxNzU5Mjk1MzEwfDA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1685381949388-bb0402fbe133?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw1fHxub3RpZmljYXRpb258ZW58MHx8fHwxNzU5Mjk1MzEwfDA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1685381949388-bb0402fbe133?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw1fHxub3RpZmljYXRpb258ZW58MHx8fHwxNzU5Mjk1MzEwfDA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080 1456w" sizes="100vw"><img src="https://images.unsplash.com/photo-1685381949388-bb0402fbe133?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw1fHxub3RpZmljYXRpb258ZW58MHx8fHwxNzU5Mjk1MzEwfDA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080" width="4500" height="3000" data-attrs="{&quot;src&quot;:&quot;https://images.unsplash.com/photo-1685381949388-bb0402fbe133?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw1fHxub3RpZmljYXRpb258ZW58MHx8fHwxNzU5Mjk1MzEwfDA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:3000,&quot;width&quot;:4500,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;a white square with a red circle on top of it&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpg&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="a white square with a red circle on top of it" title="a white square with a red circle on top of it" srcset="https://images.unsplash.com/photo-1685381949388-bb0402fbe133?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw1fHxub3RpZmljYXRpb258ZW58MHx8fHwxNzU5Mjk1MzEwfDA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1685381949388-bb0402fbe133?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw1fHxub3RpZmljYXRpb258ZW58MHx8fHwxNzU5Mjk1MzEwfDA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1685381949388-bb0402fbe133?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw1fHxub3RpZmljYXRpb258ZW58MHx8fHwxNzU5Mjk1MzEwfDA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1685381949388-bb0402fbe133?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw1fHxub3RpZmljYXRpb258ZW58MHx8fHwxNzU5Mjk1MzEwfDA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"></figcaption></figure></div><p>Every modern product whether it&#8217;s a banking app, a ride-sharing platform, or a social network depends on one invisible yet powerful system: notifications.</p><p>They&#8217;re the tiny nudges that keep your product alive and your users informed.</p><ul><li><p>A push when your cab is 2 minutes away</p></li><li><p>An SMS with your OTP</p></li><li><p>An email confirming your order</p></li></ul><p>Seems simple enough, right? Just send a message.</p><p>But here&#8217;s where the trap lies &#128071;</p><blockquote><p><em>At small scale, everything feels easy. At scale, everything breaks.</em></p></blockquote><p>For a prototype, you can literally loop over all users and call your provider&#8217;s API. Works fine for a few hundred users.<br>But when you need to send 100,000+ messages, &#8220;just send&#8221; quickly turns into &#8220;why is nothing working?&#8221;</p><p>Let&#8217;s see why.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.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"> 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></p><h2><strong>Why This Problem Is Deceptively Hard</strong></h2><p>Imagine a banking app where 100,000 transactions fail due to a temporary outage.<br>You need to alert all affected users and fast.</p><p>What looks like a simple &#8220;send notifications&#8221; job now becomes a distributed system problem.</p><p>You&#8217;re suddenly fighting on multiple fronts:</p><ul><li><p><strong>Throughput</strong> - Can you send thousands per second, not per hour?</p></li><li><p><strong>Reliability</strong> - What if FCM or SMTP is slow or returns 5xx errors?</p></li><li><p><strong>Idempotency</strong> - If your service crashes mid-way, can you retry safely without duplicates?</p></li><li><p><strong>Scalability</strong> - Will it still hold if you jump from 100k &#8594; 1M tomorrow?</p></li><li><p><strong>Observability</strong> - How do you know what succeeded, failed, or got delayed?</p></li></ul><p>These five are the pillars every resilient notification system must solve.</p><h2><strong>First Attempts (and Why They Fail)</strong></h2><h3><strong>Approach 1: Loop and Send Directly</strong></h3><p><strong>Idea: </strong>Just iterate through all users and send via Email/SMS/Push provider.</p><pre><code>for user in users:
    sendNotification(user)</code></pre><p><strong>Why it feels right:</strong><br>Simple. Easy to code. Works perfectly in dev.</p><p><strong>Why it fails:</strong><br>Each call might take ~300ms.<br>100k &#215; 300ms = 30,000 seconds &#8594; 8+ hours!</p><p>You can try threading, but you&#8217;ll hit:</p><ul><li><p>Provider rate limits</p></li><li><p>Connection errors</p></li><li><p>Duplicate sends on retries</p></li></ul><p>If your process crashes mid-way, you&#8217;ve no clue who got what.</p><p><strong>Lesson:</strong> Code simplicity &#8800; system simplicity. Throughput and fault tolerance don&#8217;t come free.</p><h3><strong>Approach 2: Use Database as a Queue</strong></h3><p><strong>Idea: </strong>Insert all notifications in a table:</p><pre><code>INSERT INTO notifications (user_id, status)
VALUES (user_id, &#8216;PENDING&#8217;)</code></pre><p>A worker picks up <code>PENDING</code>, sends it, then marks <code>SENT</code>.</p><p><strong>Why it feels right:</strong><br>SQL is reliable. Transactions give confidence. You can <code>count(*)</code> to see progress.</p><p><strong>Why it fails:</strong><br>At 100k+, your DB becomes the bottleneck:</p><ul><li><p>Hot rows &amp; lock contention</p></li><li><p>Slow vacuuming</p></li><li><p>Replication lag</p></li></ul><p>DBs are great at state, not streaming events.<br>You&#8217;re forcing it to do something it wasn&#8217;t built for.</p><p><strong>Lesson:</strong> Don&#8217;t turn your source of truth into a message queue.</p><h3><strong>Approach 3: Cron Job Batches</strong></h3><p><strong>Idea: </strong>Run a job every minute that sends pending messages.</p><p><strong>Why it feels right:</strong><br>Scheduled jobs = easy mental model. &#8220;Send everything due now.&#8221;</p><p><strong>Why it fails:</strong><br>At the top of the minute &#8594; a burst of 100k requests.<br>Providers respond with 429 (rate-limit) or block your IP.<br>Your &#8220;real-time&#8221; notification now has up to 59s latency.</p><p><strong>Lesson:</strong> Batching helps organization, not elasticity.</p><div><hr></div><h2><strong>The Scalable Approach</strong></h2><p>To scale gracefully, separate concerns:</p><blockquote><p><em>&#8220;Deciding what to send&#8221; &#8800; &#8220;Actually sending it&#8221;</em></p></blockquote><p>Think of it as an assembly line:</p><ol><li><p>A producer decides what needs sending</p></li><li><p>A queue manages the flow</p></li><li><p>Workers deliver at safe speed</p></li><li><p>Metrics keep you informed</p></li></ol><p>Let&#8217;s break it down.</p><h3><strong>1. Producer Service (Brain)</strong></h3><ul><li><p>Figures out who to notify (recipients)</p></li><li><p>Prepares personalized payloads (<code>Hello, Tom &#128075;</code>)</p></li><li><p>Publishes one message per user into a queue</p></li></ul><p>It&#8217;s stateless: you can run multiple producers in parallel.<br>It doesn&#8217;t care when it&#8217;s delivered &#8212; just that it&#8217;s enqueued.</p><h3><strong>2. Queue or Stream (Buffer)</strong></h3><p>Use something like SQS, RabbitMQ, Kafka, Pub/Sub.</p><p><strong>Why?</strong></p><ul><li><p>Absorbs bursts &#8212; workers can pull at their own pace</p></li><li><p>Handles retries gracefully</p></li><li><p>Offers DLQ (Dead Letter Queue) for poison messages</p></li><li><p>Enables backpressure &#8212; if providers slow down, queue length grows, not your CPU usage</p></li></ul><p>Think of it as a shock absorber in your system.</p><h3><strong>3. Delivery Workers (Hands)</strong></h3><p>Each channel (push, email, SMS) has its own workers.</p><p>They:</p><ul><li><p>Pull messages at a controlled rate</p></li><li><p>Enforce per-provider rate limits (avoid bans)</p></li><li><p>Use idempotency keys (<code>campaign_id + user_id + channel</code>)</p></li><li><p>Retry transient failures (e.g. network blips) with exponential backoff</p></li><li><p>Send unrecoverable ones to DLQ for manual retry/inspection</p></li></ul><p>Parallelize with more workers. They can scale horizontally.</p><h3><strong>4. Observability (Eyes)</strong></h3><p>You can&#8217;t fix what you can&#8217;t see.</p><p>Track:</p><ul><li><p><strong>Metrics</strong>: enqueue/sent/failed/sec, retries, p95 latency</p></li><li><p><strong>Logs</strong>: idempotency key + provider response codes</p></li><li><p><strong>Alerts</strong>: spikes in DLQ, latency breaches, 5xx rates</p></li></ul><p>Use tools like Prometheus + Grafana or Datadog.<br>Even a simple dashboard helps detect silent failures early.</p><h2><strong>Why This Architecture Works</strong></h2><p><strong>Throughput:</strong><br>50 workers &#215; 35 req/s = ~1,750 req/s &#8594; <strong>100k in ~1 minute</strong></p><p><strong>Reliability:</strong><br>Queue buffers bursts, retries are idempotent.</p><p><strong>Scalability:</strong><br>Add workers; partition queues, scale independently.</p><p><strong>Correctness:</strong><br>Idempotency prevents duplicates, DLQ captures bad events.</p><p><strong>Visibility:</strong><br>Metrics &amp; alerts show real-time health.</p><p>This is first-principles engineering:</p><ul><li><p>Decouple producers &amp; consumers</p></li><li><p>Isolate failures</p></li><li><p>Scale horizontally</p></li><li><p>Design for retries &amp; observability</p></li></ul><h3><strong>Interview Pivot (How to Explain It)</strong></h3><p>If asked in an interview &#128071;</p><blockquote><p><em>&#8220;How would you design a system to send 100,000 notifications?&#8221;</em></p></blockquote><p>You say:</p><blockquote><p><em>&#8220;Naively, I&#8217;d loop through all users and call the provider directly but that couples expansion and delivery, and breaks with retries or rate limits.<br>Instead, I&#8217;d split concerns:<br>A producer expands recipients and enqueues messages.<br>Workers consume from the queue at a safe pace, enforce per-provider rate limits, use idempotency keys to prevent duplicates, and push failed messages to a DLQ.<br>That gives me high throughput, safety, and visibility 100k notifications in minutes, and scalable to millions.&#8221;</em></p></blockquote><p>That&#8217;s not just an answer that&#8217;s a design mindset.</p><h2><strong>What&#8217;s Next?</strong></h2><p>We&#8217;ve laid the foundation - a robust, scalable notification system.<br>But there&#8217;s more to explore if you really want to think like an architect:</p><ul><li><p>How do we ensure each notification is sent exactly once?</p></li><li><p>How do we handle sudden spikes, like 1 million events per second?</p></li><li><p>What if iOS consumers stop working and fail to receive notifications?</p></li><li><p>How do we alert engineers automatically when something breaks?</p></li></ul><p>We&#8217;ll tackle these real-world challenges one by one in upcoming articles. Stay tuned.</p><div><hr></div><p><strong>Related</strong></p><p>This article scratched the surface. The real interview goes 10 levels deeper.</p><ul><li><p>How do you handle hot partitions?</p></li><li><p>What if the cache goes down during a spike?</p></li><li><p>How do you avoid counting the same view twice?</p></li></ul><p>I&#8217;ve written an ebook that prepares you for <strong>all of it</strong>.</p><p>35 real problems. The patterns that solve them. The follow-ups you&#8217;ll actually face. The principles behind solving problems at scale, not just the final answers.</p><p>&#128073; <strong><a href="https://skilledcoder.gumroad.com/l/system-design">Grab your copy here</a></strong></p><p>Thanks for reading. See you in next post.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/p/how-would-you-design-a-system-to?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://newsletter.theskilledcoder.com/p/how-would-you-design-a-system-to?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[The Hardest Part of Engineering Isn’t Programming]]></title><description><![CDATA[It&#8217;s alignment, collaboration, and making systems work inside organizations]]></description><link>https://newsletter.theskilledcoder.com/p/the-hardest-part-of-engineering-isnt</link><guid isPermaLink="false">https://newsletter.theskilledcoder.com/p/the-hardest-part-of-engineering-isnt</guid><dc:creator><![CDATA[Skilled Coder]]></dc:creator><pubDate>Sat, 06 Sep 2025 12:33:12 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!4z_0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F187741ea-e2bb-4b02-9207-228f6e59bb19_1024x608.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_!4z_0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F187741ea-e2bb-4b02-9207-228f6e59bb19_1024x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4z_0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F187741ea-e2bb-4b02-9207-228f6e59bb19_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!4z_0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F187741ea-e2bb-4b02-9207-228f6e59bb19_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!4z_0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F187741ea-e2bb-4b02-9207-228f6e59bb19_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!4z_0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F187741ea-e2bb-4b02-9207-228f6e59bb19_1024x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4z_0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F187741ea-e2bb-4b02-9207-228f6e59bb19_1024x608.png" width="1024" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/187741ea-e2bb-4b02-9207-228f6e59bb19_1024x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:608,&quot;width&quot;:1024,&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_!4z_0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F187741ea-e2bb-4b02-9207-228f6e59bb19_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!4z_0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F187741ea-e2bb-4b02-9207-228f6e59bb19_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!4z_0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F187741ea-e2bb-4b02-9207-228f6e59bb19_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!4z_0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F187741ea-e2bb-4b02-9207-228f6e59bb19_1024x608.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"></figcaption></figure></div><p>A few months back, I found myself staring at a problem that felt deceptively simple:<br><strong>&#8220;We need a unified view of how our APIs are doing across the company.&#8221;</strong></p><p>Sounds easy, right? Just throw some dashboards, grab a few metrics, and boom job done.<br>Except, no. This was one of those problems where the devil wasn&#8217;t in the details, the devil was the details.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.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">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><h3><strong>Background</strong></h3><p>Our company had APIs everywhere - some powering core products, others quietly serving backend needs, and many more that just&#8230; existed. But no matter how important or obscure, they all had one thing in common:</p><p>Nobody had a single view of how they were doing.</p><ul><li><p>Were they following governance standards?</p></li><li><p>Did they meet latency SLAs (P95, P99)?</p></li><li><p>Were they failing silently somewhere?</p></li></ul><p>Each team had their own dashboards, their own logs, their own way of tracking. Imagine trying to run a city where every neighborhood has its own maps, traffic lights, and bylaws but nobody talks to each other. That&#8217;s where we were.</p><p>Our mission: build a &#8220;control tower&#8221; for all APIs in one place.</p><h3><strong>The Naive First Answer: &#8220;Just Read the Logs&#8221;</strong></h3><p>The obvious first thought was: well, the data already exists. APIs log everything - successes, failures, latencies, requests. Just scoop it up.</p><p>Then we asked our edge gateways what they were logging, the answer came back like a punch:</p><p><strong>20&#8211;25 terabytes of logs per day. Billions of events.</strong></p><p>Let that sink in. Every. Single. Day.</p><p>That meant:</p><ul><li><p>Gigantic ingestion pipelines.</p></li><li><p>Massive storage costs (cold + hot tiers).</p></li><li><p>Complex transformation logic before we could even query anything useful.</p></li></ul><p>What sounded like &#8220;just read the logs&#8221; turned into &#8220;build a data warehouse project the size of a small startup.&#8221;</p><h3><strong>Talking to the Gatekeepers</strong></h3><p>The next step was obvious but painful: talk to the teams running these edge gateways.</p><p>This is where the non-technical pain starts:</p><ul><li><p>They spoke a different &#8220;language&#8221; than us - security and infra-first, while we cared about API-level insights.</p></li><li><p>Their logs had dozens of fields we didn&#8217;t care about, and were missing fields we desperately needed.</p></li><li><p>They already had their workflows; our requests felt like interruptions.</p></li></ul><p>We had to set up meeting after meeting:</p><ul><li><p>&#8220;What exactly are you logging?&#8221;</p></li><li><p>&#8220;Can we get field X?&#8221;</p></li><li><p>&#8220;What does this cryptic field mean?&#8221;</p></li><li><p>&#8220;Oh, you&#8217;re logging to Splunk - can we tap into it?&#8221;</p></li></ul><p>And yes, Splunk had all the data. But it wasn&#8217;t designed for the kind of structured, API-centric queries we wanted.</p><h3><strong>The Pain of Building From Scratch</strong></h3><p>At this point, the obvious engineering option was:</p><ul><li><p>Ingest logs from Splunk.</p></li><li><p>Store them in S3 or Databricks.</p></li><li><p>Build structured tables.</p></li><li><p>Layer insights pipelines on top.</p></li></ul><p>It sounds like progress&#8230; but think about the effort:</p><ul><li><p><strong>Time</strong>: months just to get ingestion stable.</p></li><li><p><strong>Cost</strong>: storing petabytes within weeks.</p></li><li><p><strong>Ops Overhead</strong>: keeping pipelines alive against daily terabytes.</p></li><li><p><strong>Redundancy</strong>: building yet another giant data system when the company already had dozens.</p></li></ul><p>It felt wrong. Painfully wrong.</p><h3><strong>The Twist: Someone Already Did the Hard Part</strong></h3><p>Here&#8217;s where luck and persistence collide.</p><p>While poking around, we discovered another team in the company had already built a massive ingestion pipeline - for security events.</p><ul><li><p>They were reading from <strong>60+ different log sources</strong>.</p></li><li><p>Normalizing data into the <strong>OCSF format </strong>(Standard Logging).</p></li><li><p>Storing everything in structured tables.</p></li><li><p>Running Kafka, databases, pipelines - the whole machinery.</p></li></ul><p>They weren&#8217;t solving our problem, but the foundation was eerily similar.</p><p>So we had a choice:</p><ul><li><p><strong>Option A:</strong> Keep building our own &#8220;parallel empire,&#8221; doubling costs and effort.</p></li><li><p><strong>Option B:</strong> Swallow our ego, walk over, and ask to collaborate.</p></li></ul><p>We chose Option B.</p><h3><strong>Collaboration &#8800; Easy</strong></h3><p>Now, collaboration sounds noble in principle. But in practice, it&#8217;s one of the hardest things in engineering.</p><ul><li><p>Their priorities were security, ours were API observability.</p></li><li><p>Their timelines were different.</p></li><li><p>Their formats weren&#8217;t built with APIs in mind.</p></li><li><p>And, let&#8217;s be honest, not everyone likes outsiders coming in with &#8220;we want to use your system for our stuff.&#8221;</p></li></ul><p>It took weeks - literally three to four weeks - of discussions, clarifications, requirement docs, and alignment calls.</p><p>Some conversations went in circles:</p><ul><li><p>&#8220;Can we add these fields?&#8221;</p></li><li><p>&#8220;Will your pipeline support our query scale?&#8221;</p></li><li><p>&#8220;How much additional load will this put on you?&#8221;</p></li></ul><p>At times, it felt like more diplomacy than engineering.</p><h3><strong>The 10% Coding Myth</strong></h3><p>Here&#8217;s the part that might shock a lot of junior engineers: the actual coding part of this project was maybe 10&#8211;15% of the total effort.</p><p>The rest?</p><ul><li><p>Negotiating requirements.</p></li><li><p>Understanding existing systems.</p></li><li><p>Aligning with teams who didn&#8217;t always share our goals.</p></li><li><p>Making trade-offs with cost, scale, and compliance.</p></li><li><p>Documenting and explaining why we weren&#8217;t reinventing the wheel.</p></li></ul><p>And this is the pain nobody prepares you for: the pain of alignment.</p><h3><strong>Where AI Still Fails</strong></h3><p>People often ask: <em>&#8220;Why won&#8217;t AI replace engineers soon?&#8221;</em></p><p>Here&#8217;s why:</p><p>AI can generate SQL queries, code snippets, maybe even pipeline scripts. But it can&#8217;t:</p><ul><li><p>Sit in a room with five stakeholders and resolve conflicting goals.</p></li><li><p>Decide whether to build vs reuse based on organizational context.</p></li><li><p>Balance storage costs against real-time needs.</p></li><li><p>Handle the messy human side of building systems inside large organizations.</p></li></ul><p>That&#8217;s the stuff that eats up months and it&#8217;s the stuff AI can&#8217;t touch (yet).</p><h3><strong>The Endgame</strong></h3><p>Eventually, we piggybacked on the existing ingestion pipeline.</p><p>We stored billions of events in cold storage, moved slices into hot storage for fast queries, and built insights pipelines on top.</p><p>The result: a working API observability layer without rebuilding the entire ingestion empire from scratch.</p><p>But the lesson wasn&#8217;t just about logs, APIs, or storage tiers.</p><p>Engineering is not just:</p><ul><li><p>Knowing the best data structure.</p></li><li><p>Writing the cleanest code.</p></li><li><p>Or deploying the fastest service.</p></li></ul><p>It&#8217;s about solving problems <em><strong>inside the real-world mess</strong></em>:</p><ul><li><p>Systems already exist, often imperfectly.</p></li><li><p>People have competing goals.</p></li><li><p>Costs and trade-offs matter.</p></li><li><p>Reinventing the wheel is easy but dangerous.</p></li></ul><p><strong>Engineering = 20% tech, 80% alignment.</strong></p><p>That&#8217;s the truth no coding tutorial tells you.</p><p>When I look back, the story wasn&#8217;t about APIs at all. It was about realizing that as you grow in your career, the bottleneck isn&#8217;t your coding speed. It&#8217;s your ability to navigate systems - technical, organizational, and human.</p><p>And if you ever find yourself drowning in 25 terabytes of logs a day, remember: the solution might not be another line of code. It might be a conversation.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.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[YouTube System Design from First Principles]]></title><description><![CDATA[Explained Like You&#8217;re 5, But Smarter]]></description><link>https://newsletter.theskilledcoder.com/p/youtube-system-design-from-first</link><guid isPermaLink="false">https://newsletter.theskilledcoder.com/p/youtube-system-design-from-first</guid><dc:creator><![CDATA[Skilled Coder]]></dc:creator><pubDate>Sun, 31 Aug 2025 11:49:47 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Nawc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21df2497-214f-48dc-a205-c31084eda4d3_1024x608.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_!Nawc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21df2497-214f-48dc-a205-c31084eda4d3_1024x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Nawc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21df2497-214f-48dc-a205-c31084eda4d3_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!Nawc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21df2497-214f-48dc-a205-c31084eda4d3_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!Nawc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21df2497-214f-48dc-a205-c31084eda4d3_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!Nawc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21df2497-214f-48dc-a205-c31084eda4d3_1024x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Nawc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21df2497-214f-48dc-a205-c31084eda4d3_1024x608.png" width="1024" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/21df2497-214f-48dc-a205-c31084eda4d3_1024x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:608,&quot;width&quot;:1024,&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_!Nawc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21df2497-214f-48dc-a205-c31084eda4d3_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!Nawc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21df2497-214f-48dc-a205-c31084eda4d3_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!Nawc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21df2497-214f-48dc-a205-c31084eda4d3_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!Nawc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21df2497-214f-48dc-a205-c31084eda4d3_1024x608.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"></figcaption></figure></div><p>We want to let users upload a video and let millions of other users watch it smoothly.<br>That sounds simple, but videos are huge (hundreds of MBs), networks are unreliable, and viewers expect instant playback.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.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"> 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></p><p>So our design has to solve:</p><ul><li><p>Storing large video files safely.</p></li><li><p>Converting them so they play well on all devices.</p></li><li><p>Delivering them fast worldwide.</p></li><li><p>Scaling as traffic grows from 10 users to millions.</p></li></ul><div><hr></div><h2><strong>Minimum Viable Product (MVP)</strong></h2><p>Let&#8217;s start with the simplest working version.</p><h3><strong>Components</strong></h3><p><strong>Client Upload &#8594; Object Storage</strong></p><ul><li><p>Instead of sending a huge file through our server, the client uploads directly to Object Storage (like Amazon S3 or Google Cloud Storage).</p></li><li><p>Why? Because it&#8217;s built to store huge files, automatically replicated, and cheap.</p></li></ul><p><strong>App Server (Metadata)</strong></p><ul><li><p>Handles small data: title, description, user info, publish status.</p></li><li><p>Stores this in a Relational Database (Postgres/MySQL).</p></li></ul><p><strong>Transcoding Service (Video Processor)</strong></p><ul><li><p>Takes the uploaded raw video and converts it into multiple formats (240p, 480p, 720p).</p></li><li><p>Why? Different devices and network speeds &#8594; different quality needed.</p></li></ul><p><strong>CDN (Content Delivery Network)</strong></p><ul><li><p>A global network of servers that caches video segments close to users.</p></li><li><p>Why? Without CDN, every play would hit our storage directly &#8594; slow and expensive.</p></li></ul><p><strong>Queue (Task Manager)</strong></p><ul><li><p>When a video is uploaded, we push a &#8220;transcode this file&#8221; job into a queue.</p></li><li><p>Workers pull jobs one by one &#8594; keeps system stable even if thousands of uploads happen.</p></li></ul><p><strong>Database Glimpse</strong></p><pre><code>-- Who uploaded what
CREATE TABLE users (
  id BIGINT PRIMARY KEY,
  name VARCHAR(100),
  email VARCHAR(200) UNIQUE
);

-- Core video table
CREATE TABLE videos (
  id BIGINT PRIMARY KEY,
  owner_id BIGINT REFERENCES users(id),
  title VARCHAR(200),
  description TEXT,
  status VARCHAR(20),   -- uploaded, processing, published
  created_at TIMESTAMP
);

-- Which renditions exist
CREATE TABLE renditions (
  video_id BIGINT REFERENCES videos(id),
  quality VARCHAR(10),  -- 240p, 480p, 720p
  path TEXT,            -- storage/CDN path
  PRIMARY KEY(video_id, quality)
);</code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XL25!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ed876f2-c055-4e5b-9d19-8a12298f3fcd_960x1192.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XL25!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ed876f2-c055-4e5b-9d19-8a12298f3fcd_960x1192.png 424w, https://substackcdn.com/image/fetch/$s_!XL25!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ed876f2-c055-4e5b-9d19-8a12298f3fcd_960x1192.png 848w, https://substackcdn.com/image/fetch/$s_!XL25!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ed876f2-c055-4e5b-9d19-8a12298f3fcd_960x1192.png 1272w, https://substackcdn.com/image/fetch/$s_!XL25!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ed876f2-c055-4e5b-9d19-8a12298f3fcd_960x1192.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XL25!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ed876f2-c055-4e5b-9d19-8a12298f3fcd_960x1192.png" width="630" height="782.25" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1ed876f2-c055-4e5b-9d19-8a12298f3fcd_960x1192.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1192,&quot;width&quot;:960,&quot;resizeWidth&quot;:630,&quot;bytes&quot;:191292,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/172395245?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ed876f2-c055-4e5b-9d19-8a12298f3fcd_960x1192.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XL25!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ed876f2-c055-4e5b-9d19-8a12298f3fcd_960x1192.png 424w, https://substackcdn.com/image/fetch/$s_!XL25!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ed876f2-c055-4e5b-9d19-8a12298f3fcd_960x1192.png 848w, https://substackcdn.com/image/fetch/$s_!XL25!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ed876f2-c055-4e5b-9d19-8a12298f3fcd_960x1192.png 1272w, https://substackcdn.com/image/fetch/$s_!XL25!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ed876f2-c055-4e5b-9d19-8a12298f3fcd_960x1192.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Why This Works (MVP)</strong></p><ul><li><p>Simple: only 5 moving parts.</p></li><li><p>Resilient: queue prevents overload.</p></li><li><p>Cost-efficient: CDN cuts bandwidth bills, storage is cheap.</p></li></ul><p>But&#8230; it&#8217;s limited:</p><ul><li><p>Startup latency (may take 2&#8211;3 seconds to buffer).</p></li><li><p>Limited quality options.</p></li><li><p>All running in one region &#8594; bad for global users.</p></li></ul><div><hr></div><h2><strong>Scaling Up (When Traffic Grows)</strong></h2><p>When our MVP gets popular (say, 100k uploads/day, 1M viewers), cracks appear. Let&#8217;s evolve step by step.</p><h3><strong>Playback Experience</strong></h3><p><strong>Issue:</strong> Viewers wait 2&#8211;3 seconds before playback begins.</p><p><strong>Solution:</strong> Preload the first few seconds into the CDN as soon as a video is published. Playback feels instant.</p><p><strong>Upgrade:</strong> Add higher qualities like 1080p, but only for videos that cross a popularity threshold. This saves storage and processing costs.</p><h3><strong>Database Load</strong></h3><p><strong>Issue:</strong> With millions of requests, the relational database struggles with queries like trending videos, likes, and search.</p><p><strong>Solution:</strong></p><ul><li><p>Add a cache (Redis) for popular data.</p></li><li><p>Use a search index (Elasticsearch) for fast lookups.</p></li></ul><pre><code>-- Daily view counts (approximate is fine)
CREATE TABLE video_views (
  video_id BIGINT REFERENCES videos(id),
  day DATE,
  approx_count BIGINT,
  PRIMARY KEY(video_id, day)
);</code></pre><p>Exact counters aren&#8217;t necessary; eventual consistency is good enough for user experience.</p><h3><strong>Cost Control</strong></h3><p><strong>Issue:</strong> Storage and bandwidth bills grow rapidly.</p><p><strong>Solution:</strong></p><ul><li><p>Move older, rarely watched videos to cold storage.</p></li><li><p>Use per-title encoding to compress intelligently, cutting bandwidth by 20&#8211;40%.</p></li></ul><h3><strong>Global Expansion</strong></h3><p><strong>Issue:</strong> A viewer in UK fetching video data from a US server faces high latency.</p><p><strong>Solution:</strong> Replicate storage across regions and let CDNs serve videos from the nearest origin.</p><h3><strong>Reliability and Failures</strong></h3><p><strong>Issue:</strong> Transcoding jobs pile up or storage has a temporary outage.</p><p><strong>Solution:</strong></p><ul><li><p>Use dead-letter queues to handle failed jobs.</p></li><li><p>Autoscale worker pools; temporarily skip highest quality and backfill later.</p></li><li><p>Multi-region storage ensures redundancy.</p></li></ul><div><hr></div><h3><strong>Lessons from YouTube&#8217;s Growth</strong></h3><p>From a single bucket and database, the system grows into a global platform:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DF1a!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88e06a76-5a84-4bd2-815b-dee3c38be212_1232x326.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DF1a!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88e06a76-5a84-4bd2-815b-dee3c38be212_1232x326.png 424w, https://substackcdn.com/image/fetch/$s_!DF1a!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88e06a76-5a84-4bd2-815b-dee3c38be212_1232x326.png 848w, https://substackcdn.com/image/fetch/$s_!DF1a!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88e06a76-5a84-4bd2-815b-dee3c38be212_1232x326.png 1272w, https://substackcdn.com/image/fetch/$s_!DF1a!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88e06a76-5a84-4bd2-815b-dee3c38be212_1232x326.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DF1a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88e06a76-5a84-4bd2-815b-dee3c38be212_1232x326.png" width="722" height="191.0487012987013" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/88e06a76-5a84-4bd2-815b-dee3c38be212_1232x326.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:326,&quot;width&quot;:1232,&quot;resizeWidth&quot;:722,&quot;bytes&quot;:56861,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/172395245?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88e06a76-5a84-4bd2-815b-dee3c38be212_1232x326.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!DF1a!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88e06a76-5a84-4bd2-815b-dee3c38be212_1232x326.png 424w, https://substackcdn.com/image/fetch/$s_!DF1a!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88e06a76-5a84-4bd2-815b-dee3c38be212_1232x326.png 848w, https://substackcdn.com/image/fetch/$s_!DF1a!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88e06a76-5a84-4bd2-815b-dee3c38be212_1232x326.png 1272w, https://substackcdn.com/image/fetch/$s_!DF1a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88e06a76-5a84-4bd2-815b-dee3c38be212_1232x326.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>We started with the simplest version of YouTube: a bucket for files, a database for metadata, and a queue for processing. That was enough for the first few thousand users.</p><p>But real systems don&#8217;t stay small. As traffic grew, new challenges appeared one by one: buffering, database overload, rising costs, global latency, and reliability concerns. Each time, the solution wasn&#8217;t magic it was applying first principles:</p><ul><li><p>Keep data close to users.</p></li><li><p>Optimize for real-world networks.</p></li><li><p>Spend compute and storage only where it creates visible value.</p></li><li><p>Design for failure so the system bends instead of breaking.</p></li></ul><p>The end result is what we see today: a system that can absorb millions of uploads and serve billions of daily views without users thinking twice about what happens behind the scenes.</p><div><hr></div><p>System design isn&#8217;t about memorizing complex diagrams it&#8217;s about starting with a clear mental model, asking <em>&#8220;what must always be true?&#8221;</em>, and evolving step by step as scale demands.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/p/youtube-system-design-from-first?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://newsletter.theskilledcoder.com/p/youtube-system-design-from-first?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.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[Why Postgres Made MongoDB Less Special]]></title><description><![CDATA[The NoSQL Revolution That Strengthened SQL]]></description><link>https://newsletter.theskilledcoder.com/p/why-postgres-made-mongodb-less-special</link><guid isPermaLink="false">https://newsletter.theskilledcoder.com/p/why-postgres-made-mongodb-less-special</guid><dc:creator><![CDATA[Skilled Coder]]></dc:creator><pubDate>Tue, 12 Aug 2025 14:18:11 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!-C0Q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7cce4-8592-4307-bc1b-02a1264b6c23_1098x577.heic" 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_!-C0Q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7cce4-8592-4307-bc1b-02a1264b6c23_1098x577.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-C0Q!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7cce4-8592-4307-bc1b-02a1264b6c23_1098x577.heic 424w, https://substackcdn.com/image/fetch/$s_!-C0Q!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7cce4-8592-4307-bc1b-02a1264b6c23_1098x577.heic 848w, https://substackcdn.com/image/fetch/$s_!-C0Q!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7cce4-8592-4307-bc1b-02a1264b6c23_1098x577.heic 1272w, https://substackcdn.com/image/fetch/$s_!-C0Q!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7cce4-8592-4307-bc1b-02a1264b6c23_1098x577.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-C0Q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7cce4-8592-4307-bc1b-02a1264b6c23_1098x577.heic" width="1098" height="577" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2cb7cce4-8592-4307-bc1b-02a1264b6c23_1098x577.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:577,&quot;width&quot;:1098,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:18987,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://newsletter.theskilledcoder.com/i/170789431?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7cce4-8592-4307-bc1b-02a1264b6c23_1098x577.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-C0Q!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7cce4-8592-4307-bc1b-02a1264b6c23_1098x577.heic 424w, https://substackcdn.com/image/fetch/$s_!-C0Q!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7cce4-8592-4307-bc1b-02a1264b6c23_1098x577.heic 848w, https://substackcdn.com/image/fetch/$s_!-C0Q!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7cce4-8592-4307-bc1b-02a1264b6c23_1098x577.heic 1272w, https://substackcdn.com/image/fetch/$s_!-C0Q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7cce4-8592-4307-bc1b-02a1264b6c23_1098x577.heic 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>In the early 2010s, MongoDB was everywhere.<br>Meetups, blog posts, hackathons everyone was saying the same thing:<br>Forget SQL. Just store JSON and ship faster.</p><p>And for a certain kind of project, MongoDB was a breath of fresh air. No schemas, easy to install, and &#8220;web scale&#8221; (a phrase that became a meme after that infamous video).</p><p>But hype doesn&#8217;t last forever.</p><div><hr></div><h3><strong>What Problem Did MongoDB Solve?</strong></h3><p>Back then:</p><ul><li><p>Startups wanted to build fast without getting bogged down in database schema design.</p></li><li><p>Developers hated <code>ALTER TABLE</code> migrations just to add a single field.</p></li><li><p>The world was moving toward JSON APIs - storing JSON directly made sense.</p></li></ul><p><strong>MongoDB gave you:</strong></p><ul><li><p><strong>Schema-less storage</strong> : Add a new field to your documents without a migration.</p></li><li><p><strong>Developer-friendly</strong> : Query with a syntax that felt closer to JavaScript than SQL.</p></li><li><p><strong>Horizontal scaling</strong> : Shard your data across servers to handle large workloads.</p></li></ul><p><br>A 2011 social media startup could ship features quickly - today you store  <code>{ name, bio }</code>, tomorrow you add <code>{ profilePic }</code> - without touching migrations or breaking existing data.</p><h3><strong>Where MongoDB Fell Short</strong></h3><p>The marketing was great. The reality was&#8230; mixed.</p><ol><li><p><strong>Schema-less &#8800; Structure-less</strong><br>&#8220;No schema&#8221; often turned into &#8220;no consistency.&#8221; You&#8217;d end up with <code>{name}</code> in some documents, <code>{fullName} </code>in others, and <code>{n}</code> in a few because someone fat-fingered it.</p></li><li><p><strong>Joins? What Joins?</strong><br>MongoDB didn&#8217;t do joins well (or at all in early days). If your data was relational - orders, customers, products - you either duplicated data everywhere or wrote ugly aggregation pipelines.</p></li><li><p><strong>Early Durability Issues</strong><br>Older MongoDB versions had cases where writes could be acknowledged before hitting disk. That&#8217;s not great if you care about not losing money or orders.</p></li><li><p><strong>Sharding Complexity</strong><br>Yes, you could scale horizontally - but running and maintaining a sharded Mongo cluster was an ops headache.</p></li></ol><h3><strong>How Modern Solutions Beat or Complement It</strong></h3><p>MongoDB isn&#8217;t &#8220;dead&#8221; like Hadoop hype - it&#8217;s still widely used - but it&#8217;s no longer the &#8220;SQL killer&#8221; it was marketed as.</p><p><strong>1. Postgres Got JSON</strong></p><ul><li><p>PostgreSQL added JSON/JSONB columns with indexing, giving you the flexibility of Mongo plus relational power.</p></li><li><p>You can store semi-structured data and still run SQL joins when you need them.</p></li></ul><p><strong>2. Managed Mongo (Atlas)</strong></p><ul><li><p>Atlas fixed some pain points  but it&#8217;s basically Mongo with training wheels. You&#8217;re still dealing with document design pitfalls if you misuse it.</p></li></ul><p><strong>3. Better Fit-for-Purpose Choices</strong></p><ul><li><p>DynamoDB for massive key-value workloads.</p></li><li><p>Elasticsearch for text search.</p></li><li><p>Redis for caching.</p></li></ul><h4><strong>A Practical Comparison</strong></h4><p><strong>Old Way (Mongo, 2012)</strong>:</p><ul><li><p>Launch MVP fast.</p></li><li><p>Add fields freely without migrations.</p></li><li><p>Denormalize data for performance.</p></li><li><p>Regret it later when analytics and reporting need consistency.</p></li></ul><p><strong>New Way (Postgres with JSONB, 2025)</strong>:</p><ul><li><p>Use strict schemas where you need relational guarantees.</p></li><li><p>Store flexible JSON for fields that change often.</p></li><li><p>Keep queries consistent, indexed, and optimized.</p></li></ul><p><strong>Example</strong></p><p>MongoDB&#8217;s Original Pitch : "Need to store flexible data like user profiles with different fields for each user? MongoDB lets you add <code>{ favoriteFood }</code> to one document and <code>{ petName }</code> to another without schema changes."</p><p><strong>Now (Postgres with JSONB):</strong><br>JSONB column: store flexible fields <em>inside</em> a relational table.</p><ul><li><p>Need <code>favoriteFood</code> for one row? Add it in JSONB.</p></li><li><p>Still join on <code>user_id</code> like a normal SQL table.</p></li><li><p>Create an index on <code>favoriteFood</code> if needed.</p></li></ul><p>The only reason many teams picked Mongo flexible documents is now built into Postgres, but without sacrificing joins, ACID, or query power.</p><h4><strong>Where MongoDB Still Works Well</strong></h4><ul><li><p>Rapid prototyping where schema changes daily.</p></li><li><p>Event logging or analytics where documents don&#8217;t need complex joins.</p></li><li><p>Content-driven apps (CMS, catalogs) where items are self-contained.</p></li></ul><p></p><p>MongoDB wasn&#8217;t a SQL killer. It was a shortcut for certain workloads that sometimes turned into technical debt.<br>Used with discipline, it&#8217;s still a solid choice. But if you treat &#8220;NoSQL&#8221; as &#8220;No Rules,&#8221; you&#8217;ll end up with a data swamp.</p><p>The NoSQL revolution didn&#8217;t kill SQL  it just made Postgres even stronger.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/p/why-postgres-made-mongodb-less-special?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://newsletter.theskilledcoder.com/p/why-postgres-made-mongodb-less-special?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[The Step‑by‑Step Journey of Scaling a Service to 1M Users]]></title><description><![CDATA[From Zero to a Million Users]]></description><link>https://newsletter.theskilledcoder.com/p/the-stepbystep-journey-of-scaling</link><guid isPermaLink="false">https://newsletter.theskilledcoder.com/p/the-stepbystep-journey-of-scaling</guid><dc:creator><![CDATA[Skilled Coder]]></dc:creator><pubDate>Sat, 02 Aug 2025 13:32:45 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Qhii!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a65de35-96b8-4dc9-a9e1-a1aff9fa0633_1024x608.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_!Qhii!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a65de35-96b8-4dc9-a9e1-a1aff9fa0633_1024x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Qhii!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a65de35-96b8-4dc9-a9e1-a1aff9fa0633_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!Qhii!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a65de35-96b8-4dc9-a9e1-a1aff9fa0633_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!Qhii!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a65de35-96b8-4dc9-a9e1-a1aff9fa0633_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!Qhii!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a65de35-96b8-4dc9-a9e1-a1aff9fa0633_1024x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Qhii!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a65de35-96b8-4dc9-a9e1-a1aff9fa0633_1024x608.png" width="1024" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9a65de35-96b8-4dc9-a9e1-a1aff9fa0633_1024x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:608,&quot;width&quot;:1024,&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_!Qhii!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a65de35-96b8-4dc9-a9e1-a1aff9fa0633_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!Qhii!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a65de35-96b8-4dc9-a9e1-a1aff9fa0633_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!Qhii!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a65de35-96b8-4dc9-a9e1-a1aff9fa0633_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!Qhii!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a65de35-96b8-4dc9-a9e1-a1aff9fa0633_1024x608.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"></figcaption></figure></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.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">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>Building a product that scales from a handful of users to millions isn&#8217;t about pulling some magic architecture out of thin air. It&#8217;s about knowing what really matters at each stage and not wasting time on stuff you don&#8217;t need yet.</p><p>This article breaks down the journey from 0 to1M users step by step, what to focus on, what tech choices make sense, and when to level up your stack.</p><div><hr></div><h1><strong>0 to 100 Users: Just Ship It</strong></h1><p>At this stage, your goal isn&#8217;t scale, it&#8217;s speed of development. You want to validate the idea, get feedback, and iterate fast. Over-optimizing early wastes time and slows you down.</p><h2><strong>Tech Requirements</strong></h2><p><strong>Infrastructure</strong></p><ul><li><p><strong>Single server (monolith)</strong>: One machine running everything : app, database, and static assets.</p></li><li><p>Keep it simple to deploy and easy to debug.</p></li></ul><p><strong>Database</strong></p><ul><li><p>One relational database like PostgreSQL or MySQL.</p></li><li><p>No need for sharding, replicas, or complex schemas yet.</p></li><li><p>Focus on correctness and easy migrations.</p></li></ul><p><strong>Authentication</strong></p><ul><li><p>JWTs or local sessions.</p></li><li><p>Lightweight and easy to implement.</p></li><li><p>Don&#8217;t waste time building complex auth flows unless core to your app.</p></li></ul><p><strong>Monitoring</strong></p><ul><li><p>At this point, optional. Basic server uptime monitoring is enough.</p></li></ul><h2><strong>What to Focus On</strong></h2><ul><li><p><strong>Speed of Development</strong>: Get features out quickly, gather user feedback, iterate fast.</p></li><li><p><strong>Keep It Maintainable</strong>: Even in MVP, write code that you or your co-founder can understand a month later.</p></li><li><p><strong>Avoid Premature Optimization</strong>: Don&#8217;t worry about caching, load balancing, or auto-scaling yet.</p></li></ul><blockquote><p><em>At &lt;100 users, bottlenecks are rarely technical. The real challenge is finding product&#8211;market fit. Running lean helps you test hypotheses quickly without being bogged down in infrastructure.</em></p></blockquote><div><hr></div><h1><strong>100 to 1,000 Users: Clean It Up</strong></h1><p>Now that people are actually using your service regularly, small cracks in your MVP start to show : slow queries, messy code, occasional downtime. This stage is about introducing stability and preparing for real growth.</p><h2><strong>Tech Requirements</strong></h2><p><strong>Code</strong></p><ul><li><p>Add modular layers: break spaghetti code into services/routes/components.</p></li><li><p>Set up a clean folder structure for controllers, services, and utilities.</p></li><li><p>Add basic testing (unit/integration).</p></li></ul><p><strong>Database</strong></p><ul><li><p>Start indexing frequently queried columns.</p></li><li><p>Apply basic query optimization to prevent N+1 queries and unnecessary full scans.</p></li><li><p>Introduce migration scripts if you haven&#8217;t already.</p></li></ul><p><strong>Infrastructure</strong></p><ul><li><p>Add NGINX or a simple load balancer in front of your app.</p></li><li><p>This helps distribute load if you start running multiple app instances.</p></li></ul><p><strong>Monitoring</strong></p><ul><li><p>Implement basic logs and uptime checks.</p></li><li><p>Tools: Papertrail, Datadog (lite), or even a cron job with cURL + Slack alerts.</p></li><li><p>You don&#8217;t need full observability yet, but you need visibility when things go down.</p></li></ul><p><strong>Authentication</strong></p><ul><li><p>If you started with JWT/local, ensure token refresh flows and secure session management.</p></li><li><p>Add rate limiting for login attempts (prevent brute force).</p></li></ul><h2><strong>What to Focus On</strong></h2><ul><li><p><strong>Stability</strong>: Keep the app reliable as traffic grows.</p></li><li><p><strong>First Signs of Load</strong>: Start watching for DB slowdowns, memory spikes, or CPU bottlenecks.</p></li><li><p><strong>User Trust</strong>: Downtime hurts more now because people rely on your product daily.</p></li></ul><blockquote><p><em>At 100&#8211;1000 users, the infrastructure still doesn&#8217;t justify Kubernetes clusters or multi-region databases. Instead, the biggest wins come from low-hanging fruit like indexes, load balancing, and monitoring.</em></p></blockquote><p>This is usually the stage where founders are tempted to over-engineer (&#8220;let&#8217;s move to microservices!&#8221;).</p><p>Don&#8217;t.</p><p>Stick to a monolith, but make it clean and testable.</p><div><hr></div><h1><strong>1,000 to 10,000 Users: Prepare to Scale</strong></h1><p>At this level, you can&#8217;t rely on quick hacks. You&#8217;ll start to feel database strain, server latency, and the risk of downtime. This stage is all about reducing bottlenecks before they crush you.</p><h2><strong>Tech Requirements</strong></h2><p><strong>Infrastructure</strong></p><ul><li><p>Move to the cloud (AWS EC2, GCP GKE, or Azure equivalents).</p></li><li><p>Introduce containerization (Docker) for consistency between dev and prod.</p></li><li><p>Possibly multiple app instances behind a load balancer.</p></li></ul><p><strong>Database</strong></p><ul><li><p>Implement connection pooling (e.g., PgBouncer for Postgres).</p></li><li><p>Add read replicas to offload reporting/analytics queries.</p></li><li><p>Monitor slow queries regularly.</p></li></ul><p><strong>Cache</strong></p><ul><li><p>Add Redis or Memcached for hot data (user sessions, popular queries).</p></li><li><p>This prevents your database from melting under repetitive reads.</p></li></ul><p><strong>Async Processing</strong></p><ul><li><p>Introduce background workers/queues (Celery, Sidekiq, or RabbitMQ).</p></li><li><p>Handle tasks like sending emails, notifications, report generation, etc. outside of request-response cycle.</p></li><li><p>Keeps user-facing requests fast.</p></li></ul><p><strong>Monitoring</strong></p><ul><li><p>Move beyond uptime checks, start application-level monitoring.</p></li><li><p>Tools: Prometheus, Grafana, Datadog, or New Relic (depending on budget).</p></li></ul><h2><strong>What to Focus On</strong></h2><ul><li><p><strong>Reducing Latency</strong>: Every millisecond counts when thousands of requests hit.</p></li><li><p><strong>Preventing DB Overload</strong>: Without pooling, caching, and replicas, DB will become your bottleneck.</p></li><li><p><strong>Stability Under Load</strong>: Ensure background jobs and caching absorb spikes gracefully.</p></li></ul><p>This stage isn&#8217;t about reinventing architecture yet it&#8217;s about reinforcing your monolith with strong supports.</p><ul><li><p>Most downtime at this level is caused by database saturation or blocking tasks hogging threads.</p></li><li><p>By adding caching + queues, you essentially buy yourself more runway before needing a distributed architecture.</p></li></ul><blockquote><p><em>You&#8217;ll feel tempted to split into microservices here. Resist unless absolutely necessary. A well-structured monolith with caching and async workers will handle 10k users just fine.</em></p></blockquote><div><hr></div><h1><strong>10,000 to 100,000 Users: Go Distributed</strong></h1><p>At this stage, your single beefy monolith (with caching and workers) will start showing cracks. Request volumes spike, features multiply, and downtime gets very expensive. You now need to distribute responsibility across systems for performance and reliability.</p><h2><strong>Tech Requirements</strong></h2><p><strong>Services</strong></p><p>Begin splitting the monolith into smaller services.</p><ul><li><p>Start with high-load components: authentication, notifications, file uploads.</p></li><li><p>Keep the &#8220;core&#8221; still monolithic for now to reduce complexity.</p></li></ul><p><strong>Scaling</strong></p><ul><li><p>Add auto-scaling rules for app servers (scale horizontally during traffic spikes).</p></li><li><p>Use a CDN for static content (images, CSS, JS) to offload delivery and reduce latency worldwide.</p></li></ul><p><strong>Queueing</strong></p><ul><li><p>Implement event-driven processing with Kafka, RabbitMQ, or AWS SQS.</p></li><li><p>Queue systems help decouple heavy tasks (e.g., analytics, billing) from user-facing requests.</p></li></ul><p><strong>Monitoring</strong></p><p>Move to advanced monitoring + alerting.</p><ul><li><p>Metrics: Prometheus + Grafana, Datadog, or similar.</p></li><li><p>Add error tracking (Sentry, Rollbar).</p></li><li><p>Track latency, throughput, and error rates across services.</p></li></ul><p><strong>Database</strong></p><p>Likely still one main DB, but:</p><ul><li><p>Use read replicas heavily.</p></li><li><p>Start planning for partitioning or sharding if write load grows.</p></li><li><p>Add backup &amp; recovery automation.</p></li></ul><p><strong>Infrastructure</strong></p><ul><li><p>Leverage orchestration (e.g., Kubernetes, ECS) for managing multiple services/containers.</p></li><li><p>Introduce service discovery (so microservices can find each other).</p></li></ul><h2><strong>What to Focus On</strong></h2><ul><li><p><strong>Reliability Under Pressure</strong>: Users now expect &#8220;always-on&#8221; performance.</p></li><li><p><strong>Performance</strong>: Scaling horizontally and caching smartly to handle spikes.</p></li><li><p><strong>Error Visibility</strong>: You need to know about problems before your users do.</p></li></ul><p>At this level, performance issues compound:</p><ul><li><p>A single DB query running slow now impacts thousands.</p></li><li><p>One service crashing can bring down the system if it&#8217;s not isolated.</p></li><li><p>Event queues + CDNs + monitoring make the system resilient.</p></li></ul><blockquote><p><em>Don&#8217;t rush into a full microservices architecture. Instead, extract only the pain points into separate services. A carefully modularized system scales far better than a chaotic microservice.</em></p></blockquote><div><hr></div><h1><strong>100,000 to 1M Users: Serious Scale</strong></h1><p>By now, you&#8217;re not just running a product, you&#8217;re operating a distributed system that needs cost efficiency, fault tolerance, and global reach. Every inefficiency, every DB bottleneck, every network hiccup gets amplified at scale.</p><h2><strong>Tech Requirements</strong></h2><p><strong>Database</strong></p><ul><li><p><strong>Sharding</strong>: Split data across multiple DB instances to handle writes.</p></li><li><p><strong>Denormalization</strong>: Optimize queries by storing precomputed or duplicated data when needed.</p></li><li><p><strong>Time-series storage </strong>(for metrics, logs, analytics).</p></li><li><p>Ensure automated failover + backups across regions.</p></li></ul><p><strong>Cache</strong></p><p>Implement multi-layer caching:</p><ul><li><p>Client &#8594; CDN &#8594; Edge cache &#8594; Application cache &#8594; DB</p></li><li><p>E.g., Cloudflare/Akamai at the edge, Redis/Memcached at the app layer.</p></li></ul><p>Goal: keep hot paths away from the DB entirely.</p><p><strong>Infrastructure</strong></p><ul><li><p>Global load balancers to route users to the nearest healthy region.</p></li><li><p>Traffic routing (GeoDNS, Anycast) for latency optimization.</p></li><li><p>Add edge functions (e.g., Cloudflare Workers, AWS Lambda@Edge) for things like authentication checks or lightweight personalization close to users.</p></li></ul><p><strong>Compliance &amp; Security</strong></p><ul><li><p>Enforce audit logging across all sensitive actions.</p></li><li><p>Set up rate limiting and bot protection at the edge.</p></li><li><p>Define clear security policies (SOC 2, GDPR, HIPAA if relevant).</p></li></ul><p><strong>Monitoring &amp; Observability</strong></p><ul><li><p>Full observability stack (metrics, logs, traces).</p></li><li><p>Distributed tracing (Jaeger, Zipkin, OpenTelemetry).</p></li><li><p>Automated error recovery scripts (self-healing).</p></li></ul><p><strong>DevOps Practices</strong></p><ul><li><p>CI/CD pipelines with canary deployments.</p></li><li><p>Blue-green or rolling deploys to minimize downtime.</p></li><li><p>Chaos engineering (Netflix-style) to test failure scenarios.</p></li></ul><h2><strong>What to Focus On</strong></h2><ul><li><p><strong>Cost Optimization</strong>: infra bills will skyrocket, caching/CDNs reduce costs.</p></li><li><p><strong>Failover &amp; Resilience</strong>: one region going down shouldn&#8217;t kill your app.</p></li><li><p><strong>Global Latency</strong>: keeping response times low worldwide.</p></li></ul><p>At 100k&#8211;1M users, your challenges shift from &#8220;will this hold up?&#8221; to &#8220;can we keep it cost-effective, secure, and globally fast?&#8221;</p><ul><li><p>Sharding and caching prevent DB meltdowns.</p></li><li><p>Multi-region load balancing keeps uptime near 100%.</p></li><li><p>Compliance and audit logging protect you from business-ending mistakes.</p></li></ul><blockquote><p><em>Think of this stage less like coding an app and more like running an airline: uptime, safety, and efficiency are the priorities. Features matter, but reliability is the brand now.</em></p></blockquote><div><hr></div><p>Scaling to a million users isn&#8217;t a single &#8220;big bang&#8221; move, it&#8217;s a series of practical upgrades at the right time.</p><p>The biggest mistake most teams make?</p><p>Either over-engineering too early or waiting too long to fix cracks.</p><p>If you focus on the right things at the right stage, you&#8217;ll not only handle the load: you&#8217;ll stay sane</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/p/the-stepbystep-journey-of-scaling?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://newsletter.theskilledcoder.com/p/the-stepbystep-journey-of-scaling?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[5 Uncommon Habits for Writing Truly Great Unit Tests]]></title><description><![CDATA[Unit Testing Tips You Wish You Knew Earlier]]></description><link>https://newsletter.theskilledcoder.com/p/5-uncommon-habits-for-writing-truly</link><guid isPermaLink="false">https://newsletter.theskilledcoder.com/p/5-uncommon-habits-for-writing-truly</guid><dc:creator><![CDATA[Skilled Coder]]></dc:creator><pubDate>Sat, 26 Jul 2025 05:51:01 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!tGDC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f9d478-3183-4b24-9c87-18f1d3a3ec68_1024x608.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_!tGDC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f9d478-3183-4b24-9c87-18f1d3a3ec68_1024x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tGDC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f9d478-3183-4b24-9c87-18f1d3a3ec68_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!tGDC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f9d478-3183-4b24-9c87-18f1d3a3ec68_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!tGDC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f9d478-3183-4b24-9c87-18f1d3a3ec68_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!tGDC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f9d478-3183-4b24-9c87-18f1d3a3ec68_1024x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tGDC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f9d478-3183-4b24-9c87-18f1d3a3ec68_1024x608.png" width="1024" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/74f9d478-3183-4b24-9c87-18f1d3a3ec68_1024x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:608,&quot;width&quot;:1024,&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_!tGDC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f9d478-3183-4b24-9c87-18f1d3a3ec68_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!tGDC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f9d478-3183-4b24-9c87-18f1d3a3ec68_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!tGDC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f9d478-3183-4b24-9c87-18f1d3a3ec68_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!tGDC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f9d478-3183-4b24-9c87-18f1d3a3ec68_1024x608.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"></figcaption></figure></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.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">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>Writing tests isn&#8217;t just about coverage it&#8217;s about confidence.<br>Here are 5 lesser-known but powerful habits to make your unit tests rock-solid and readable.</p><div><hr></div><h2><strong>1) Test behavior, not implementation</strong></h2><p>Write tests that check what the code should do - not how it does it internally.</p><p>Internal methods may change, but expected behavior should remain consistent.</p><p><strong>Bad Example (testing implementation):</strong></p><pre><code>@Test
void shouldCallApplyDiscountMethod() {
    PricingService spy = Mockito.spy(new PricingService());
    spy.getPrice("premium", 100);
    verify(spy).applyDiscount();  // you're testing internal method call
}</code></pre><p>This test will fail if you refactor and remove <code>applyDiscount()</code>, even if the behavior (discounted price) remains correct.</p><p><strong>Good Example (testing behavior)</strong></p><pre><code>@Test
void shouldReturnDiscountedPriceForPremiumUser() {
    double price = pricingService.getPrice("premium", 100);
    assertEquals(80, price);  // checks outcome, not method internals
}</code></pre><p>This test will still pass even if you later use a different way to calculate discounts.</p><blockquote><p>Test what your users care about - not the plumbing behind it.</p></blockquote><div><hr></div><h2><strong>2) Name tests like documentation, not code</strong></h2><p>Write test method names like they&#8217;re telling a story - clear, specific, and human-readable.</p><p>It will:</p><ul><li><p>Makes test reports easy to scan - no need to dig into code.</p></li><li><p>Helps future devs understand intent instantly.</p></li><li><p>Acts like living documentation for edge cases and requirements.</p></li></ul><p><strong>Bad Example (vague, codey)</strong></p><pre><code>@Test
void testLoginFail() {
    // What kind of fail? Why? What user? No clue.
}</code></pre><p><strong>Good Example (self-explaining):</strong></p><pre><code>@Test
void shouldThrowExceptionWhenPasswordIsInvalid() {
    assertThrows(AuthException.class, () -&gt; authService.login("john", "wrongpass"));
}</code></pre><p>Without even reading the code, you know the exact scenario being tested.</p><blockquote><p><em>Well-named tests read like user stories - not cryptic code snippets.</em></p></blockquote><div><hr></div><h2><strong>3) Write the test before fixing the bug</strong></h2><p>When you discover a bug, write a test that reproduces it before fixing the code.</p><p>Why?</p><ul><li><p>It proves the bug actually exists (not just in your head).</p></li><li><p>When you fix the code, the test passes, now you know the bug is fixed properly.</p></li><li><p>If someone reintroduces that bug later, the test will catch it.</p></li></ul><p>Let&#8217;s say you find that leap year birthdays are crashing your system.</p><pre><code>// Write the test first &#8212; it fails right now.
@Test
void shouldAllowLeapYearBirthday() {
    User user = userService.register("John", LocalDate.of(2024, 2, 29));
    assertNotNull(user);
}</code></pre><p>You run it - it throws an exception or fails.<br>Now fix the logic in <code>userService.register()</code>.<br>Once fixed, the test passes. Done.</p><blockquote><p>A failing test written before the fix proves the bug and guards against its comeback.</p></blockquote><div><hr></div><h2><strong>4) Use data-driven tests for edge cases</strong></h2><p>Instead of writing many similar tests, loop through a set of inputs using parameterized tests.</p><p>It prevents copy-paste clutter and makes test suite cleaner.</p><p>Also edge cases are easier to discover when grouped together.</p><p><strong>Bad Example (repetitive and bloated):</strong></p><pre><code>@Test
void shouldRejectEmptyUsername() {
    assertFalse(userValidator.isValidUsername(""));
}

@Test
void shouldRejectSpaceOnlyUsername() {
    assertFalse(userValidator.isValidUsername(" "));
}

@Test
void shouldRejectNewlineUsername() {
    assertFalse(userValidator.isValidUsername("\n"));
}</code></pre><p><strong>Good Example (clean and scalable):</strong></p><pre><code>@ParameterizedTest
@ValueSource(strings = {"", " ", "\n"})
void shouldRejectInvalidUsernames(String input) {
    assertFalse(userValidator.isValidUsername(input));
}</code></pre><p>One test, multiple edge cases covered and easy to add more later.</p><blockquote><p><em>Edge cases love company - test them together with parameterized inputs.</em></p></blockquote><div><hr></div><h2><strong>5. Assert what matters, not every field</strong></h2><p>Focus your assertions only on the important business outcomes, not on every field of the object.</p><p>Why?</p><ul><li><p>Keeps tests stable even as non-essential details evolve.</p></li><li><p>Makes your intent crystal clear: you&#8217;re testing this, not everything.</p></li><li><p>Saves time in test maintenance during refactors.</p></li></ul><p><strong>Bad Example (over-asserting, brittle):</strong></p><pre><code>@Test
void shouldCreateOrderSuccessfully() {
    Order order = orderService.create(user, cart);

    assertEquals(123, order.getId());
    assertEquals("2024-07-19", order.getCreatedAt().toString());
    assertEquals("John", order.getCustomerName());
    assertEquals(2500, order.getTotal());
}</code></pre><p>This test breaks if ID generation changes, date format updates, or name field is renamed - even if total amount logic is perfect.</p><p><strong>Good Example (assert business-critical value):</strong></p><pre><code>@Test
void shouldCalculateTotalCorrectlyInNewOrder() {
    Order order = orderService.create(user, cart);
    assertEquals(2500, order.getTotal()); // This is what actually matters
}</code></pre><p>Now the test will only fail if the real logic (total amount) breaks.</p><blockquote><p><em>Test the contract, not the cosmetics, assert what users or business actually care about.</em></p></blockquote><div><hr></div><p>Most developers write tests. Great developers write tests that are useful.<br>Adopt even one of these tips, and you (and teammates) will notice the benefit.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/p/5-uncommon-habits-for-writing-truly?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/p/5-uncommon-habits-for-writing-truly?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://newsletter.theskilledcoder.com/p/5-uncommon-habits-for-writing-truly?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p>]]></content:encoded></item><item><title><![CDATA[System Design Prerequisites You Should Always Consider]]></title><description><![CDATA[The Checklist I Wish I Had Before Designing My First Scalable System]]></description><link>https://newsletter.theskilledcoder.com/p/system-design-prerequisites-you-should</link><guid isPermaLink="false">https://newsletter.theskilledcoder.com/p/system-design-prerequisites-you-should</guid><dc:creator><![CDATA[Skilled Coder]]></dc:creator><pubDate>Sun, 13 Jul 2025 13:15:30 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!PfRY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae507d7-fb4d-4bd1-9bf6-4f2cd8d02064_1024x608.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_!PfRY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae507d7-fb4d-4bd1-9bf6-4f2cd8d02064_1024x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PfRY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae507d7-fb4d-4bd1-9bf6-4f2cd8d02064_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!PfRY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae507d7-fb4d-4bd1-9bf6-4f2cd8d02064_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!PfRY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae507d7-fb4d-4bd1-9bf6-4f2cd8d02064_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!PfRY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae507d7-fb4d-4bd1-9bf6-4f2cd8d02064_1024x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PfRY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae507d7-fb4d-4bd1-9bf6-4f2cd8d02064_1024x608.png" width="1024" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7ae507d7-fb4d-4bd1-9bf6-4f2cd8d02064_1024x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:608,&quot;width&quot;:1024,&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_!PfRY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae507d7-fb4d-4bd1-9bf6-4f2cd8d02064_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!PfRY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae507d7-fb4d-4bd1-9bf6-4f2cd8d02064_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!PfRY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae507d7-fb4d-4bd1-9bf6-4f2cd8d02064_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!PfRY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae507d7-fb4d-4bd1-9bf6-4f2cd8d02064_1024x608.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"></figcaption></figure></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.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">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>Designing scalable systems isn&#8217;t just about knowing the tools it&#8217;s about asking the right questions upfront. Before you look into architecture diagrams, here&#8217;s a checklist every developer should walk through.</p><div><hr></div><h1><strong>1. Understand the Goal</strong></h1><p>Before writing a single line of code or diagramming a system, ask:</p><ul><li><p><strong>What exactly are you building?</strong> (e.g., a social media platform)</p></li><li><p><strong>Who&#8217;s using it?</strong> (teenagers, professionals, businesses)</p></li><li><p><strong>Main use case:</strong> (sharing photos, professional networking, online payments)</p></li></ul><p>Without a clear goal, you may end up overengineering, solving the wrong problem, or missing critical user expectations.</p><blockquote><p>A system for internal use by employees has vastly different needs than one for millions of external users.</p></blockquote><div><hr></div><h1><strong>2. Traffic Pattern: Read-Heavy vs Write-Heavy</strong></h1><p>This helps you determine where to focus your optimization efforts.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LWcW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70294776-fdf2-447c-a43c-d9e6b9bf7871_1400x306.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LWcW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70294776-fdf2-447c-a43c-d9e6b9bf7871_1400x306.png 424w, https://substackcdn.com/image/fetch/$s_!LWcW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70294776-fdf2-447c-a43c-d9e6b9bf7871_1400x306.png 848w, https://substackcdn.com/image/fetch/$s_!LWcW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70294776-fdf2-447c-a43c-d9e6b9bf7871_1400x306.png 1272w, https://substackcdn.com/image/fetch/$s_!LWcW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70294776-fdf2-447c-a43c-d9e6b9bf7871_1400x306.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LWcW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70294776-fdf2-447c-a43c-d9e6b9bf7871_1400x306.png" width="1400" height="306" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/70294776-fdf2-447c-a43c-d9e6b9bf7871_1400x306.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:306,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&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_!LWcW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70294776-fdf2-447c-a43c-d9e6b9bf7871_1400x306.png 424w, https://substackcdn.com/image/fetch/$s_!LWcW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70294776-fdf2-447c-a43c-d9e6b9bf7871_1400x306.png 848w, https://substackcdn.com/image/fetch/$s_!LWcW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70294776-fdf2-447c-a43c-d9e6b9bf7871_1400x306.png 1272w, https://substackcdn.com/image/fetch/$s_!LWcW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70294776-fdf2-447c-a43c-d9e6b9bf7871_1400x306.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><ul><li><p>Systems like Netflix prioritize fast content delivery. Caching, CDN, and read replicas are essential.</p></li><li><p>Apps like WhatsApp focus on handling huge volumes of incoming data reliably, using queues and write buffers.</p></li></ul><p>Designing a read-heavy system with write-heavy optimizations leads to wasted resources and poor performance. This is one of the most foundational choices in backend architecture.</p><div><hr></div><h1><strong>3. Consistency vs Availability</strong></h1><p>In distributed systems, you often can&#8217;t have both perfect consistency and high availability (CAP theorem).</p><ul><li><p><strong>Strict consistency:</strong> Needed when any mismatch is unacceptable (e.g., showing $500 when your bank balance is actually $300 is a big problem).</p></li><li><p><strong>Eventual consistency:</strong> Perfectly fine when real-time precision isn&#8217;t required (e.g., social feeds showing a post a few seconds late).</p></li></ul><p>Misjudging this can lead to system unreliability or over-complexity. Choose based on business risk.</p><div><hr></div><h1><strong>4. Latency Requirements</strong></h1><p>Do users expect instant results, or can they wait?</p><p><strong>Real-time (low latency):</strong> Critical for gaming, live streaming, or payment systems. Use caching or precomputed data.</p><ul><li><p>e.g Think of Zoom. A 1-second delay ruins the experience or a Google Pay transactions.</p></li></ul><p><strong>Async (higher latency is okay):</strong> Tasks like email delivery or report generation.</p><ul><li><p>e.g Email confirmations can take a few seconds without hurting UX, analytics reports generation.</p></li></ul><p>This directly influences your use of technologies like message queues, caching, or background workers. Over-optimizing for real-time needs can make your system costly and fragile.</p><div><hr></div><h1><strong>5. Expected Scale</strong></h1><p>Think long-term. You might start with 100 users - but will it still work with 10 million?</p><p>Initial design (MVP) can be simple but should easily scale.</p><ul><li><p><strong>Google Docs:</strong> Started small, now supports millions of users editing simultaneously.</p></li><li><p><strong>Uber:</strong> Handles thousands of ride requests per minute with horizontal scaling and stateless services.</p></li></ul><p>Systems often fail not because of bugs, but because they weren&#8217;t designed to handle growth. Google Docs scaled from a basic collaborative editor to a complex real-time system. If you don&#8217;t design with scalability in mind, rewrites become painful and expensive.</p><div><hr></div><h1><strong>6. Access Patterns</strong></h1><p>Identify what data is accessed most frequently or in which pattern.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sJwn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd52d418-944e-4807-981a-936e0946b255_1400x921.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sJwn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd52d418-944e-4807-981a-936e0946b255_1400x921.png 424w, https://substackcdn.com/image/fetch/$s_!sJwn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd52d418-944e-4807-981a-936e0946b255_1400x921.png 848w, https://substackcdn.com/image/fetch/$s_!sJwn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd52d418-944e-4807-981a-936e0946b255_1400x921.png 1272w, https://substackcdn.com/image/fetch/$s_!sJwn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd52d418-944e-4807-981a-936e0946b255_1400x921.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sJwn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd52d418-944e-4807-981a-936e0946b255_1400x921.png" width="1400" height="921" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cd52d418-944e-4807-981a-936e0946b255_1400x921.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:921,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&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_!sJwn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd52d418-944e-4807-981a-936e0946b255_1400x921.png 424w, https://substackcdn.com/image/fetch/$s_!sJwn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd52d418-944e-4807-981a-936e0946b255_1400x921.png 848w, https://substackcdn.com/image/fetch/$s_!sJwn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd52d418-944e-4807-981a-936e0946b255_1400x921.png 1272w, https://substackcdn.com/image/fetch/$s_!sJwn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd52d418-944e-4807-981a-936e0946b255_1400x921.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>If you choose the wrong pattern (e.g., hitting DB for every search), you risk slow performance, high cost, and poor UX. Patterns should align with actual user interaction and scale expectations.</p><div><hr></div><h1><strong>7. Data Growth &amp; Partitioning</strong></h1><p>Data will grow. Will your system crash when it does?</p><ul><li><p><strong>YouTube Comments &#8594; Sharded by Video ID</strong><br>Each video can have millions of comments, but comments under different videos are unrelated. So YouTube shards the data by <code>video_id</code> to avoid one giant table and to make reads/writes faster.</p></li><li><p><strong>Twitter Tweets &#8594; Sharded by User ID + Time</strong><br>Tweets are partitioned by <code>user_id</code> and sometimes by time buckets. This allows fast access to a user's timeline and prevents hot partitions when a user tweets frequently.</p></li><li><p><strong>Bank Transactions &#8594; Partitioned by Account Number + Date</strong><br>To retrieve and archive transactions efficiently, banks shard data by account number and archive old records beyond 6&#8211;12 months to cold storage (e.g., tape drives or long-term S3).</p></li><li><p><strong>Google Drive / Gmail &#8594; Archive Cold Data</strong><br>Old files or emails are rarely accessed but take up space. These are moved to low-cost, long-term storage, improving DB performance and cutting storage costs.</p></li></ul><p>As your app scales, unpartitioned data becomes a bottleneck. Without planning for growth, even a basic query like &#8220;get all orders for user X&#8221; can slow down, affecting everyone.</p><div><hr></div><h1><strong>8. Failure Handling</strong></h1><p>Things break. Servers crash. Networks fail. How does your system cope?</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!n1du!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0737d0-d28b-486d-aefd-7f7870c370f1_1400x252.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!n1du!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0737d0-d28b-486d-aefd-7f7870c370f1_1400x252.png 424w, https://substackcdn.com/image/fetch/$s_!n1du!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0737d0-d28b-486d-aefd-7f7870c370f1_1400x252.png 848w, https://substackcdn.com/image/fetch/$s_!n1du!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0737d0-d28b-486d-aefd-7f7870c370f1_1400x252.png 1272w, https://substackcdn.com/image/fetch/$s_!n1du!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0737d0-d28b-486d-aefd-7f7870c370f1_1400x252.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!n1du!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0737d0-d28b-486d-aefd-7f7870c370f1_1400x252.png" width="1400" height="252" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5b0737d0-d28b-486d-aefd-7f7870c370f1_1400x252.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:252,&quot;width&quot;:1400,&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_!n1du!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0737d0-d28b-486d-aefd-7f7870c370f1_1400x252.png 424w, https://substackcdn.com/image/fetch/$s_!n1du!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0737d0-d28b-486d-aefd-7f7870c370f1_1400x252.png 848w, https://substackcdn.com/image/fetch/$s_!n1du!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0737d0-d28b-486d-aefd-7f7870c370f1_1400x252.png 1272w, https://substackcdn.com/image/fetch/$s_!n1du!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b0737d0-d28b-486d-aefd-7f7870c370f1_1400x252.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>You don&#8217;t want users facing 500 errors every time something small fails. Proper retries, fallbacks, and circuit breakers ensure graceful degradation and better user trust.</p><div><hr></div><h1><strong>9. Security &amp; Auth</strong></h1><p>If your app is public-facing or handles user data, you must think about:</p><ul><li><p>Who can access what?</p></li><li><p>How do you prevent abuse?</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fmB3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F800c9b40-bd3d-452b-be0a-bd7e4c23bf72_1270x250.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fmB3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F800c9b40-bd3d-452b-be0a-bd7e4c23bf72_1270x250.png 424w, https://substackcdn.com/image/fetch/$s_!fmB3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F800c9b40-bd3d-452b-be0a-bd7e4c23bf72_1270x250.png 848w, https://substackcdn.com/image/fetch/$s_!fmB3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F800c9b40-bd3d-452b-be0a-bd7e4c23bf72_1270x250.png 1272w, https://substackcdn.com/image/fetch/$s_!fmB3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F800c9b40-bd3d-452b-be0a-bd7e4c23bf72_1270x250.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fmB3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F800c9b40-bd3d-452b-be0a-bd7e4c23bf72_1270x250.png" width="1270" height="250" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/800c9b40-bd3d-452b-be0a-bd7e4c23bf72_1270x250.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:250,&quot;width&quot;:1270,&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_!fmB3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F800c9b40-bd3d-452b-be0a-bd7e4c23bf72_1270x250.png 424w, https://substackcdn.com/image/fetch/$s_!fmB3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F800c9b40-bd3d-452b-be0a-bd7e4c23bf72_1270x250.png 848w, https://substackcdn.com/image/fetch/$s_!fmB3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F800c9b40-bd3d-452b-be0a-bd7e4c23bf72_1270x250.png 1272w, https://substackcdn.com/image/fetch/$s_!fmB3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F800c9b40-bd3d-452b-be0a-bd7e4c23bf72_1270x250.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Security is often treated as an afterthought &#8212; until something goes wrong. Implementing OAuth, rate limiting, and CAPTCHA from day one protects your system and your users.</p><div><hr></div><h1><strong>10. Do You Need to Build It All?</strong></h1><p>You don&#8217;t need to reinvent the wheel. Use existing, battle-tested services.</p><p>Can you use a 3rd party for auth, payments, media, etc.?</p><p>Offload non-core features to SaaS or APIs</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!R_h8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc4e40e4-7df4-4029-86e2-ee6c6f0e7de2_1352x292.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!R_h8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc4e40e4-7df4-4029-86e2-ee6c6f0e7de2_1352x292.png 424w, https://substackcdn.com/image/fetch/$s_!R_h8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc4e40e4-7df4-4029-86e2-ee6c6f0e7de2_1352x292.png 848w, https://substackcdn.com/image/fetch/$s_!R_h8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc4e40e4-7df4-4029-86e2-ee6c6f0e7de2_1352x292.png 1272w, https://substackcdn.com/image/fetch/$s_!R_h8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc4e40e4-7df4-4029-86e2-ee6c6f0e7de2_1352x292.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!R_h8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc4e40e4-7df4-4029-86e2-ee6c6f0e7de2_1352x292.png" width="1352" height="292" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cc4e40e4-7df4-4029-86e2-ee6c6f0e7de2_1352x292.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:292,&quot;width&quot;:1352,&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_!R_h8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc4e40e4-7df4-4029-86e2-ee6c6f0e7de2_1352x292.png 424w, https://substackcdn.com/image/fetch/$s_!R_h8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc4e40e4-7df4-4029-86e2-ee6c6f0e7de2_1352x292.png 848w, https://substackcdn.com/image/fetch/$s_!R_h8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc4e40e4-7df4-4029-86e2-ee6c6f0e7de2_1352x292.png 1272w, https://substackcdn.com/image/fetch/$s_!R_h8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc4e40e4-7df4-4029-86e2-ee6c6f0e7de2_1352x292.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Building everything in-house is tempting but inefficient. Offloading non-core parts lets you focus on your unique value. If Uber built its own media service or SMS gateway from scratch, it would have slowed their growth drastically.</p><div><hr></div><p>These aren&#8217;t hard rules - but they&#8217;ll save you from hard rewrites. Think of them as your system design compass.</p><p>And once your system is built, don&#8217;t forget to think about observability (logs, metrics, alerts), deployment strategy (CI/CD, rollback), data backups, cost optimization, and team ownership.</p><p>Because building is just the beginning - running it well is where the real game begins. Will share that in some other article.</p>]]></content:encoded></item><item><title><![CDATA[Your Logs Are Lying to You (And What to Do About It)]]></title><description><![CDATA[Logs Are a Code Smell (Sometimes)]]></description><link>https://newsletter.theskilledcoder.com/p/your-logs-are-lying-to-you-and-what</link><guid isPermaLink="false">https://newsletter.theskilledcoder.com/p/your-logs-are-lying-to-you-and-what</guid><dc:creator><![CDATA[Skilled Coder]]></dc:creator><pubDate>Sun, 06 Jul 2025 06:00:20 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!vTwC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54e80ecc-61a9-40fd-a5f7-c35965d31f5c_1024x608.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_!vTwC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54e80ecc-61a9-40fd-a5f7-c35965d31f5c_1024x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vTwC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54e80ecc-61a9-40fd-a5f7-c35965d31f5c_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!vTwC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54e80ecc-61a9-40fd-a5f7-c35965d31f5c_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!vTwC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54e80ecc-61a9-40fd-a5f7-c35965d31f5c_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!vTwC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54e80ecc-61a9-40fd-a5f7-c35965d31f5c_1024x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vTwC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54e80ecc-61a9-40fd-a5f7-c35965d31f5c_1024x608.png" width="1024" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/54e80ecc-61a9-40fd-a5f7-c35965d31f5c_1024x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:608,&quot;width&quot;:1024,&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_!vTwC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54e80ecc-61a9-40fd-a5f7-c35965d31f5c_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!vTwC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54e80ecc-61a9-40fd-a5f7-c35965d31f5c_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!vTwC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54e80ecc-61a9-40fd-a5f7-c35965d31f5c_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!vTwC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54e80ecc-61a9-40fd-a5f7-c35965d31f5c_1024x608.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"></figcaption></figure></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.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"> 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>When your logs say everything&#8230; and nothing.</p><p>Almost every developer has done it:</p><pre><code>for (Order order : orders) {
    log.info("Processing order {}", order.getId());
    process(order);
}</code></pre><p>It feels harmless when you have ten test orders on your laptop.<br>Push the same code to production - where there are two million orders an hour and suddenly:</p><ul><li><p>Pods get evicted because log files fill the disk.</p></li><li><p>Your observability bill shoots past your coffee budget.</p></li><li><p>Real errors disappear under a waterfall of &#8220;Processing order&#8230;&#8221;.</p></li></ul><p>This is what happens when we use logging as a substitute for design.</p><p>Logging isn&#8217;t the villain. Using it as duct-tape for deeper design problems is.</p><p><br>Below are four everyday logging mistakes (I&#8217;ve made every one of them), the pain they cause, and simple ways to turn the noise into real insight.</p><div><hr></div><h3>1. Hot-Loop Logging</h3><pre><code>for (User u : userList) {
    log.debug("User found: {}", u.getEmail());
    sendWelcomeMail(u);
}</code></pre><p><strong>Why it stings</strong></p><ul><li><p><strong>CPU &amp; I/O drain: </strong>Formatting strings and writing to disk thousands of times a second steals cycles from business logic.</p></li><li><p><strong>Real-world fallout: </strong>One team I coached saw their Kubernetes node hit &#8220;DiskPressure&#8221; after 40 minutes of a bulk import - logs alone chewed 22 GB.</p></li><li><p><strong>Debugging blindfold: </strong>When everything is logged, nothing stands out.</p></li></ul><p><strong>Fix in five minutes</strong></p><pre><code>int processed = 0;
long start = System.nanoTime();

for (User u : userList) {
    sendWelcomeMail(u);
    processed++;
}

log.info("Sent {} welcome mails in {} ms",
         processed,
         (System.nanoTime() - start)/1_000_000);</code></pre><p><em><strong>Log once, summarise, move on.</strong></em><strong><br></strong>Need per-user data? Emit a metric (<code>welcome_mail_total</code>) and graph it, no human wants to read 100 000 log lines about it.</p><div><hr></div><h3>2. Boolean-Flag Noise</h3><pre><code>log.debug("isActive=" + user.isActive());</code></pre><p>Even when DEBUG is disabled, the JVM still builds that string. Repeat in a hot path and the garbage collector becomes your shadow.</p><p><strong>Fix in five seconds</strong></p><pre><code>if (log.isDebugEnabled()) {
    log.debug("isActive={}", user.isActive());
}</code></pre><ul><li><p>The guard stops needless work.</p></li><li><p>The <code>{}</code> placeholder defers formatting until the line is actually written.</p></li></ul><div><hr></div><h3>3. Panic-Level Misuse</h3><pre><code>log.error("Invalid coupon code: {}", code);</code></pre><p>A user typo is annoying, not an outage, yet it pages the on-call engineer at midnight.</p><p><strong>How to choose the right level</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2ga_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbabf3d2-f008-401c-b68a-fba3f349ed4a_888x644.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2ga_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbabf3d2-f008-401c-b68a-fba3f349ed4a_888x644.png 424w, https://substackcdn.com/image/fetch/$s_!2ga_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbabf3d2-f008-401c-b68a-fba3f349ed4a_888x644.png 848w, https://substackcdn.com/image/fetch/$s_!2ga_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbabf3d2-f008-401c-b68a-fba3f349ed4a_888x644.png 1272w, https://substackcdn.com/image/fetch/$s_!2ga_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbabf3d2-f008-401c-b68a-fba3f349ed4a_888x644.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2ga_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbabf3d2-f008-401c-b68a-fba3f349ed4a_888x644.png" width="576" height="417.72972972972974" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dbabf3d2-f008-401c-b68a-fba3f349ed4a_888x644.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:644,&quot;width&quot;:888,&quot;resizeWidth&quot;:576,&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_!2ga_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbabf3d2-f008-401c-b68a-fba3f349ed4a_888x644.png 424w, https://substackcdn.com/image/fetch/$s_!2ga_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbabf3d2-f008-401c-b68a-fba3f349ed4a_888x644.png 848w, https://substackcdn.com/image/fetch/$s_!2ga_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbabf3d2-f008-401c-b68a-fba3f349ed4a_888x644.png 1272w, https://substackcdn.com/image/fetch/$s_!2ga_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbabf3d2-f008-401c-b68a-fba3f349ed4a_888x644.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Route <code>ERROR</code> to PagerDuty, send <code>WARN</code> to a Slack channel, and let <code>INFO</code> live quietly in your log store.</p><div><hr></div><h3>4. &#8220;Printf Metrics&#8221;</h3><pre><code>long t0 = System.nanoTime();
// DB query&#8230;
log.info("query_ms={}", (System.nanoTime() - t0) / 1_000_000);</code></pre><p>You later write a regex in Grafana to graph the numbers. One day someone changes the log text, the regex breaks, and alerts go silent.</p><p><strong>Better: emit a real metric</strong></p><pre><code>Timer queryTimer = Metrics.timer("db.query.duration");
long t0 = System.nanoTime();

runQuery(sql);

queryTimer.record(System.nanoTime() - t0, TimeUnit.NANOSECONDS);</code></pre><ul><li><p>Percentiles, alerts, and dashboards stay intact no matter how the log message evolves.</p></li><li><p>Logs tell stories; metrics track numbers; traces show relationships. Keep the channels separate.</p></li></ul><div><hr></div><h3><strong>Choosing Not to Log</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AYJ9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf0180f8-b74e-4714-8e6d-1833cc78d24e_1400x1081.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AYJ9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf0180f8-b74e-4714-8e6d-1833cc78d24e_1400x1081.png 424w, https://substackcdn.com/image/fetch/$s_!AYJ9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf0180f8-b74e-4714-8e6d-1833cc78d24e_1400x1081.png 848w, https://substackcdn.com/image/fetch/$s_!AYJ9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf0180f8-b74e-4714-8e6d-1833cc78d24e_1400x1081.png 1272w, https://substackcdn.com/image/fetch/$s_!AYJ9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf0180f8-b74e-4714-8e6d-1833cc78d24e_1400x1081.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AYJ9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf0180f8-b74e-4714-8e6d-1833cc78d24e_1400x1081.png" width="686" height="529.69" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cf0180f8-b74e-4714-8e6d-1833cc78d24e_1400x1081.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1081,&quot;width&quot;:1400,&quot;resizeWidth&quot;:686,&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_!AYJ9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf0180f8-b74e-4714-8e6d-1833cc78d24e_1400x1081.png 424w, https://substackcdn.com/image/fetch/$s_!AYJ9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf0180f8-b74e-4714-8e6d-1833cc78d24e_1400x1081.png 848w, https://substackcdn.com/image/fetch/$s_!AYJ9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf0180f8-b74e-4714-8e6d-1833cc78d24e_1400x1081.png 1272w, https://substackcdn.com/image/fetch/$s_!AYJ9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf0180f8-b74e-4714-8e6d-1833cc78d24e_1400x1081.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>A Simple Logging Playbook You Can Adopt Tomorrow</h3><ul><li><p><strong>Write a one-page team policy</strong><br><em>Levels, PII rules, retention</em>. Consistency beats &#8220;whatever the last person did&#8221;.</p></li><li><p><strong>Set a daily log budget</strong><br>Choose a number (e.g., &#8220;1 GB per service per day&#8221;) and alert when you get close.</p></li><li><p><strong>Add request IDs automatically</strong><br>With SLF4J&#8217;s MDC or Log4j ThreadContext. One-click correlation beats grep.</p></li><li><p><strong>Batch or sample in bulk jobs</strong><br>Log the first record, every thousandth, and the last. Or just the summary.</p></li><li><p><strong>Review the top 10 chatty log statements every sprint</strong><br>Deleting dead noise is the fastest performance win you&#8217;ll ever get.</p></li></ul><div><hr></div><p>Logging is like salt in cooking: essential, but easy to overdo. Whenever you add a line, ask yourself:</p><ol><li><p>Who will read this and why?</p></li><li><p>Is there a cheaper/faster way to get the same insight?</p></li><li><p>Could this message become dangerous at scale?</p></li></ol><p>Answer those three and you&#8217;ll log just enough and probably sleep better on-call.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/p/your-logs-are-lying-to-you-and-what?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://newsletter.theskilledcoder.com/p/your-logs-are-lying-to-you-and-what?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Concepts You Only Learn After Running Code in Production]]></title><description><![CDATA[The Unwritten Rules of Production-Grade Software]]></description><link>https://newsletter.theskilledcoder.com/p/concepts-you-only-learn-after-running</link><guid isPermaLink="false">https://newsletter.theskilledcoder.com/p/concepts-you-only-learn-after-running</guid><dc:creator><![CDATA[Skilled Coder]]></dc:creator><pubDate>Sun, 22 Jun 2025 11:58:58 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Csx7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F349187e7-d022-4a6c-b1f0-1c81f5291863_1024x608.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_!Csx7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F349187e7-d022-4a6c-b1f0-1c81f5291863_1024x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Csx7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F349187e7-d022-4a6c-b1f0-1c81f5291863_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!Csx7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F349187e7-d022-4a6c-b1f0-1c81f5291863_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!Csx7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F349187e7-d022-4a6c-b1f0-1c81f5291863_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!Csx7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F349187e7-d022-4a6c-b1f0-1c81f5291863_1024x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Csx7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F349187e7-d022-4a6c-b1f0-1c81f5291863_1024x608.png" width="1024" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/349187e7-d022-4a6c-b1f0-1c81f5291863_1024x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:608,&quot;width&quot;:1024,&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_!Csx7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F349187e7-d022-4a6c-b1f0-1c81f5291863_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!Csx7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F349187e7-d022-4a6c-b1f0-1c81f5291863_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!Csx7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F349187e7-d022-4a6c-b1f0-1c81f5291863_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!Csx7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F349187e7-d022-4a6c-b1f0-1c81f5291863_1024x608.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"></figcaption></figure></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.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"> 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>Writing correct code is only step one.<br>Keeping it alive, fast, and resilient in production is a different game.<br>These lessons aren&#8217;t just theory - they&#8217;re the hard truths that every backend developer learns after their first real outage, rollback, or midnight PagerDuty call.</p><p>Read them before production teaches them to you the hard way.</p><div><hr></div><h2><strong>1. Production readiness involves more than code correctness</strong></h2><p>Just because your code compiles and passes tests doesn&#8217;t mean it&#8217;s ready for production. True readiness requires operational support: monitoring, alerting, scaling, security, and performance.</p><p><strong>Example:</strong><br>You deploy a new service to prod. The logic works, but there&#8217;s no alerting on CPU/memory spikes. It goes down at midnight, and no one knows until users start complaining next morning.</p><p><strong>Checklist to consider:</strong></p><ul><li><p>Is there an SLA/SLO defined?</p></li><li><p>Are alerts configured for error rates, latency, memory, CPU?</p></li><li><p>Is there a fallback or graceful degradation?</p></li></ul><div><hr></div><h2><strong>2. Structured logging is essential for debugging</strong></h2><p>Plain text logs like <code>Something went wrong</code> are useless. Structured logs (e.g., JSON with trace IDs, timestamps, severity levels) allow automated parsing and correlation.</p><p><strong>Example:</strong><br>During a spike in 500 errors, you can&#8217;t trace which request failed where. But if logs include fields like <code>trace_id</code>, <code>user_id</code>, <code>service</code>, <code>error_code</code>, you can group and search easily.</p><p>Good structured log:</p><pre><code>{
  "timestamp": "2025-06-19T10:22:10Z",
  "level": "ERROR",
  "service": "payment-service",
  "trace_id": "abcd1234",
  "message": "Payment gateway timeout"
}</code></pre><div><hr></div><h2><strong>3. Every network call should have a timeout</strong></h2><p>If you call another service without a timeout, your thread could hang indefinitely, leading to thread pool exhaustion and cascading failures.</p><p><strong>Scenario:</strong><br>Service A calls Service B. B gets slow. A keeps waiting. All threads in A get stuck &#8594; A becomes unresponsive &#8594; everything collapses.</p><p><strong>Fix</strong><br>Set timeouts at:</p><ul><li><p>HTTP client (e.g., <code>OkHttp</code>, <code>RestTemplate</code>)</p></li><li><p>DB queries (JDBC socket timeout)</p></li><li><p>Redis or Kafka clients</p></li></ul><div><hr></div><h2><strong>4. Rate limiting is critical, even for internal services</strong></h2><p>Internal systems can be misused or buggy. Rate limiting guards against flood or misuse - intentional or not.</p><p><strong>Scenario:</strong><br>An internal batch job starts hammering the notification service with 10K requests/sec due to a bug. Notification service goes down. Now even real users can&#8217;t get OTPs.</p><p><strong>Fix:</strong><br>Apply per-client or per-service rate limits using:</p><ul><li><p>API Gateway (e.g., Kong, NGINX)</p></li><li><p>Service mesh (e.g., Istio)</p></li><li><p>App-level logic (bucket/token/leaky bucket)</p></li></ul><div><hr></div><h2><strong>5. High latency impacts user experience as much as downtime</strong></h2><p>A slow service feels broken to users. Latency can degrade engagement, increase bounce rate, or trigger retries/load spikes.</p><p><strong>Scenario:</strong><br>Login API is up but takes 5s to respond due to DB slowness. Users refresh, causing even more load &#8594; full outage.</p><p><strong>Fix:</strong></p><ul><li><p>Track 95th/99th percentile latency.</p></li><li><p>Add caching or DB query optimization.</p></li><li><p>Offload heavy work to background jobs.</p></li></ul><div><hr></div><h2><strong>6. Retries should be bounded and controlled</strong></h2><p>Automatic retries can worsen an outage if uncontrolled - this is called a retry storm.</p><p><strong>Scenario:</strong><br>Service A retries B on failure every 100ms. B is already slow. Now it&#8217;s even more overloaded and goes into a full crash.</p><p><strong>Fix:</strong></p><ul><li><p>Use exponential backoff and jitter.</p></li><li><p>Cap retry attempts (e.g., max 3).</p></li><li><p>Add circuit breakers (e.g., Resilience4j, Hystrix).</p></li></ul><div><hr></div><h2><strong>7. Observability is more than just logs</strong></h2><p>You need logs, metrics, and traces (the &#8220;three pillars&#8221;) for full observability.</p><p><strong>Scenario:</strong><br>A request is slow. Without traces, you don&#8217;t know if DB, Redis, or another service is the bottleneck. Logs alone can&#8217;t answer this.</p><p><strong>Fix:</strong></p><ul><li><p>Logs &#8594; for deep inspection</p></li><li><p>Metrics &#8594; for monitoring trends (e.g., Prometheus)</p></li><li><p>Traces &#8594; for request flow (e.g., OpenTelemetry, Jaeger)</p></li></ul><div><hr></div><h2><strong>8. Feature flags must be maintained and cleaned up</strong></h2><p>Feature flags help with controlled rollout, but forgotten flags add tech debt and risk.</p><p><strong>Scenario:</strong><br>A bug is fixed but old flags still exist in code. Devs misunderstand logic later &#8594; reintroduce same bug.</p><p><strong>Fix:</strong></p><ul><li><p>Document flags (who owns them, expiry date)</p></li><li><p>Use tooling like LaunchDarkly or Unleash</p></li><li><p>Add flag cleanup checklist post-release</p></li></ul><div><hr></div><h2><strong>9. Every system has a performance bottleneck</strong></h2><p>No matter how optimized your code is, some component (DB, network, cache, CPU, etc.) will limit the system&#8217;s throughput or latency.</p><p><strong>Scenario:</strong><br>You scale your API horizontally but still hit latency issues. Root cause? A slow SQL join that&#8217;s CPU-bound and unindexed.</p><p><strong>Fixes:</strong></p><ul><li><p>Use tools like flame graphs, APM (e.g., New Relic), or p99 profiling.</p></li><li><p>Continuously measure throughput vs. response time under load.</p></li><li><p>Don&#8217;t guess bottlenecks - measure first.</p></li></ul><div><hr></div><h2><strong>10. Safe deployments require rollback mechanisms</strong></h2><p>If a release breaks production, you need a way to undo quickly, ideally with zero downtime.</p><p><strong>Scenario:</strong><br>A new release introduces a subtle bug in pricing logic. No one notices until revenue drops. But rollback is slow due to DB schema changes.</p><p><strong>Best Practices:</strong></p><ul><li><p>Use blue/green or canary deployments.</p></li><li><p>Avoid irreversible migrations or release them behind a feature flag.</p></li><li><p>Keep one-click rollback in your CI/CD pipeline.</p></li></ul><div><hr></div><h2><strong>11. Real-world failures differ from test failures</strong></h2><p>Staging &#8800; prod. In production, you face network partitions, DNS failures, dirty data, and zombie jobs that tests never covered.</p><p><strong>Scenario:</strong><br>A service worked fine in staging. But in production, a downstream call times out on certain ISPs due to MTU mismatch - something tests never simulated.</p><p><strong>Takeaways:</strong></p><ul><li><p>Simulate chaos (e.g., Chaos Monkey).</p></li><li><p>Validate under production-like load and data.</p></li><li><p>Collect failure patterns from prod incidents.</p></li></ul><div><hr></div><h2><strong>12. API versioning is necessary for evolution</strong></h2><p>As APIs evolve, old clients must still work. Breaking changes without versioning = breaking everyone at once.</p><p><strong>Scenario:</strong><br>You change the payload format or rename a field. Suddenly, old mobile app clients start crashing.</p><p><strong>Solutions:</strong></p><ul><li><p>Use versioned URLs (<code>/v1/user</code>, <code>/v2/user</code>) or headers.</p></li><li><p>Keep multiple versions live and sunset them gradually.</p></li><li><p>Version your OpenAPI spec to stay in sync.</p></li></ul><div><hr></div><h2><strong>13. Avoid exposing internal error messages to users</strong></h2><p>Detailed stack traces or DB errors give attackers insight and confuse users.</p><p><strong>Bad Example:</strong></p><pre><code>500 Internal Server Error: org.hibernate.JDBCException: could not execute statement</code></pre><p><strong>Fix:</strong></p><ul><li><p>Show users friendly messages: <em>&#8220;Oops! Something went wrong.&#8221;</em></p></li><li><p>Log the internal error for engineers with request/trace ID.</p></li><li><p>Apply exception mapping at controller boundaries.</p></li></ul><div><hr></div><h2><strong>14. Databases often become the scalability bottleneck</strong></h2><p>Most backends are read/write bound to a DB. Poor indexing, large joins, and lack of sharding are killers at scale.</p><p><strong>Scenario:</strong><br>As traffic grows, your Postgres query latency spikes. You realize a table with 50M rows isn&#8217;t partitioned and has no composite index.</p><p><strong>Fixes:</strong></p><ul><li><p>Design tables with future volume in mind.</p></li><li><p>Regularly monitor slow queries.</p></li><li><p>Add read replicas, caching layers, or move to scalable DBs (e.g., DynamoDB, CockroachDB).</p></li></ul><div><hr></div><h2><strong>15. Scheduled tasks must be monitored</strong></h2><p>Cron jobs or background workers often get no attention - until they stop running silently.</p><p><strong>Scenario:</strong><br>A cleanup job stops due to a bug in one row&#8217;s data. No alert. After a month, your DB is bloated, app is slow.</p><p><strong>Fix:</strong></p><ul><li><p>Log success/failure of every run.</p></li><li><p>Set up alerts if job doesn&#8217;t run or fails X times.</p></li><li><p>Use dashboards for job duration trends.</p></li></ul><div><hr></div><h2><strong>16. Rolling back code doesn&#8217;t undo external effects</strong></h2><p>Deploying an old version doesn&#8217;t rollback side effects like:</p><ul><li><p>DB rows written</p></li><li><p>Emails sent</p></li><li><p>Payments processed</p></li></ul><p><strong>Scenario:</strong><br>A broken release sends duplicate invoices to 10K users. You roll back, but those emails are already in their inbox.</p><p><strong>Best Practices:</strong></p><ul><li><p>Use compensating transactions (e.g., &#8220;void invoice&#8221;).</p></li><li><p>Track side effects with IDs (e.g., for retry safety).</p></li><li><p>Keep side-effect actions behind flags or queues so they can be paused.</p></li></ul><div><hr></div><h2><strong>17. Caching systems and CDNs can become points of failure</strong></h2><p>We think of caches and CDNs as performance boosters - but they can break things just as easily. Stale data, cache stampedes, CDN outages - all can silently impact users.</p><p><strong>Scenarios:</strong></p><ul><li><p>A product price was updated, but due to CDN cache delay, users still see old pricing &#8594; trust issue.</p></li><li><p>Redis goes down &#8594; app crashes because no fallback or TTL was handled.</p></li></ul><p><strong>Mitigation:</strong></p><ul><li><p>Always set proper TTLs and cache headers.</p></li><li><p>Implement cache fallback logic (e.g., fetch from DB if Redis fails).</p></li><li><p>Invalidate cache explicitly after writes.</p></li><li><p>Monitor cache hit ratios and propagation delays.</p></li></ul><div><hr></div><h2><strong>18. System behavior can change unexpectedly due to external dependencies</strong></h2><p>Your system is only as stable as what it depends on. Third-party APIs, DNS providers, TLS certs, cloud infra updates - any can break your flow without you changing a single line of code.</p><p><strong>Scenario:</strong><br>A payment provider silently changes their API response format &#8594; your parser crashes. Or their cert expires &#8594; your SSL handshake fails &#8594; transactions drop.</p><p><strong>Precautions:</strong></p><ul><li><p>Implement fallback logic and error categorization for third-party calls.</p></li><li><p>Monitor dependency latency/availability as first-class metrics.</p></li><li><p>Set alerts for cert expiration, DNS resolution, etc.</p></li><li><p>Use contract testing or canary calls to detect API changes early.</p></li></ul><div><hr></div><h2><strong>19. High availability requires planning for failure modes</strong></h2><p><strong>Explanation:</strong><br>Redundancy isn&#8217;t optional. Systems will fail - the question is how gracefully you handle it.</p><p><strong>Scenario:</strong><br>Your DB goes down. No failover exists. Users hit a 500 wall for hours.</p><p><strong>Design for HA:</strong></p><ul><li><p>Replicate data across zones/regions.</p></li><li><p>Add load balancer + health checks.</p></li><li><p>Regularly test failover drills and chaos scenarios.</p></li></ul><div><hr></div><h2><strong>20. Cumulative latency across services adds up</strong></h2><p>Even if each service is &#8220;fast&#8221; (say 50ms), calling 5 such services adds 250ms. This hurts UX.</p><p><strong>Scenario:</strong><br>Your checkout page calls pricing, inventory, offers, and tax services - each &lt;100ms. Combined latency = sluggish experience.</p><p><strong>Fix:</strong></p><ul><li><p>Run calls in parallel wherever possible.</p></li><li><p>Use local caches for static data.</p></li><li><p>Measure end-to-end latency, not just per-service metrics.</p></li></ul><div><hr></div><p>These aren&#8217;t just best practices - they&#8217;re survival strategies.<br>The sooner you internalize them, the fewer post-mortems you&#8217;ll write.<br>Whether you&#8217;re building APIs, backend systems, or distributed apps, treat this list as a checklist for production maturity.</p><p>Because writing code is easy. Running it at scale, safely? That&#8217;s where real engineering begins.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://newsletter.theskilledcoder.com/p/concepts-you-only-learn-after-running?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://newsletter.theskilledcoder.com/p/concepts-you-only-learn-after-running?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p></p>]]></content:encoded></item></channel></rss>